servo: Merge #4554 - Update rustc to revision 2cfb5acb5a2751c759627377e602bac4f88f2d19 (from servo:rustup_20141221); r=jdm
authorMs2ger <ms2ger@gmail.com>
Thu, 08 Jan 2015 08:00:57 -0700
changeset 335557 b61915429f0654b5eeaabc2adfea8eb543cb2d5c
parent 335556 8035f280bc27839a42696851e4da3387466bdb8a
child 335558 18ebde6273965f1e3b67d881c4ad28ca6acd5c41
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #4554 - Update rustc to revision 2cfb5acb5a2751c759627377e602bac4f88f2d19 (from servo:rustup_20141221); r=jdm Source-Repo: https://github.com/servo/servo Source-Revision: 1d7148c79f9124779a910fd5291c5fa0543b2dae
servo/components/canvas/canvas_paint_task.rs
servo/components/compositing/compositor.rs
servo/components/compositing/compositor_layer.rs
servo/components/compositing/compositor_task.rs
servo/components/compositing/constellation.rs
servo/components/compositing/pipeline.rs
servo/components/compositing/windowing.rs
servo/components/devtools/actor.rs
servo/components/devtools/actors/console.rs
servo/components/devtools/actors/inspector.rs
servo/components/devtools/actors/root.rs
servo/components/devtools/actors/tab.rs
servo/components/devtools/lib.rs
servo/components/devtools/protocol.rs
servo/components/gfx/buffer_map.rs
servo/components/gfx/display_list/mod.rs
servo/components/gfx/display_list/optimizer.rs
servo/components/gfx/font.rs
servo/components/gfx/font_cache_task.rs
servo/components/gfx/font_context.rs
servo/components/gfx/font_template.rs
servo/components/gfx/lib.rs
servo/components/gfx/paint_context.rs
servo/components/gfx/paint_task.rs
servo/components/gfx/platform/freetype/font.rs
servo/components/gfx/platform/macos/font.rs
servo/components/gfx/platform/macos/font_context.rs
servo/components/gfx/text/glyph.rs
servo/components/gfx/text/shaping/harfbuzz.rs
servo/components/gfx/text/text_run.rs
servo/components/gfx/text/util.rs
servo/components/layout/Cargo.toml
servo/components/layout/block.rs
servo/components/layout/construct.rs
servo/components/layout/context.rs
servo/components/layout/css/matching.rs
servo/components/layout/css/node_style.rs
servo/components/layout/display_list_builder.rs
servo/components/layout/floats.rs
servo/components/layout/flow.rs
servo/components/layout/flow_list.rs
servo/components/layout/flow_ref.rs
servo/components/layout/fragment.rs
servo/components/layout/incremental.rs
servo/components/layout/inline.rs
servo/components/layout/layout_debug.rs
servo/components/layout/layout_task.rs
servo/components/layout/lib.rs
servo/components/layout/list_item.rs
servo/components/layout/model.rs
servo/components/layout/table.rs
servo/components/layout/table_caption.rs
servo/components/layout/table_cell.rs
servo/components/layout/table_colgroup.rs
servo/components/layout/table_row.rs
servo/components/layout/table_rowgroup.rs
servo/components/layout/table_wrapper.rs
servo/components/layout/text.rs
servo/components/layout/traversal.rs
servo/components/layout/util.rs
servo/components/layout/wrapper.rs
servo/components/msg/compositor_msg.rs
servo/components/msg/constellation_msg.rs
servo/components/net/about_loader.rs
servo/components/net/fetch/request.rs
servo/components/net/fetch/response.rs
servo/components/net/http_loader.rs
servo/components/net/image/holder.rs
servo/components/net/image_cache_task.rs
servo/components/net/lib.rs
servo/components/net/resource_task.rs
servo/components/plugins/lib.rs
servo/components/plugins/lints/inheritance_integrity.rs
servo/components/plugins/lints/privatize.rs
servo/components/plugins/lints/str_to_string.rs
servo/components/plugins/lints/transmute_type.rs
servo/components/plugins/lints/unrooted_must_root.rs
servo/components/plugins/utils.rs
servo/components/script/Cargo.toml
servo/components/script/cors.rs
servo/components/script/dom/bindings/callback.rs
servo/components/script/dom/bindings/codegen/CodegenRust.py
servo/components/script/dom/bindings/global.rs
servo/components/script/dom/bindings/js.rs
servo/components/script/dom/bindings/refcounted.rs
servo/components/script/dom/bindings/utils.rs
servo/components/script/dom/domexception.rs
servo/components/script/dom/element.rs
servo/components/script/dom/event.rs
servo/components/script/dom/eventtarget.rs
servo/components/script/dom/htmlcanvaselement.rs
servo/components/script/dom/htmlelement.rs
servo/components/script/dom/htmlformelement.rs
servo/components/script/dom/htmliframeelement.rs
servo/components/script/dom/htmlinputelement.rs
servo/components/script/dom/htmlmediaelement.rs
servo/components/script/dom/htmlserializer.rs
servo/components/script/dom/htmltablecellelement.rs
servo/components/script/dom/node.rs
servo/components/script/dom/treewalker.rs
servo/components/script/dom/window.rs
servo/components/script/dom/workerglobalscope.rs
servo/components/script/dom/xmlhttprequest.rs
servo/components/script/dom/xmlhttprequesteventtarget.rs
servo/components/script/lib.rs
servo/components/script/parse/html.rs
servo/components/script/script_task.rs
servo/components/script/tests.rs
servo/components/script/textinput.rs
servo/components/script/timers.rs
servo/components/servo/Cargo.lock
servo/components/servo/lib.rs
servo/components/servo/main.rs
servo/components/style/Cargo.toml
servo/components/style/legacy.rs
servo/components/style/lib.rs
servo/components/style/media_queries.rs
servo/components/style/properties/common_types.rs
servo/components/style/properties/mod.rs.mako
servo/components/style/selector_matching.rs
servo/components/style/selectors.rs
servo/components/util/cache.rs
servo/components/util/cursor.rs
servo/components/util/deque/mod.rs
servo/components/util/geometry.rs
servo/components/util/lib.rs
servo/components/util/logical_geometry.rs
servo/components/util/opts.rs
servo/components/util/persistent_list.rs
servo/components/util/range.rs
servo/components/util/rtinstrument.rs
servo/components/util/str.rs
servo/components/util/task.rs
servo/components/util/task_state.rs
servo/components/util/tid.rs
servo/components/util/vec.rs
servo/components/util/workqueue.rs
servo/ports/cef/.cargo/config
servo/ports/cef/Cargo.lock
servo/ports/cef/browser.rs
servo/ports/cef/browser_host.rs
servo/ports/cef/core.rs
servo/ports/cef/lib.rs
servo/ports/cef/string.rs
servo/ports/cef/window.rs
servo/ports/glfw/window.rs
servo/ports/glutin/window.rs
servo/ports/gonk/Cargo.lock
servo/python/tidy.py
servo/rust-snapshot-hash
servo/tests/contenttest.rs
servo/tests/reftest.rs
--- a/servo/components/canvas/canvas_paint_task.rs
+++ b/servo/components/canvas/canvas_paint_task.rs
@@ -5,16 +5,17 @@
 use azure::azure_hl::{DrawTarget, Color, SurfaceFormat, BackendType, StrokeOptions, DrawOptions};
 use azure::azure_hl::{ColorPattern, PatternRef};
 use geom::rect::Rect;
 use geom::size::Size2D;
 use servo_util::task::spawn_named;
 
 use std::comm;
 
+#[deriving(Copy)]
 pub enum CanvasMsg {
     FillRect(Rect<f32>),
     ClearRect(Rect<f32>),
     StrokeRect(Rect<f32>),
     Recreate(Size2D<i32>),
     Close,
 }
 
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -24,19 +24,19 @@ use layers::geometry::{DevicePixel, Laye
 use layers::layers::{BufferRequest, Layer, LayerBufferSet};
 use layers::rendergl;
 use layers::rendergl::RenderContext;
 use layers::scene::Scene;
 use png;
 use gleam::gl::types::{GLint, GLsizei};
 use gleam::gl;
 use script_traits::{ConstellationControlMsg, ScriptControlChan};
-use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, LayerId};
-use servo_msg::compositor_msg::{ReadyState, PaintState, Scrollable};
-use servo_msg::constellation_msg::{mod, ConstellationChan};
+use servo_msg::compositor_msg::{Epoch, LayerId};
+use servo_msg::compositor_msg::{ReadyState, PaintState, ScrollPolicy};
+use servo_msg::constellation_msg::{ConstellationChan, NavigationDirection};
 use servo_msg::constellation_msg::Msg as ConstellationMsg;
 use servo_msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
 use servo_msg::constellation_msg::{PipelineId, WindowSizeData};
 use servo_util::geometry::{PagePx, ScreenPx, ViewportPx};
 use servo_util::memory::MemoryProfilerChan;
 use servo_util::opts;
 use servo_util::time::{TimeProfilerCategory, profile, TimeProfilerChan};
 use servo_util::{memory, time};
@@ -142,17 +142,17 @@ pub struct ScrollEvent {
 
 #[deriving(PartialEq)]
 enum CompositionRequest {
     NoCompositingNecessary,
     CompositeOnScrollTimeout(u64),
     CompositeNow,
 }
 
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 enum ShutdownState {
     NotShuttingDown,
     ShuttingDown,
     FinishedShuttingDown,
 }
 
 struct HitTestResult {
     layer: Rc<Layer<CompositorData>>,
@@ -375,19 +375,20 @@ impl<Window: WindowMethods> IOCompositor
         // If we're painting in headless mode, schedule a recomposite.
         if opts::get().output_file.is_some() {
             self.composite_if_necessary()
         }
     }
 
     fn get_earliest_pipeline_ready_state(&self) -> ReadyState {
         if self.ready_states.len() == 0 {
-            return Blank;
+            return ReadyState::Blank;
         }
-        return self.ready_states.values().fold(FinishedLoading, |a, &b| cmp::min(a, b));
+        return self.ready_states.values().fold(ReadyState::FinishedLoading,
+                                               |a, &b| cmp::min(a, b));
 
     }
 
     fn change_paint_state(&mut self, pipeline_id: PipelineId, paint_state: PaintState) {
         match self.paint_states.entry(pipeline_id) {
             Occupied(entry) => {
                 *entry.into_mut() = paint_state;
             }
@@ -472,17 +473,17 @@ impl<Window: WindowMethods> IOCompositor
                                                frame_rect: Option<TypedRect<PagePx, f32>>)
                                                -> Rc<Layer<CompositorData>> {
         let layer_properties = LayerProperties {
             pipeline_id: pipeline.id,
             epoch: Epoch(0),
             id: LayerId::null(),
             rect: Rect::zero(),
             background_color: azure_hl::Color::new(0., 0., 0., 0.),
-            scroll_policy: Scrollable,
+            scroll_policy: ScrollPolicy::Scrollable,
         };
 
         let root_layer = CompositorData::new_layer(pipeline.clone(),
                                                    layer_properties,
                                                    WantsScrollEventsFlag::WantsScrollEvents,
                                                    opts::get().tile_size);
         if !self.paint_channels.contains_key(&pipeline.id) {
             self.paint_channels.insert(pipeline.id, pipeline.paint_chan.clone());
@@ -499,17 +500,17 @@ impl<Window: WindowMethods> IOCompositor
         return root_layer;
     }
 
     fn create_frame_tree_root_layers(&mut self,
                                      frame_tree: &SendableFrameTree,
                                      frame_rect: Option<TypedRect<PagePx, f32>>)
                                      -> Rc<Layer<CompositorData>> {
         // Initialize the ReadyState and PaintState for this pipeline.
-        self.ready_states.insert(frame_tree.pipeline.id, Blank);
+        self.ready_states.insert(frame_tree.pipeline.id, ReadyState::Blank);
         self.paint_states.insert(frame_tree.pipeline.id, PaintState::Painting);
 
         let root_layer = self.create_root_layer_for_pipeline_and_rect(&frame_tree.pipeline,
                                                                       frame_rect);
         for kid in frame_tree.children.iter() {
             root_layer.add_child(self.create_frame_tree_root_layers(&kid.frame_tree, kid.rect));
         }
         return root_layer;
@@ -902,26 +903,26 @@ impl<Window: WindowMethods> IOCompositor
         }
 
         self.send_viewport_rects_for_all_layers();
         self.composite_if_necessary();
     }
 
     fn on_navigation_window_event(&self, direction: WindowNavigateMsg) {
         let direction = match direction {
-            windowing::WindowNavigateMsg::Forward => constellation_msg::Forward,
-            windowing::WindowNavigateMsg::Back => constellation_msg::Back,
+            windowing::WindowNavigateMsg::Forward => NavigationDirection::Forward,
+            windowing::WindowNavigateMsg::Back => NavigationDirection::Back,
         };
         let ConstellationChan(ref chan) = self.constellation_chan;
         chan.send(ConstellationMsg::Navigate(direction))
     }
 
     fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) {
         let ConstellationChan(ref chan) = self.constellation_chan;
-        chan.send(constellation_msg::KeyEvent(key, state, modifiers))
+        chan.send(ConstellationMsg::KeyEvent(key, state, modifiers))
     }
 
     fn convert_buffer_requests_to_pipeline_requests_map(&self,
                                                         requests: Vec<(Rc<Layer<CompositorData>>,
                                                                        Vec<BufferRequest>)>) ->
                                                         HashMap<PipelineId, (PaintChan,
                                                                              Vec<PaintRequest>)> {
         let scale = self.device_pixels_per_page_px();
@@ -1020,17 +1021,17 @@ impl<Window: WindowMethods> IOCompositor
         true
     }
 
     fn is_ready_to_paint_image_output(&self) -> bool {
         if !self.got_load_complete_message {
             return false;
         }
 
-        if self.get_earliest_pipeline_ready_state() != FinishedLoading {
+        if self.get_earliest_pipeline_ready_state() != ReadyState::FinishedLoading {
             return false;
         }
 
         if self.has_outstanding_paint_msgs() {
             return false;
         }
 
         if !self.all_pipelines_in_idle_paint_state() {
@@ -1118,17 +1119,17 @@ impl<Window: WindowMethods> IOCompositor
                 let src_start = (height - y - 1) * stride;
                 let src_slice = orig_pixels.slice(src_start, src_start + stride);
                 copy_memory(pixels.slice_mut(dst_start, dst_start + stride),
                             src_slice.slice_to(stride));
             }
             let mut img = png::Image {
                 width: width as u32,
                 height: height as u32,
-                pixels: png::RGB8(pixels),
+                pixels: png::PixelsByColorType::RGB8(pixels),
             };
             let res = png::store_png(&mut img, &path);
             assert!(res.is_ok());
 
             debug!("shutting down the constellation after generating an output file");
             let ConstellationChan(ref chan) = self.constellation_chan;
             chan.send(ConstellationMsg::Exit);
             self.shutdown_state = ShutdownState::ShuttingDown;
--- a/servo/components/compositing/compositor_layer.rs
+++ b/servo/components/compositing/compositor_layer.rs
@@ -12,19 +12,19 @@ use geom::matrix::identity;
 use geom::point::{Point2D, TypedPoint2D};
 use geom::size::TypedSize2D;
 use geom::rect::Rect;
 use gfx::paint_task::Msg as PaintMsg;
 use layers::color::Color;
 use layers::geometry::LayerPixel;
 use layers::layers::{Layer, LayerBufferSet};
 use layers::platform::surface::NativeSurfaceMethods;
-use script_traits::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
+use script_traits::CompositorEvent::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
 use script_traits::{ScriptControlChan, ConstellationControlMsg};
-use servo_msg::compositor_msg::{Epoch, FixedPosition, LayerId, ScrollPolicy};
+use servo_msg::compositor_msg::{Epoch, LayerId, ScrollPolicy};
 use std::num::Float;
 use std::num::FloatMath;
 use std::rc::Rc;
 
 pub struct CompositorData {
     /// This layer's pipeline. BufferRequests and mouse events will be sent through this.
     pub pipeline: CompositionPipeline,
 
@@ -117,17 +117,17 @@ pub trait CompositorLayer {
     fn scroll_layer_and_all_child_layers(&self,
                                          new_offset: TypedPoint2D<LayerPixel, f32>)
                                          -> bool;
 
     /// Return a flag describing how this layer deals with scroll events.
     fn wants_scroll_events(&self) -> WantsScrollEventsFlag;
 }
 
-#[deriving(PartialEq, Clone)]
+#[deriving(Copy, PartialEq, Clone)]
 pub enum WantsScrollEventsFlag {
     WantsScrollEvents,
     DoesntWantScrollEvents,
 }
 
 fn to_layers_color(color: &azure_hl::Color) -> Color {
     Color { r: color.r, g: color.g, b: color.b, a: color.a }
 }
@@ -338,17 +338,17 @@ impl CompositorLayer for Layer<Composito
         let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
     }
 
     fn scroll_layer_and_all_child_layers(&self, new_offset: TypedPoint2D<LayerPixel, f32>)
                                          -> bool {
         let mut result = false;
 
         // Only scroll this layer if it's not fixed-positioned.
-        if self.extra_data.borrow().scroll_policy != FixedPosition {
+        if self.extra_data.borrow().scroll_policy != ScrollPolicy::FixedPosition {
             let new_offset = new_offset.to_untyped();
             *self.transform.borrow_mut() = identity().translate(new_offset.x, new_offset.y, 0.0);
             *self.content_offset.borrow_mut() = Point2D::from_untyped(&new_offset);
             result = true
         }
 
         let offset_for_children = new_offset + self.extra_data.borrow().scroll_offset;
         for child in self.children().iter() {
--- a/servo/components/compositing/compositor_task.rs
+++ b/servo/components/compositing/compositor_task.rs
@@ -15,22 +15,22 @@ use azure::azure_hl::{SourceSurfaceMetho
 use geom::point::Point2D;
 use geom::rect::Rect;
 use geom::size::Size2D;
 use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata};
 use layers::layers::LayerBufferSet;
 use servo_msg::compositor_msg::{Epoch, LayerId, LayerMetadata, ReadyState};
 use servo_msg::compositor_msg::{PaintListener, PaintState, ScriptListener, ScrollPolicy};
 use servo_msg::constellation_msg::{ConstellationChan, LoadData, PipelineId};
-use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers, Pressed};
+use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers};
 use servo_util::cursor::Cursor;
 use servo_util::memory::MemoryProfilerChan;
 use servo_util::time::TimeProfilerChan;
 use std::comm::{channel, Sender, Receiver};
-use std::fmt::{FormatError, Formatter, Show};
+use std::fmt::{Error, Formatter, Show};
 use std::rc::Rc;
 
 /// Sends messages to the compositor. This is a trait supplied by the port because the method used
 /// to communicate with the compositor may have to kick OS event loops awake, communicate cross-
 /// process, and so forth.
 pub trait CompositorProxy : 'static + Send {
     /// Sends a message to the compositor.
     fn send(&mut self, msg: Msg);
@@ -84,23 +84,24 @@ impl ScriptListener for Box<CompositorPr
         box self.clone_compositor_proxy() as Box<ScriptListener+'static>
     }
 
     fn set_title(&mut self, pipeline_id: PipelineId, title: Option<String>) {
         self.send(Msg::ChangePageTitle(pipeline_id, title))
     }
 
     fn send_key_event(&mut self, key: Key, state: KeyState, modifiers: KeyModifiers) {
-        if state == Pressed {
+        if state == KeyState::Pressed {
             self.send(Msg::KeyEvent(key, modifiers));
         }
     }
 }
 
 /// Information about each layer that the compositor keeps.
+#[deriving(Copy)]
 pub struct LayerProperties {
     pub pipeline_id: PipelineId,
     pub epoch: Epoch,
     pub id: LayerId,
     pub rect: Rect<f32>,
     pub background_color: Color,
     pub scroll_policy: ScrollPolicy,
 }
@@ -216,17 +217,17 @@ pub enum Msg {
     KeyEvent(Key, KeyModifiers),
     /// Changes the cursor.
     SetCursor(Cursor),
     /// Informs the compositor that the paint task for the given pipeline has exited.
     PaintTaskExited(PipelineId),
 }
 
 impl Show for Msg {
-    fn fmt(&self, f: &mut Formatter) -> Result<(),FormatError> {
+    fn fmt(&self, f: &mut Formatter) -> Result<(),Error> {
         match *self {
             Msg::Exit(..) => write!(f, "Exit"),
             Msg::ShutdownComplete(..) => write!(f, "ShutdownComplete"),
             Msg::GetGraphicsMetadata(..) => write!(f, "GetGraphicsMetadata"),
             Msg::CreateOrUpdateRootLayer(..) => write!(f, "CreateOrUpdateRootLayer"),
             Msg::CreateOrUpdateDescendantLayer(..) => write!(f, "CreateOrUpdateDescendantLayer"),
             Msg::SetLayerOrigin(..) => write!(f, "SetLayerOrigin"),
             Msg::ScrollFragmentPoint(..) => write!(f, "ScrollFragmentPoint"),
--- a/servo/components/compositing/constellation.rs
+++ b/servo/components/compositing/constellation.rs
@@ -9,31 +9,30 @@ use compositor_task::Msg as CompositorMs
 use devtools_traits;
 use devtools_traits::DevtoolsControlChan;
 use geom::rect::{Rect, TypedRect};
 use geom::scale_factor::ScaleFactor;
 use gfx::font_cache_task::FontCacheTask;
 use layers::geometry::DevicePixel;
 use layout_traits::LayoutTaskFactory;
 use libc;
-use script_traits::{mod, ConstellationControlMsg};
+use script_traits::{CompositorEvent, ConstellationControlMsg};
 use script_traits::{ScriptControlChan, ScriptTaskFactory};
 use servo_msg::compositor_msg::LayerId;
 use servo_msg::constellation_msg::{mod, ConstellationChan, Failure};
-use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed};
-use servo_msg::constellation_msg::{KeyEvent, Key, KeyState, KeyModifiers};
+use servo_msg::constellation_msg::{IFrameSandboxState, NavigationDirection};
+use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers};
 use servo_msg::constellation_msg::{LoadData, NavigationType};
 use servo_msg::constellation_msg::{PipelineExitType, PipelineId};
 use servo_msg::constellation_msg::{SubpageId, WindowSizeData};
 use servo_msg::constellation_msg::Msg as ConstellationMsg;
 use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
 use servo_net::resource_task::ResourceTask;
 use servo_net::resource_task;
-use servo_net::storage_task::StorageTask;
-use servo_net::storage_task;
+use servo_net::storage_task::{StorageTask, StorageTaskMsg};
 use servo_util::cursor::Cursor;
 use servo_util::geometry::{PagePx, ViewportPx};
 use servo_util::opts;
 use servo_util::task::spawn_named;
 use servo_util::time::TimeProfilerChan;
 use std::cell::{Cell, RefCell};
 use std::collections::{HashMap, HashSet};
 use std::io;
@@ -86,16 +85,17 @@ pub struct Constellation<LTF, STF> {
 
     /// A channel through which messages can be sent to the time profiler.
     pub time_profiler_chan: TimeProfilerChan,
 
     pub window_size: WindowSizeData,
 }
 
 /// A unique ID used to identify a frame.
+#[deriving(Copy)]
 pub struct FrameId(u32);
 
 /// One frame in the hierarchy.
 struct FrameTree {
     /// The ID of this frame.
     pub id: FrameId,
     /// The pipeline for this frame.
     pub pipeline: Rc<Pipeline>,
@@ -510,21 +510,21 @@ impl<LTF: LayoutTaskFactory, STF: Script
         true
     }
 
     fn handle_exit(&mut self) {
         for (_id, ref pipeline) in self.pipelines.iter() {
             pipeline.exit(PipelineExitType::Complete);
         }
         self.image_cache_task.exit();
-        self.resource_task.send(resource_task::Exit);
+        self.resource_task.send(resource_task::ControlMsg::Exit);
         self.devtools_chan.as_ref().map(|chan| {
             chan.send(devtools_traits::ServerExitMsg);
         });
-        self.storage_task.send(storage_task::Exit);
+        self.storage_task.send(StorageTaskMsg::Exit);
         self.font_cache_task.exit();
         self.compositor_proxy.send(CompositorMsg::ShutdownComplete);
     }
 
     fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) {
         debug!("handling failure message from pipeline {}, {}", pipeline_id, subpage_id);
 
         if opts::get().hard_fail {
@@ -566,17 +566,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
 
         let new_id = self.get_next_pipeline_id();
         let new_frame_id = self.get_next_frame_id();
         let pipeline = self.new_pipeline(new_id, subpage_id, None,
                                          LoadData::new(Url::parse("about:failure").unwrap()));
 
         self.browse(Some(pipeline_id),
                     Rc::new(FrameTree::new(new_frame_id, pipeline.clone(), None)),
-                    constellation_msg::Load);
+                    NavigationType::Load);
 
         self.pipelines.insert(new_id, pipeline);
     }
 
     /// Performs navigation. This pushes a `FrameChange` object onto the list of pending frames.
     ///
     /// TODO(pcwalton): Send a `BeforeBrowse` message to the embedder and allow cancellation.
     fn browse(&mut self,
@@ -591,17 +591,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
     }
 
     fn handle_init_load(&mut self, url: Url) {
         let next_pipeline_id = self.get_next_pipeline_id();
         let next_frame_id = self.get_next_frame_id();
         let pipeline = self.new_pipeline(next_pipeline_id, None, None, LoadData::new(url));
         self.browse(None,
                     Rc::new(FrameTree::new(next_frame_id, pipeline.clone(), None)),
-                    constellation_msg::Load);
+                    NavigationType::Load);
         self.pipelines.insert(pipeline.id, pipeline);
     }
 
     fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId,
                              rect: TypedRect<PagePx, f32>) {
         debug!("Received frame rect {} from {}, {}", rect, pipeline_id, subpage_id);
         let mut already_sent = HashSet::new();
 
@@ -713,17 +713,18 @@ impl<LTF: LayoutTaskFactory, STF: Script
         // then reuse the script task in creating the new pipeline
         let source_pipeline = self.pipelines.get(&source_pipeline_id).expect("Constellation:
             source Id of ScriptLoadedURLInIFrame does have an associated pipeline in
             constellation. This should be impossible.").clone();
 
         let source_url = source_pipeline.load_data.url.clone();
 
         let same_script = (source_url.host() == url.host() &&
-                           source_url.port() == url.port()) && sandbox == IFrameUnsandboxed;
+                           source_url.port() == url.port()) &&
+                           sandbox == IFrameSandboxState::IFrameUnsandboxed;
         // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
         // Reuse the script task if the URL is same-origin
         let script_pipeline = if same_script {
             debug!("Constellation: loading same-origin iframe at {}", url);
             Some(source_pipeline.clone())
         } else {
             debug!("Constellation: loading cross-origin iframe at {}", url);
             None
@@ -780,70 +781,71 @@ impl<LTF: LayoutTaskFactory, STF: Script
         let subpage_id = source_frame.pipeline.subpage_id;
         let next_pipeline_id = self.get_next_pipeline_id();
         let next_frame_id = self.get_next_frame_id();
         let pipeline = self.new_pipeline(next_pipeline_id, subpage_id, None, load_data);
         self.browse(Some(source_id),
                     Rc::new(FrameTree::new(next_frame_id,
                                            pipeline.clone(),
                                            parent.borrow().clone())),
-                    constellation_msg::Load);
+                    NavigationType::Load);
         self.pipelines.insert(pipeline.id, pipeline);
     }
 
     fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) {
         debug!("received message to navigate {}", direction);
 
         // TODO(tkuehn): what is the "critical point" beyond which pending frames
         // should not be cleared? Currently, the behavior is that forward/back
         // navigation always has navigation priority, and after that new page loading is
         // first come, first served.
         let destination_frame = match direction {
-            constellation_msg::Forward => {
+            NavigationDirection::Forward => {
                 if self.navigation_context.next.is_empty() {
                     debug!("no next page to navigate to");
                     return;
                 } else {
                     let old = self.current_frame().as_ref().unwrap();
                     for frame in old.iter() {
                         frame.pipeline.revoke_paint_permission();
                     }
                 }
                 self.navigation_context.forward(&mut *self.compositor_proxy)
             }
-            constellation_msg::Back => {
+            NavigationDirection::Back => {
                 if self.navigation_context.previous.is_empty() {
                     debug!("no previous page to navigate to");
                     return;
                 } else {
                     let old = self.current_frame().as_ref().unwrap();
                     for frame in old.iter() {
                         frame.pipeline.revoke_paint_permission();
                     }
                 }
                 self.navigation_context.back(&mut *self.compositor_proxy)
             }
         };
 
         for frame in destination_frame.iter() {
             frame.pipeline.load();
         }
-        self.grant_paint_permission(destination_frame, constellation_msg::Navigate);
+        self.grant_paint_permission(destination_frame, NavigationType::Navigate);
 
     }
 
     fn pipeline_is_in_current_frame(&self, pipeline_id: PipelineId) -> bool {
         self.current_frame().iter()
             .any(|current_frame| current_frame.contains(pipeline_id))
     }
 
     fn handle_key_msg(&self, key: Key, state: KeyState, mods: KeyModifiers) {
         self.current_frame().as_ref().map(|frame| {
             let ScriptControlChan(ref chan) = frame.pipeline.script_chan;
-            chan.send(ConstellationControlMsg::SendEvent(frame.pipeline.id, script_traits::KeyEvent(key, state, mods)));
+            chan.send(ConstellationControlMsg::SendEvent(
+                frame.pipeline.id, CompositorEvent::KeyEvent(key, state, mods)));
         });
     }
 
     fn handle_get_pipeline_title_msg(&mut self, pipeline_id: PipelineId) {
         match self.pipelines.get(&pipeline_id) {
             None => self.compositor_proxy.send(CompositorMsg::ChangePageTitle(pipeline_id, None)),
             Some(pipeline) => {
                 let ScriptControlChan(ref script_channel) = pipeline.script_chan;
@@ -1000,17 +1002,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
     // Grants a frame tree permission to paint; optionally updates navigation to reflect a new page
     fn grant_paint_permission(&mut self, frame_tree: Rc<FrameTree>, navigation_type: NavigationType) {
         // Give permission to paint to the new frame and all child frames
         self.set_ids(&frame_tree);
 
         // Don't call navigation_context.load() on a Navigate type (or None, as in the case of
         // parsed iframes that finish loading)
         match navigation_type {
-            constellation_msg::Load => {
+            NavigationType::Load => {
                 debug!("evicting old frames due to load");
                 let evicted = self.navigation_context.load(frame_tree,
                                                            &mut *self.compositor_proxy);
                 self.handle_evicted_frames(evicted);
             }
             _ => {
                 debug!("ignoring non-load navigation type");
             }
--- a/servo/components/compositing/pipeline.rs
+++ b/servo/components/compositing/pipeline.rs
@@ -1,20 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use CompositorProxy;
-use layout_traits::{ExitNowMsg, LayoutTaskFactory, LayoutControlChan};
+use layout_traits::{LayoutControlMsg, LayoutTaskFactory, LayoutControlChan};
 use script_traits::{ScriptControlChan, ScriptTaskFactory};
 use script_traits::{NewLayoutInfo, ConstellationControlMsg};
 
 use devtools_traits::DevtoolsControlChan;
 use gfx::paint_task::Msg as PaintMsg;
-use gfx::paint_task::{PaintPermissionGranted, PaintPermissionRevoked};
 use gfx::paint_task::{PaintChan, PaintTask};
 use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
 use servo_msg::constellation_msg::{LoadData, WindowSizeData, PipelineExitType};
 use servo_net::image_cache_task::ImageCacheTask;
 use gfx::font_cache_task::FontCacheTask;
 use servo_net::resource_task::ResourceTask;
 use servo_net::storage_task::StorageTask;
 use servo_util::time::TimeProfilerChan;
@@ -161,22 +160,22 @@ impl Pipeline {
     }
 
     pub fn load(&self) {
         let ScriptControlChan(ref chan) = self.script_chan;
         chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone()));
     }
 
     pub fn grant_paint_permission(&self) {
-        let _ = self.paint_chan.send_opt(PaintPermissionGranted);
+        let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionGranted);
     }
 
     pub fn revoke_paint_permission(&self) {
         debug!("pipeline revoking paint channel paint permission");
-        let _ = self.paint_chan.send_opt(PaintPermissionRevoked);
+        let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionRevoked);
     }
 
     pub fn exit(&self, exit_type: PipelineExitType) {
         debug!("pipeline {} exiting", self.id);
 
         // Script task handles shutting down layout, and layout handles shutting down the painter.
         // For now, if the script task has failed, we give up on clean shutdown.
         let ScriptControlChan(ref chan) = self.script_chan;
@@ -191,17 +190,17 @@ impl Pipeline {
 
     pub fn force_exit(&self) {
         let ScriptControlChan(ref script_channel) = self.script_chan;
         let _ = script_channel.send_opt(
             ConstellationControlMsg::ExitPipeline(self.id,
                                                   PipelineExitType::PipelineOnly));
         let _ = self.paint_chan.send_opt(PaintMsg::Exit(None, PipelineExitType::PipelineOnly));
         let LayoutControlChan(ref layout_channel) = self.layout_chan;
-        let _ = layout_channel.send_opt(ExitNowMsg(PipelineExitType::PipelineOnly));
+        let _ = layout_channel.send_opt(LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly));
     }
 
     pub fn to_sendable(&self) -> CompositionPipeline {
         CompositionPipeline {
             id: self.id.clone(),
             script_chan: self.script_chan.clone(),
             paint_chan: self.paint_chan.clone(),
         }
--- a/servo/components/compositing/windowing.rs
+++ b/servo/components/compositing/windowing.rs
@@ -10,31 +10,34 @@ use geom::point::TypedPoint2D;
 use geom::scale_factor::ScaleFactor;
 use geom::size::TypedSize2D;
 use layers::geometry::DevicePixel;
 use layers::platform::surface::NativeGraphicsMetadata;
 use servo_msg::compositor_msg::{PaintState, ReadyState};
 use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData};
 use servo_util::cursor::Cursor;
 use servo_util::geometry::ScreenPx;
-use std::fmt::{FormatError, Formatter, Show};
+use std::fmt::{Error, Formatter, Show};
 use std::rc::Rc;
 
+#[deriving(Clone)]
 pub enum MouseWindowEvent {
     Click(uint, TypedPoint2D<DevicePixel, f32>),
     MouseDown(uint, TypedPoint2D<DevicePixel, f32>),
     MouseUp(uint, TypedPoint2D<DevicePixel, f32>),
 }
 
+#[deriving(Clone)]
 pub enum WindowNavigateMsg {
     Forward,
     Back,
 }
 
 /// Events that the windowing system sends to Servo.
+#[deriving(Clone)]
 pub enum WindowEvent {
     /// Sent when no message has arrived, but the event loop was kicked for some reason (perhaps
     /// by another Servo subsystem).
     ///
     /// FIXME(pcwalton): This is kind of ugly and may not work well with multiprocess Servo.
     /// It's possible that this should be something like
     /// `CompositorMessageWindowEvent(compositor_task::Msg)` instead.
     Idle,
@@ -63,17 +66,17 @@ pub enum WindowEvent {
     Navigation(WindowNavigateMsg),
     /// Sent when the user quits the application
     Quit,
     /// Sent when a key input state changes
     KeyEvent(Key, KeyState, KeyModifiers),
 }
 
 impl Show for WindowEvent {
-    fn fmt(&self, f: &mut Formatter) -> Result<(),FormatError> {
+    fn fmt(&self, f: &mut Formatter) -> Result<(),Error> {
         match *self {
             WindowEvent::Idle => write!(f, "Idle"),
             WindowEvent::Refresh => write!(f, "Refresh"),
             WindowEvent::InitializeCompositing => write!(f, "InitializeCompositing"),
             WindowEvent::Resize(..) => write!(f, "Resize"),
             WindowEvent::KeyEvent(..) => write!(f, "Key"),
             WindowEvent::LoadUrl(..) => write!(f, "LoadUrl"),
             WindowEvent::MouseWindowEventClass(..) => write!(f, "Mouse"),
--- a/servo/components/devtools/actor.rs
+++ b/servo/components/devtools/actor.rs
@@ -15,17 +15,17 @@ use serialize::json;
 
 /// A common trait for all devtools actors that encompasses an immutable name
 /// and the ability to process messages that are directed to particular actors.
 /// TODO: ensure the name is immutable
 pub trait Actor : Any {
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      msg: &json::JsonObject,
+                      msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()>;
     fn name(&self) -> String;
 }
 
 impl<'a> AnyMutRefExt<'a> for &'a mut (Actor + 'a) {
     fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
         if self.is::<T>() {
             unsafe {
@@ -144,24 +144,24 @@ impl ActorRegistry {
         /*let actor: &mut Actor+Send+Sized = *self.actors.find_mut(&name.to_string()).unwrap();
         (actor as &mut Any).downcast_mut::<T>().unwrap()*/
         self.actors.get_mut(&name.to_string()).unwrap().downcast_mut::<T>().unwrap()
     }
 
     /// Attempt to process a message as directed by its `to` property. If the actor is not
     /// found or does not indicate that it knew how to process the message, ignore the failure.
     pub fn handle_message(&mut self,
-                          msg: &json::JsonObject,
+                          msg: &json::Object,
                           stream: &mut TcpStream)
                           -> Result<(), ()> {
-        let to = msg.get(&"to".to_string()).unwrap().as_string().unwrap();
+        let to = msg.get("to").unwrap().as_string().unwrap();
         match self.actors.get(&to.to_string()) {
             None => println!("message received for unknown actor \"{}\"", to),
             Some(actor) => {
-                let msg_type = msg.get(&"type".to_string()).unwrap().as_string().unwrap();
+                let msg_type = msg.get("type").unwrap().as_string().unwrap();
                 if !try!(actor.handle_message(self, &msg_type.to_string(), msg, stream)) {
                     println!("unexpected message type \"{}\" found for actor \"{}\"",
                              msg_type, to);
                 }
             }
         }
         let new_actors = replace(&mut *self.new_actors.borrow_mut(), vec!());
         for actor in new_actors.into_iter() {
--- a/servo/components/devtools/actors/console.rs
+++ b/servo/components/devtools/actors/console.rs
@@ -10,18 +10,17 @@ use actor::{Actor, ActorRegistry};
 use protocol::JsonPacketStream;
 
 use devtools_traits::{EvaluateJS, NullValue, VoidValue, NumberValue, StringValue, BooleanValue};
 use devtools_traits::{ActorValue, DevtoolScriptControlMsg};
 use servo_msg::constellation_msg::PipelineId;
 
 use collections::TreeMap;
 use core::cell::RefCell;
-use serialize::json;
-use serialize::json::ToJson;
+use serialize::json::{mod, Json, ToJson};
 use std::io::TcpStream;
 use std::num::Float;
 
 #[deriving(Encodable)]
 struct StartedListenersTraits {
     customNetworkRequest: bool,
 }
 
@@ -71,17 +70,17 @@ enum ConsoleMessageType {
     ConsoleAPIType(ConsoleAPIMessage),
     PageErrorType(PageErrorMessage),
     LogMessageType(LogMessage),
 }
 
 #[deriving(Encodable)]
 struct GetCachedMessagesReply {
     from: String,
-    messages: Vec<json::JsonObject>,
+    messages: Vec<json::Object>,
 }
 
 #[deriving(Encodable)]
 struct StopListenersReply {
     from: String,
     stoppedListeners: Vec<String>,
 }
 
@@ -91,21 +90,21 @@ struct AutocompleteReply {
     matches: Vec<String>,
     matchProp: String,
 }
 
 #[deriving(Encodable)]
 struct EvaluateJSReply {
     from: String,
     input: String,
-    result: json::Json,
+    result: Json,
     timestamp: uint,
-    exception: json::Json,
+    exception: Json,
     exceptionMessage: String,
-    helperResult: json::Json,
+    helperResult: Json,
 }
 
 pub struct ConsoleActor {
     pub name: String,
     pub pipeline: PipelineId,
     pub script_chan: Sender<DevtoolScriptControlMsg>,
     pub streams: RefCell<Vec<TcpStream>>,
 }
@@ -113,21 +112,21 @@ pub struct ConsoleActor {
 impl Actor for ConsoleActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       _registry: &ActorRegistry,
                       msg_type: &String,
-                      msg: &json::JsonObject,
+                      msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "getCachedMessages" => {
-                let types = msg.get(&"messageTypes".to_string()).unwrap().as_list().unwrap();
+                let types = msg.get(&"messageTypes".to_string()).unwrap().as_array().unwrap();
                 let /*mut*/ messages = vec!();
                 for msg_type in types.iter() {
                     let msg_type = msg_type.as_string().unwrap();
                     match msg_type.as_slice() {
                         "ConsoleAPI" => {
                             //TODO: figure out all consoleapi properties from FFOX source
                         }
 
@@ -191,17 +190,17 @@ impl Actor for ConsoleActor {
             }
 
             "stopListeners" => {
                 //TODO: actually implement listener filters that support starting/stopping
                 let msg = StopListenersReply {
                     from: self.name(),
                     stoppedListeners: msg.get(&"listeners".to_string())
                                          .unwrap()
-                                         .as_list()
+                                         .as_array()
                                          .unwrap_or(&vec!())
                                          .iter()
                                          .map(|listener| listener.as_string().unwrap().to_string())
                                          .collect(),
                 };
                 stream.write_json_packet(&msg);
                 true
             }
@@ -223,68 +222,68 @@ impl Actor for ConsoleActor {
                 let (chan, port) = channel();
                 self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan));
 
                 //TODO: extract conversion into protocol module or some other useful place
                 let result = match try!(port.recv_opt()) {
                     VoidValue => {
                         let mut m = TreeMap::new();
                         m.insert("type".to_string(), "undefined".to_string().to_json());
-                        json::Object(m)
+                        Json::Object(m)
                     }
                     NullValue => {
                         let mut m = TreeMap::new();
                         m.insert("type".to_string(), "null".to_string().to_json());
-                        json::Object(m)
+                        Json::Object(m)
                     }
                     BooleanValue(val) => val.to_json(),
                     NumberValue(val) => {
                         if val.is_nan() {
                             let mut m = TreeMap::new();
                             m.insert("type".to_string(), "NaN".to_string().to_json());
-                            json::Object(m)
+                            Json::Object(m)
                         } else if val.is_infinite() {
                             let mut m = TreeMap::new();
                             if val < 0. {
                                 m.insert("type".to_string(), "-Infinity".to_string().to_json());
                             } else {
                                 m.insert("type".to_string(), "Infinity".to_string().to_json());
                             }
-                            json::Object(m)
+                            Json::Object(m)
                         } else if val == Float::neg_zero() {
                             let mut m = TreeMap::new();
                             m.insert("type".to_string(), "-0".to_string().to_json());
-                            json::Object(m)
+                            Json::Object(m)
                         } else {
                             val.to_json()
                         }
                     }
                     StringValue(s) => s.to_json(),
                     ActorValue(s) => {
                         //TODO: make initial ActorValue message include these properties.
                         let mut m = TreeMap::new();
                         m.insert("type".to_string(), "object".to_string().to_json());
                         m.insert("class".to_string(), "???".to_string().to_json());
                         m.insert("actor".to_string(), s.to_json());
                         m.insert("extensible".to_string(), true.to_json());
                         m.insert("frozen".to_string(), false.to_json());
                         m.insert("sealed".to_string(), false.to_json());
-                        json::Object(m)
+                        Json::Object(m)
                     }
                 };
 
                 //TODO: catch and return exception values from JS evaluation
                 let msg = EvaluateJSReply {
                     from: self.name(),
                     input: input,
                     result: result,
                     timestamp: 0,
-                    exception: json::Object(TreeMap::new()),
+                    exception: Json::Object(TreeMap::new()),
                     exceptionMessage: "".to_string(),
-                    helperResult: json::Object(TreeMap::new()),
+                    helperResult: Json::Object(TreeMap::new()),
                 };
                 stream.write_json_packet(&msg);
                 true
             }
 
             _ => false
         })
     }
--- a/servo/components/devtools/actors/inspector.rs
+++ b/servo/components/devtools/actors/inspector.rs
@@ -7,18 +7,17 @@
 use devtools_traits::{GetRootNode, GetDocumentElement, GetChildren, DevtoolScriptControlMsg};
 use devtools_traits::{GetLayout, NodeInfo, ModifyAttribute};
 
 use actor::{Actor, ActorRegistry};
 use protocol::JsonPacketStream;
 
 use collections::TreeMap;
 use servo_msg::constellation_msg::PipelineId;
-use serialize::json;
-use serialize::json::ToJson;
+use serialize::json::{mod, Json, ToJson};
 use std::cell::RefCell;
 use std::io::TcpStream;
 use std::num::Float;
 
 pub struct InspectorActor {
     pub name: String,
     pub walker: RefCell<Option<String>>,
     pub pageStyle: RefCell<Option<String>>,
@@ -61,17 +60,17 @@ struct HideBoxModelReply {
 impl Actor for HighlighterActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       _registry: &ActorRegistry,
                       msg_type: &String,
-                      _msg: &json::JsonObject,
+                      _msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "showBoxModel" => {
                 let msg = ShowBoxModelReply {
                     from: self.name(),
                 };
                 stream.write_json_packet(&msg);
                 true
@@ -98,22 +97,22 @@ struct ModifyAttributeReply{
 impl Actor for NodeActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      msg: &json::JsonObject,
+                      msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "modifyAttributes" => {
                 let target = msg.get(&"to".to_string()).unwrap().as_string().unwrap();
-                let mods = msg.get(&"modifications".to_string()).unwrap().as_list().unwrap();
+                let mods = msg.get(&"modifications".to_string()).unwrap().as_array().unwrap();
                 let modifications = mods.iter().map(|json_mod| {
                     json::decode(json_mod.to_string().as_slice()).unwrap()
                 }).collect();
 
                 self.script_chan.send(ModifyAttribute(self.pipeline,
                                                       registry.actor_to_script(target.to_string()),
                                                       modifications));
                 let reply = ModifyAttributeReply{
@@ -271,17 +270,17 @@ struct ChildrenReply {
 impl Actor for WalkerActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      msg: &json::JsonObject,
+                      msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "querySelector" => {
                 let msg = QuerySelectorReply {
                     from: self.name(),
                 };
                 stream.write_json_packet(&msg);
                 true
@@ -363,17 +362,17 @@ struct GetAppliedReply {
 struct GetComputedReply {
     computed: Vec<uint>, //XXX all css props
     from: String,
 }
 
 #[deriving(Encodable)]
 struct AppliedEntry {
     rule: String,
-    pseudoElement: json::Json,
+    pseudoElement: Json,
     isSystem: bool,
     matchedSelectors: Vec<String>,
 }
 
 #[deriving(Encodable)]
 struct AppliedRule {
     actor: String,
     __type__: uint,
@@ -395,17 +394,17 @@ struct AppliedSheet {
     styleSheetIndex: int,
     ruleCount: uint,
 }
 
 #[deriving(Encodable)]
 struct GetLayoutReply {
     width: int,
     height: int,
-    autoMargins: json::Json,
+    autoMargins: Json,
     from: String,
 }
 
 #[deriving(Encodable)]
 #[allow(dead_code)]
 struct AutoMargins {
     top: String,
     bottom: String,
@@ -416,17 +415,17 @@ struct AutoMargins {
 impl Actor for PageStyleActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      msg: &json::JsonObject,
+                      msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "getApplied" => {
                 //TODO: query script for relevant applied styles to node (msg.node)
                 let msg = GetAppliedReply {
                     entries: vec!(),
                     rules: vec!(),
                     sheets: vec!(),
@@ -464,19 +463,19 @@ impl Actor for PageStyleActor {
                     height: height.round() as int,
                     autoMargins: if auto_margins {
                         //TODO: real values like processMargins in http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js
                         let mut m = TreeMap::new();
                         m.insert("top".to_string(), "auto".to_string().to_json());
                         m.insert("bottom".to_string(), "auto".to_string().to_json());
                         m.insert("left".to_string(), "auto".to_string().to_json());
                         m.insert("right".to_string(), "auto".to_string().to_json());
-                        json::Object(m)
+                        Json::Object(m)
                     } else {
-                        json::Null
+                        Json::Null
                     },
                     from: self.name(),
                 };
                 stream.write_json_packet(&msg);
                 true
             }
 
             _ => false,
@@ -487,17 +486,17 @@ impl Actor for PageStyleActor {
 impl Actor for InspectorActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      _msg: &json::JsonObject,
+                      _msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "getWalker" => {
                 if self.walker.borrow().is_none() {
                     let walker = WalkerActor {
                         name: registry.new_name("walker"),
                         script_chan: self.script_chan.clone(),
                         pipeline: self.pipeline,
--- a/servo/components/devtools/actors/root.rs
+++ b/servo/components/devtools/actors/root.rs
@@ -48,17 +48,17 @@ pub struct RootActor {
 impl Actor for RootActor {
     fn name(&self) -> String {
         "root".to_string()
     }
 
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      _msg: &json::JsonObject,
+                      _msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "listAddons" => {
                 let actor = ErrorReply {
                     from: "root".to_string(),
                     error: "noAddons".to_string(),
                     message: "This root actor has no browser addons.".to_string(),
                 };
--- a/servo/components/devtools/actors/tab.rs
+++ b/servo/components/devtools/actors/tab.rs
@@ -72,17 +72,17 @@ pub struct TabActor {
 impl Actor for TabActor {
     fn name(&self) -> String {
         self.name.clone()
     }
 
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
-                      _msg: &json::JsonObject,
+                      _msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()> {
         Ok(match msg_type.as_slice() {
             "reconfigure" => {
                 stream.write_json_packet(&ReconfigureReply { from: self.name() });
                 true
             }
 
             // https://wiki.mozilla.org/Remote_Debugging_Protocol#Listing_Browser_Tabs
--- a/servo/components/devtools/lib.rs
+++ b/servo/components/devtools/lib.rs
@@ -16,17 +16,16 @@ extern crate log;
 /// An actor-based remote devtools server implementation. Only tested with nightly Firefox
 /// versions at time of writing. Largely based on reverse-engineering of Firefox chrome
 /// devtool logs and reading of [code](http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/).
 
 extern crate collections;
 extern crate core;
 extern crate devtools_traits;
 extern crate serialize;
-extern crate sync;
 extern crate "msg" as servo_msg;
 extern crate "util" as servo_util;
 
 use actor::{Actor, ActorRegistry};
 use actors::console::ConsoleActor;
 use actors::inspector::InspectorActor;
 use actors::root::RootActor;
 use actors::tab::TabActor;
@@ -37,17 +36,17 @@ use servo_msg::constellation_msg::Pipeli
 use servo_util::task::spawn_named;
 
 use std::cell::RefCell;
 use std::collections::HashMap;
 use std::comm;
 use std::comm::{Disconnected, Empty};
 use std::io::{TcpListener, TcpStream};
 use std::io::{Acceptor, Listener, TimedOut};
-use sync::{Arc, Mutex};
+use std::sync::{Arc, Mutex};
 
 mod actor;
 /// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/
 mod actors {
     pub mod console;
     pub mod inspector;
     pub mod root;
     pub mod tab;
--- a/servo/components/devtools/protocol.rs
+++ b/servo/components/devtools/protocol.rs
@@ -1,33 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /// Low-level wire protocol implementation. Currently only supports [JSON packets](https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport#JSON_Packets).
 
 use serialize::{json, Encodable};
+use serialize::json::Json;
 use std::io::{IoError, OtherIoError, EndOfFile, TcpStream, IoResult};
 use std::num;
 
 pub trait JsonPacketStream {
     fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T);
-    fn read_json_packet(&mut self) -> IoResult<json::Json>;
+    fn read_json_packet(&mut self) -> IoResult<Json>;
 }
 
 impl JsonPacketStream for TcpStream {
     fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T) {
         let s = json::encode(obj).replace("__type__", "type");
         println!("<- {}", s);
         self.write_str(s.len().to_string().as_slice()).unwrap();
         self.write_u8(':' as u8).unwrap();
         self.write_str(s.as_slice()).unwrap();
     }
 
-    fn read_json_packet<'a>(&mut self) -> IoResult<json::Json> {
+    fn read_json_packet<'a>(&mut self) -> IoResult<Json> {
         // https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport
         // In short, each JSON packet is [ascii length]:[JSON data of given length]
         let mut buffer = vec!();
         loop {
             let colon = ':' as u8;
             match self.read_byte() {
                 Ok(c) if c != colon => buffer.push(c as u8),
                 Ok(_) => {
--- a/servo/components/gfx/buffer_map.rs
+++ b/servo/components/gfx/buffer_map.rs
@@ -22,17 +22,17 @@ pub struct BufferMap {
     /// The maximum allowed memory. Unused buffers will be deleted
     /// when this threshold is exceeded.
     max_mem: uint,
     /// A monotonically increasing counter to track how recently tile sizes were used.
     counter: uint,
 }
 
 /// A key with which to store buffers. It is based on the size of the buffer.
-#[deriving(Eq)]
+#[deriving(Eq, Copy)]
 struct BufferKey([uint, ..2]);
 
 impl Hash for BufferKey {
     fn hash(&self, state: &mut SipState) {
         let BufferKey(ref bytes) = *self;
         bytes.as_slice().hash(state);
     }
 }
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -37,17 +37,17 @@ use servo_util::dlist as servo_dlist;
 use servo_util::geometry::{mod, Au, MAX_RECT, ZERO_RECT};
 use servo_util::range::Range;
 use servo_util::smallvec::{SmallVec, SmallVec8};
 use std::fmt;
 use std::slice::Items;
 use style::ComputedValues;
 use style::computed_values::border_style;
 use style::computed_values::cursor;
-use sync::Arc;
+use std::sync::Arc;
 
 // It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
 // layout to use.
 pub use azure::azure_hl::GradientStop;
 
 pub mod optimizer;
 
 /// The factor that we multiply the blur radius by in order to inflate the boundaries of box shadow
@@ -56,17 +56,17 @@ pub mod optimizer;
 pub static BOX_SHADOW_INFLATION_FACTOR: i32 = 3;
 
 /// An opaque handle to a node. The only safe operation that can be performed on this node is to
 /// compare it to another opaque handle or to another node.
 ///
 /// Because the script task's GC does not trace layout, node data cannot be safely stored in layout
 /// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for
 /// locality reasons. Using `OpaqueNode` enforces this invariant.
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Copy)]
 pub struct OpaqueNode(pub uintptr_t);
 
 impl OpaqueNode {
     /// Returns the address of this node, for debugging purposes.
     pub fn id(&self) -> uintptr_t {
         let OpaqueNode(pointer) = *self;
         pointer
     }
@@ -623,17 +623,17 @@ impl ClippingRegion {
             }).collect(),
         }
     }
 }
 
 /// Metadata attached to each display item. This is useful for performing auxiliary tasks with
 /// the display list involving hit testing: finding the originating DOM node and determining the
 /// cursor to use when the element is hovered over.
-#[deriving(Clone)]
+#[deriving(Clone, Copy)]
 pub struct DisplayItemMetadata {
     /// The DOM node from which this display item originated.
     pub node: OpaqueNode,
     /// The value of the `cursor` property when the mouse hovers over this display item.
     pub cursor: Cursor,
 }
 
 impl DisplayItemMetadata {
@@ -734,17 +734,17 @@ pub struct BorderDisplayItem {
     ///
     /// TODO(pcwalton): Elliptical radii.
     pub radius: BorderRadii<Au>,
 }
 
 /// Information about the border radii.
 ///
 /// TODO(pcwalton): Elliptical radii.
-#[deriving(Clone, Default, PartialEq, Show)]
+#[deriving(Clone, Default, PartialEq, Show, Copy)]
 pub struct BorderRadii<T> {
     pub top_left: T,
     pub top_right: T,
     pub bottom_right: T,
     pub bottom_left: T,
 }
 
 impl<T> BorderRadii<T> where T: PartialEq + Zero {
--- a/servo/components/gfx/display_list/optimizer.rs
+++ b/servo/components/gfx/display_list/optimizer.rs
@@ -4,17 +4,17 @@
 
 //! Transforms a display list to produce a visually-equivalent, but cheaper-to-paint, one.
 
 use display_list::{DisplayItem, DisplayList, StackingContext};
 
 use collections::dlist::DList;
 use geom::rect::Rect;
 use servo_util::geometry::{mod, Au};
-use sync::Arc;
+use std::sync::Arc;
 
 /// Transforms a display list to produce a visually-equivalent, but cheaper-to-paint, one.
 pub struct DisplayListOptimizer {
     /// The visible rect in page coordinates.
     visible_rect: Rect<Au>,
 }
 
 impl DisplayListOptimizer {
--- a/servo/components/gfx/font.rs
+++ b/servo/components/gfx/font.rs
@@ -1,22 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use geom::{Point2D, Rect, Size2D};
 use std::mem;
-use std::string;
+use std::slice;
 use std::rc::Rc;
 use std::cell::RefCell;
 use servo_util::cache::{Cache, HashCache};
 use servo_util::smallvec::{SmallVec, SmallVec8};
 use style::computed_values::{font_variant, font_weight};
 use style::style_structs::Font as FontStyle;
-use sync::Arc;
+use std::sync::Arc;
 
 use collections::hash::Hash;
 use platform::font_context::FontContextHandle;
 use platform::font::{FontHandle, FontTable};
 use servo_util::geometry::Au;
 use text::glyph::{GlyphStore, GlyphId};
 use text::shaping::ShaperMethods;
 use text::{Shaper, TextRun};
@@ -51,21 +51,20 @@ pub type FontTableTag = u32;
 
 pub trait FontTableTagConversions {
     fn tag_to_str(&self) -> String;
 }
 
 impl FontTableTagConversions for FontTableTag {
     fn tag_to_str(&self) -> String {
         unsafe {
-            let reversed = string::raw::from_buf_len(mem::transmute(self), 4);
-            return String::from_chars([reversed.as_slice().char_at(3),
-                                       reversed.as_slice().char_at(2),
-                                       reversed.as_slice().char_at(1),
-                                       reversed.as_slice().char_at(0)]);
+            let pointer = mem::transmute::<&u32, *const u8>(self);
+            let mut bytes = slice::from_raw_buf(&pointer, 4).to_vec();
+            bytes.reverse();
+            String::from_utf8_unchecked(bytes)
         }
     }
 }
 
 pub trait FontTableMethods {
     fn with_buffer(&self, |*const u8, uint|);
 }
 
@@ -96,26 +95,27 @@ pub struct Font {
     pub requested_pt_size: Au,
     pub actual_pt_size: Au,
     pub shaper: Option<Shaper>,
     pub shape_cache: HashCache<ShapeCacheEntry,Arc<GlyphStore>>,
     pub glyph_advance_cache: HashCache<u32,FractionalPixel>,
 }
 
 bitflags! {
+    #[deriving(Copy)]
     flags ShapingFlags: u8 {
         #[doc="Set if the text is entirely whitespace."]
         const IS_WHITESPACE_SHAPING_FLAG = 0x01,
         #[doc="Set if we are to ignore ligatures."]
         const IGNORE_LIGATURES_SHAPING_FLAG = 0x02
     }
 }
 
 /// Various options that control text shaping.
-#[deriving(Clone, Eq, PartialEq, Hash)]
+#[deriving(Clone, Eq, PartialEq, Hash, Copy)]
 pub struct ShapingOptions {
     /// Spacing to add between each letter. Corresponds to the CSS 2.1 `letter-spacing` property.
     /// NB: You will probably want to set the `IGNORE_LIGATURES_SHAPING_FLAG` if this is non-null.
     pub letter_spacing: Option<Au>,
     /// Spacing to add between each word. Corresponds to the CSS 2.1 `word-spacing` property.
     pub word_spacing: Au,
     /// Various flags.
     pub flags: ShapingFlags,
--- a/servo/components/gfx/font_cache_task.rs
+++ b/servo/components/gfx/font_cache_task.rs
@@ -5,17 +5,17 @@
 use platform::font_list::get_available_families;
 use platform::font_list::get_system_default_family;
 use platform::font_list::get_variations_for_family;
 use platform::font_list::get_last_resort_font_families;
 use platform::font_context::FontContextHandle;
 
 use collections::str::Str;
 use std::collections::HashMap;
-use sync::Arc;
+use std::sync::Arc;
 use font_template::{FontTemplate, FontTemplateDescriptor};
 use platform::font_template::FontTemplateData;
 use servo_net::resource_task::{ResourceTask, load_whole_resource};
 use servo_util::task::spawn_named;
 use servo_util::str::LowercaseString;
 use style::Source;
 
 /// A list of font templates that make up a given font family.
--- a/servo/components/gfx/font_context.rs
+++ b/servo/components/gfx/font_context.rs
@@ -14,17 +14,17 @@ use font::FontHandleMethods;
 use platform::font::FontHandle;
 use servo_util::cache::HashCache;
 use servo_util::smallvec::{SmallVec, SmallVec8};
 use servo_util::geometry::Au;
 use servo_util::arc_ptr_eq;
 
 use std::rc::Rc;
 use std::cell::RefCell;
-use sync::Arc;
+use std::sync::Arc;
 
 use azure::AzFloat;
 use azure::azure_hl::BackendType;
 use azure::scaled_font::ScaledFont;
 
 #[cfg(any(target_os="linux", target_os = "android"))]
 use azure::scaled_font::FontInfo;
 
--- a/servo/components/gfx/font_template.rs
+++ b/servo/components/gfx/font_template.rs
@@ -2,24 +2,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use style::computed_values::font_weight;
 use platform::font_context::FontContextHandle;
 use platform::font::FontHandle;
 use platform::font_template::FontTemplateData;
 
-use sync::{Arc, Weak};
+use std::sync::{Arc, Weak};
 use font::FontHandleMethods;
 
 /// Describes how to select a font from a given family.
 /// This is very basic at the moment and needs to be
 /// expanded or refactored when we support more of the
 /// font styling parameters.
-#[deriving(Clone)]
+#[deriving(Clone, Copy)]
 pub struct FontTemplateDescriptor {
     pub weight: font_weight::T,
     pub italic: bool,
 }
 
 impl FontTemplateDescriptor {
     pub fn new(weight: font_weight::T, italic: bool) -> FontTemplateDescriptor {
         FontTemplateDescriptor {
--- a/servo/components/gfx/lib.rs
+++ b/servo/components/gfx/lib.rs
@@ -24,17 +24,16 @@ extern crate serialize;
 extern crate unicode;
 #[phase(plugin)]
 extern crate "plugins" as servo_plugins;
 extern crate "net" as servo_net;
 #[phase(plugin, link)]
 extern crate "util" as servo_util;
 extern crate "msg" as servo_msg;
 extern crate style;
-extern crate sync;
 extern crate time;
 extern crate url;
 
 // Eventually we would like the shaper to be pluggable, as many operating systems have their own
 // shapers. For now, however, this is a hard dependency.
 extern crate harfbuzz;
 
 // Linux and Android-specific library dependencies
--- a/servo/components/gfx/paint_context.rs
+++ b/servo/components/gfx/paint_context.rs
@@ -28,17 +28,17 @@ use servo_net::image::base::Image;
 use servo_util::geometry::{Au, MAX_RECT};
 use servo_util::opts;
 use servo_util::range::Range;
 use std::default::Default;
 use std::mem;
 use std::num::{Float, FloatMath};
 use std::ptr;
 use style::computed_values::border_style;
-use sync::Arc;
+use std::sync::Arc;
 use text::TextRun;
 use text::glyph::CharIndex;
 
 pub struct PaintContext<'a> {
     pub draw_target: DrawTarget,
     pub font_ctx: &'a mut Box<FontContext>,
     /// The rectangle that this context encompasses in page coordinates.
     pub page_rect: Rect<f32>,
@@ -47,23 +47,25 @@ pub struct PaintContext<'a> {
     /// The clipping rect for the stacking context as a whole.
     pub clip_rect: Option<Rect<Au>>,
     /// The current transient clipping region, if any. A "transient clipping region" is the
     /// clipping region used by the last display item. We cache the last value so that we avoid
     /// pushing and popping clipping regions unnecessarily.
     pub transient_clip: Option<ClippingRegion>,
 }
 
+#[deriving(Copy)]
 enum Direction {
     Top,
     Left,
     Right,
     Bottom
 }
 
+#[deriving(Copy)]
 enum DashSize {
     DottedBorder = 1,
     DashedBorder = 3
 }
 
 impl<'a> PaintContext<'a> {
     pub fn get_draw_target(&self) -> &DrawTarget {
         &self.draw_target
--- a/servo/components/gfx/paint_task.rs
+++ b/servo/components/gfx/paint_task.rs
@@ -30,17 +30,17 @@ use servo_util::geometry::{Au, ZERO_POIN
 use servo_util::opts;
 use servo_util::smallvec::SmallVec;
 use servo_util::task::spawn_named_with_send_on_failure;
 use servo_util::task_state;
 use servo_util::time::{TimeProfilerChan, TimeProfilerCategory, profile};
 use std::comm::{Receiver, Sender, channel};
 use std::mem;
 use std::task::TaskBuilder;
-use sync::Arc;
+use std::sync::Arc;
 
 /// Information about a hardware graphics layer that layout sends to the painting task.
 #[deriving(Clone)]
 pub struct PaintLayer {
     /// A per-pipeline ID describing this layer that should be stable across reflows.
     pub id: LayerId,
     /// The color of the background in this layer. Used for unpainted content.
     pub background_color: Color,
--- a/servo/components/gfx/platform/freetype/font.rs
+++ b/servo/components/gfx/platform/freetype/font.rs
@@ -25,17 +25,17 @@ use freetype::freetype::{FT_SizeRec, FT_
 use freetype::freetype::{ft_sfnt_os2};
 use freetype::tt_os2::TT_OS2;
 
 use std::mem;
 use std::num::Float;
 use std::ptr;
 use std::string;
 
-use sync::Arc;
+use std::sync::Arc;
 
 fn float_to_fixed_ft(f: f64) -> i32 {
     float_to_fixed(6, f)
 }
 
 fn fixed_to_float_ft(f: i32) -> f64 {
     fixed_to_float(6, f)
 }
--- a/servo/components/gfx/platform/macos/font.rs
+++ b/servo/components/gfx/platform/macos/font.rs
@@ -24,17 +24,17 @@ use core_foundation::string::UniChar;
 use core_graphics::font::CGGlyph;
 use core_graphics::geometry::CGRect;
 use core_text::font::CTFont;
 use core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors};
 use core_text::font_descriptor::{kCTFontDefaultOrientation};
 
 use std::num::Float;
 use std::ptr;
-use sync::Arc;
+use std::sync::Arc;
 
 pub struct FontTable {
     data: CFData,
 }
 
 // Noncopyable.
 impl Drop for FontTable {
     fn drop(&mut self) {}
@@ -95,25 +95,25 @@ impl FontHandleMethods for FontHandle {
         self.ctfont.symbolic_traits().is_italic()
     }
 
     fn boldness(&self) -> font_weight::T {
         // -1.0 to 1.0
         let normalized = self.ctfont.all_traits().normalized_weight();
         // 0.0 to 9.0
         let normalized = (normalized + 1.0) / 2.0 * 9.0;
-        if normalized < 1.0 { return font_weight::Weight100; }
-        if normalized < 2.0 { return font_weight::Weight200; }
-        if normalized < 3.0 { return font_weight::Weight300; }
-        if normalized < 4.0 { return font_weight::Weight400; }
-        if normalized < 5.0 { return font_weight::Weight500; }
-        if normalized < 6.0 { return font_weight::Weight600; }
-        if normalized < 7.0 { return font_weight::Weight700; }
-        if normalized < 8.0 { return font_weight::Weight800; }
-        return font_weight::Weight900;
+        if normalized < 1.0 { return font_weight::T::Weight100; }
+        if normalized < 2.0 { return font_weight::T::Weight200; }
+        if normalized < 3.0 { return font_weight::T::Weight300; }
+        if normalized < 4.0 { return font_weight::T::Weight400; }
+        if normalized < 5.0 { return font_weight::T::Weight500; }
+        if normalized < 6.0 { return font_weight::T::Weight600; }
+        if normalized < 7.0 { return font_weight::T::Weight700; }
+        if normalized < 8.0 { return font_weight::T::Weight800; }
+        return font_weight::T::Weight900;
     }
 
     fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
         let characters: [UniChar,  ..1] = [codepoint as UniChar];
         let mut glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
         let count: CFIndex = 1;
 
         let result = self.ctfont.get_glyphs_for_characters(&characters[0],
@@ -174,17 +174,17 @@ impl FontHandleMethods for FontHandle {
             x_height:         Au::from_pt(self.ctfont.x_height() as f64),
             em_size:          em_size,
             ascent:           Au::from_pt(ascent * scale),
             descent:          Au::from_pt(descent * scale),
             max_advance:      max_advance_width,
             average_advance:  average_advance,
             line_gap:         Au::from_frac_px(line_gap),
         };
-        debug!("Font metrics (@{:f} pt): {}", self.ctfont.pt_size() as f64, metrics);
+        debug!("Font metrics (@{} pt): {}", self.ctfont.pt_size() as f64, metrics);
         return metrics;
     }
 
     fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
         let result: Option<CFData> = self.ctfont.get_font_table(tag);
         result.and_then(|data| {
             Some(FontTable::wrap(data))
         })
--- a/servo/components/gfx/platform/macos/font_context.rs
+++ b/servo/components/gfx/platform/macos/font_context.rs
@@ -2,15 +2,14 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #[deriving(Clone)]
 pub struct FontContextHandle {
     ctx: ()
 }
 
-#[deriving(Clone)]
 impl FontContextHandle {
     // this is a placeholder until NSFontManager or whatever is bound in here.
     pub fn new() -> FontContextHandle {
         FontContextHandle { ctx: () }
     }
 }
--- a/servo/components/gfx/text/glyph.rs
+++ b/servo/components/gfx/text/glyph.rs
@@ -17,17 +17,17 @@ use geom::point::Point2D;
 /// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly.
 ///
 /// In the common case (reasonable glyph advances, no offsets from the font em-box, and one glyph
 /// per character), we pack glyph advance, glyph id, and some flags into a single u32.
 ///
 /// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or
 /// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information
 /// in DetailedGlyphStore.
-#[deriving(Clone, Show)]
+#[deriving(Clone, Show, Copy)]
 struct GlyphEntry {
     value: u32,
 }
 
 impl GlyphEntry {
     fn new(value: u32) -> GlyphEntry {
         GlyphEntry {
             value: value,
@@ -82,17 +82,17 @@ impl GlyphEntry {
         GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT as uint)
     }
 }
 
 /// The id of a particular glyph within a font
 pub type GlyphId = u32;
 
 // TODO: unify with bit flags?
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Copy)]
 pub enum BreakType {
     None,
     Normal,
     Hyphen,
 }
 
 static BREAK_TYPE_NONE:   u8 = 0x0;
 static BREAK_TYPE_NORMAL: u8 = 0x1;
@@ -246,17 +246,17 @@ impl GlyphEntry {
     #[inline(always)]
     fn adapt_character_flags_of_entry(&self, other: GlyphEntry) -> GlyphEntry {
         GlyphEntry { value: self.value | other.value }
     }
 }
 
 // Stores data for a detailed glyph, in the case that several glyphs
 // correspond to one character, or the glyph's data couldn't be packed.
-#[deriving(Clone, Show)]
+#[deriving(Clone, Show, Copy)]
 struct DetailedGlyph {
     id: GlyphId,
     // glyph's advance, in the text's direction (RTL or RTL)
     advance: Au,
     // glyph's offset from the font's em-box (from top-left)
     offset: Point2D<Au>,
 }
 
@@ -265,17 +265,17 @@ impl DetailedGlyph {
         DetailedGlyph {
             id: id,
             advance: advance,
             offset: offset,
         }
     }
 }
 
-#[deriving(PartialEq, Clone, Eq, Show)]
+#[deriving(PartialEq, Clone, Eq, Show, Copy)]
 struct DetailedGlyphRecord {
     // source string offset/GlyphEntry offset in the TextRun
     entry_offset: CharIndex,
     // offset into the detailed glyphs buffer
     detail_offset: int,
 }
 
 impl PartialOrd for DetailedGlyphRecord {
@@ -406,16 +406,17 @@ impl<'a> DetailedGlyphStore {
         mem::swap(&mut self.detail_lookup, &mut sorted_records);
 
         self.lookup_is_sorted = true;
     }
 }
 
 // This struct is used by GlyphStore clients to provide new glyph data.
 // It should be allocated on the stack and passed by reference to GlyphStore.
+#[deriving(Copy)]
 pub struct GlyphData {
     id: GlyphId,
     advance: Au,
     offset: Point2D<Au>,
     is_missing: bool,
     cluster_start: bool,
     ligature_start: bool,
 }
@@ -438,16 +439,17 @@ impl GlyphData {
         }
     }
 }
 
 // This enum is a proxy that's provided to GlyphStore clients when iterating
 // through glyphs (either for a particular TextRun offset, or all glyphs).
 // Rather than eagerly assembling and copying glyph data, it only retrieves
 // values as they are needed from the GlyphStore, using provided offsets.
+#[deriving(Copy)]
 pub enum GlyphInfo<'a> {
     Simple(&'a GlyphStore, CharIndex),
     Detail(&'a GlyphStore, CharIndex, u16),
 }
 
 impl<'a> GlyphInfo<'a> {
     pub fn id(self) -> GlyphId {
         match self {
--- a/servo/components/gfx/text/shaping/harfbuzz.rs
+++ b/servo/components/gfx/text/shaping/harfbuzz.rs
@@ -498,17 +498,17 @@ impl Shaper {
             None => {}
             Some(letter_spacing) => advance = advance + letter_spacing,
         };
 
         // CSS 2.1 § 16.4 states that "word spacing affects each space (U+0020) and non-breaking
         // space (U+00A0) left in the text after the white space processing rules have been
         // applied. The effect of the property on other word-separator characters is undefined."
         // We elect to only space the two required code points.
-        if character == ' ' || character == '\u00a0' {
+        if character == ' ' || character == '\u{a0}' {
             advance = advance + options.word_spacing
         }
 
         advance
     }
 }
 
 /// Callbacks from Harfbuzz when font map and glyph advance lookup needed.
--- a/servo/components/gfx/text/text_run.rs
+++ b/servo/components/gfx/text/text_run.rs
@@ -4,17 +4,17 @@
 
 use font::{Font, FontHandleMethods, FontMetrics, IS_WHITESPACE_SHAPING_FLAG, RunMetrics};
 use font::{ShapingOptions};
 use platform::font_template::FontTemplateData;
 use servo_util::geometry::Au;
 use servo_util::range::Range;
 use servo_util::vec::{Comparator, FullBinarySearchMethods};
 use std::slice::Items;
-use sync::Arc;
+use std::sync::Arc;
 use text::glyph::{CharIndex, GlyphStore};
 
 /// A single "paragraph" of text in one font size and style.
 #[deriving(Clone)]
 pub struct TextRun {
     pub text: Arc<String>,
     pub font_template: Arc<FontTemplateData>,
     pub actual_pt_size: Au,
--- a/servo/components/gfx/text/util.rs
+++ b/servo/components/gfx/text/util.rs
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use text::glyph::CharIndex;
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Eq, Copy)]
 pub enum CompressionMode {
     CompressNone,
     CompressWhitespace,
     CompressWhitespaceNewline,
     DiscardNewline
 }
 
 // ported from Gecko's nsTextFrameUtils::TransformText.
--- a/servo/components/layout/Cargo.toml
+++ b/servo/components/layout/Cargo.toml
@@ -29,22 +29,22 @@ path = "../plugins"
 path = "../net"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies.cssparser]
 git = "https://github.com/servo/rust-cssparser"
 
-[dependencies.encoding]
-git = "https://github.com/lifthrasiir/rust-encoding"
-
 [dependencies.geom]
 git = "https://github.com/servo/rust-geom"
 
 [dependencies.url]
 git = "https://github.com/servo/rust-url"
 
 [dependencies.string_cache]
 git = "https://github.com/servo/string-cache"
 
 [dependencies.string_cache_macros]
 git = "https://github.com/servo/string-cache"
+
+[dependencies]
+encoding = "0.2"
--- a/servo/components/layout/block.rs
+++ b/servo/components/layout/block.rs
@@ -56,17 +56,17 @@ use servo_util::geometry::{Au, MAX_AU};
 use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
 use servo_util::opts;
 use std::cmp::{max, min};
 use std::fmt;
 use style::ComputedValues;
 use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
 use style::computed_values::{LengthOrPercentage, box_sizing, display, float};
 use style::computed_values::{overflow, position};
-use sync::Arc;
+use std::sync::Arc;
 
 /// Information specific to floated blocks.
 #[deriving(Clone, Encodable)]
 pub struct FloatedBlockInfo {
     /// The amount of inline size that is available for the float.
     pub containing_inline_size: Au,
 
     /// The float ceiling, relative to `BaseFlow::position::cur_b` (i.e. the top part of the border
@@ -87,16 +87,17 @@ impl FloatedBlockInfo {
             float_ceiling: Au(0),
             index: None,
             float_kind: float_kind,
         }
     }
 }
 
 /// The solutions for the block-size-and-margins constraint equation.
+#[deriving(Copy)]
 struct BSizeConstraintSolution {
     block_start: Au,
     _block_end: Au,
     block_size: Au,
     margin_block_start: Au,
     margin_block_end: Au
 }
 
@@ -342,18 +343,18 @@ impl CandidateBSizeIterator {
                 block_container_block_size.scale_by(percent)
             }
             (LengthOrPercentage::Percentage(_), None) => Au(0),
             (LengthOrPercentage::Length(length), _) => length,
         };
 
         // If the style includes `box-sizing: border-box`, subtract the border and padding.
         let adjustment_for_box_sizing = match fragment.style.get_box().box_sizing {
-            box_sizing::border_box => fragment.border_padding.block_start_end(),
-            box_sizing::content_box => Au(0),
+            box_sizing::T::border_box => fragment.border_padding.block_start_end(),
+            box_sizing::T::content_box => Au(0),
         };
 
         return CandidateBSizeIterator {
             block_size: block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
             max_block_size: max_block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
             min_block_size: adjust(min_block_size, adjustment_for_box_sizing),
             candidate_value: Au(0),
             status: CandidateBSizeIteratorStatus::Initial,
@@ -1318,22 +1319,22 @@ impl BlockFlow {
             {
                 let kid_base = flow::mut_base(kid);
                 kid_base.block_container_explicit_block_size = explicit_content_size;
                 kid_base.absolute_static_i_offset = absolute_static_i_offset;
                 kid_base.fixed_static_i_offset = fixed_static_i_offset;
             }
 
             match flow::base(kid).flags.float_kind() {
-                float::none => {}
-                float::left => {
+                float::T::none => {}
+                float::T::left => {
                     inline_size_of_preceding_left_floats = inline_size_of_preceding_left_floats +
                         flow::base(kid).intrinsic_inline_sizes.preferred_inline_size;
                 }
-                float::right => {
+                float::T::right => {
                     inline_size_of_preceding_right_floats = inline_size_of_preceding_right_floats +
                         flow::base(kid).intrinsic_inline_sizes.preferred_inline_size;
                 }
             }
 
             // The inline-start margin edge of the child flow is at our inline-start content edge,
             // and its inline-size is our content inline-size.
             {
@@ -1403,24 +1404,26 @@ impl BlockFlow {
             }
         }
     }
 
     /// Determines the type of formatting context this is. See the definition of
     /// `FormattingContextType`.
     fn formatting_context_type(&self) -> FormattingContextType {
         let style = self.fragment.style();
-        if style.get_box().float != float::none {
+        if style.get_box().float != float::T::none {
             return FormattingContextType::Other
         }
         match style.get_box().display {
-            display::table_cell | display::table_caption | display::inline_block => {
+            display::T::table_cell |
+            display::T::table_caption |
+            display::T::inline_block => {
                 FormattingContextType::Other
             }
-            _ if style.get_box().overflow != overflow::visible => FormattingContextType::Block,
+            _ if style.get_box().overflow != overflow::T::visible => FormattingContextType::Block,
             _ => FormattingContextType::None,
         }
     }
 
     /// Per CSS 2.1 § 9.5, block formatting contexts' inline widths and positions are affected by
     /// the presence of floats. This is the part of the assign-heights traversal that computes
     /// the final inline position and width for such flows.
     ///
@@ -1457,17 +1460,17 @@ impl BlockFlow {
 
         // TODO(pcwalton): If the inline-size of this flow is different from the size we estimated
         // earlier, lay it out again.
 
         self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
     }
 
     fn is_inline_block(&self) -> bool {
-        self.fragment.style().get_box().display == display::inline_block
+        self.fragment.style().get_box().display == display::T::inline_block
     }
 
     /// Computes the content portion (only) of the intrinsic inline sizes of this flow. This is
     /// used for calculating shrink-to-fit width. Assumes that intrinsic sizes have already been
     /// computed for this flow.
     fn content_intrinsic_inline_sizes(&self) -> IntrinsicISizes {
         let surrounding_inline_size = self.fragment.surrounding_intrinsic_inline_size();
         IntrinsicISizes {
@@ -1522,26 +1525,26 @@ impl Flow for BlockFlow {
             let child_base = flow::mut_base(kid);
             let float_kind = child_base.flags.float_kind();
             if !is_absolutely_positioned && !fixed_width {
                 computation.content_intrinsic_sizes.minimum_inline_size =
                     max(computation.content_intrinsic_sizes.minimum_inline_size,
                         child_base.intrinsic_inline_sizes.minimum_inline_size);
 
                 match float_kind {
-                    float::none => {
+                    float::T::none => {
                         computation.content_intrinsic_sizes.preferred_inline_size =
                             max(computation.content_intrinsic_sizes.preferred_inline_size,
                                 child_base.intrinsic_inline_sizes.preferred_inline_size);
                     }
-                    float::left => {
+                    float::T::left => {
                         left_float_width = left_float_width +
                             child_base.intrinsic_inline_sizes.preferred_inline_size;
                     }
-                    float::right => {
+                    float::T::right => {
                         right_float_width = right_float_width +
                             child_base.intrinsic_inline_sizes.preferred_inline_size;
                     }
                 }
             }
 
             flags.union_floated_descendants_flags(child_base.flags);
         }
@@ -1551,19 +1554,19 @@ impl Flow for BlockFlow {
         // says not to. In practice, Gecko and WebKit both do this.
         computation.content_intrinsic_sizes.preferred_inline_size =
             max(computation.content_intrinsic_sizes.preferred_inline_size,
                 left_float_width + right_float_width);
 
         self.base.intrinsic_inline_sizes = computation.finish();
 
         match self.fragment.style().get_box().float {
-            float::none => {}
-            float::left => flags.insert(HAS_LEFT_FLOATED_DESCENDANTS),
-            float::right => flags.insert(HAS_RIGHT_FLOATED_DESCENDANTS),
+            float::T::none => {}
+            float::T::left => flags.insert(HAS_LEFT_FLOATED_DESCENDANTS),
+            float::T::right => flags.insert(HAS_RIGHT_FLOATED_DESCENDANTS),
         }
         self.base.flags = flags
     }
 
     /// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
     /// When called on this context, the context has had its inline-size set by the parent context.
     ///
     /// Dual fragments consume some inline-size first, and the remainder is assigned to all child
@@ -1906,17 +1909,17 @@ impl fmt::Show for BlockFlow {
                self.class(),
                self.base.debug_id(),
                self.fragment,
                self.base)
     }
 }
 
 /// The inputs for the inline-sizes-and-margins constraint equation.
-#[deriving(Show)]
+#[deriving(Show, Copy)]
 pub struct ISizeConstraintInput {
     pub computed_inline_size: MaybeAuto,
     pub inline_start_margin: MaybeAuto,
     pub inline_end_margin: MaybeAuto,
     pub inline_start: MaybeAuto,
     pub inline_end: MaybeAuto,
     pub available_inline_size: Au,
     pub static_i_offset: Au,
@@ -1939,17 +1942,17 @@ impl ISizeConstraintInput {
             inline_end: inline_end,
             available_inline_size: available_inline_size,
             static_i_offset: static_i_offset,
         }
     }
 }
 
 /// The solutions for the inline-size-and-margins constraint equation.
-#[deriving(Show)]
+#[deriving(Copy, Show)]
 pub struct ISizeConstraintSolution {
     pub inline_start: Au,
     pub inline_end: Au,
     pub inline_size: Au,
     pub margin_inline_start: Au,
     pub margin_inline_end: Au
 }
 
@@ -2001,21 +2004,22 @@ pub trait ISizeAndMarginsComputer {
         block.fragment.compute_border_and_padding(containing_block_inline_size);
 
         let mut computed_inline_size = self.initial_computed_inline_size(block,
                                                                          parent_flow_inline_size,
                                                                          layout_context);
 
         let style = block.fragment.style();
         match (computed_inline_size, style.get_box().box_sizing) {
-            (MaybeAuto::Specified(size), box_sizing::border_box) => {
+            (MaybeAuto::Specified(size), box_sizing::T::border_box) => {
                 computed_inline_size =
                     MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end())
             }
-            (MaybeAuto::Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {}
+            (MaybeAuto::Auto, box_sizing::T::border_box) |
+            (_, box_sizing::T::content_box) => {}
         }
 
         // The text alignment of a block flow is the text alignment of its box's style.
         block.base.flags.set_text_align(style.get_inheritedtext().text_align);
 
         let margin = style.logical_margin();
         let position = style.logical_position();
 
--- a/servo/components/layout/construct.rs
+++ b/servo/components/layout/construct.rs
@@ -50,17 +50,17 @@ use script::dom::htmlobjectelement::is_i
 use script::dom::node::NodeTypeId;
 use servo_util::opts;
 use std::collections::DList;
 use std::mem;
 use std::sync::atomic::Relaxed;
 use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
 use style::computed_values::{position};
 use style::{mod, ComputedValues};
-use sync::Arc;
+use std::sync::Arc;
 use url::Url;
 
 /// The results of flow construction for a DOM node.
 #[deriving(Clone)]
 pub enum ConstructionResult {
     /// This node contributes nothing at all (`display: none`). Alternately, this is what newly
     /// created nodes have their `ConstructionResult` set to.
     None,
@@ -696,17 +696,17 @@ impl<'a> FlowConstructor<'a> {
                 node.style().clone(),
                 node.restyle_damage()))
         }
 
         // If the value of `display` property is not `inline`, then we have a situation like
         // `<div style="position:absolute">foo bar baz</div>`. The fragments for `foo`, `bar`, and
         // `baz` had better not be absolutely positioned!
         let mut style = (*node.style()).clone();
-        if style.get_box().display != display::inline {
+        if style.get_box().display != display::T::inline {
             style = Arc::new(style::make_inline(&*style))
         }
 
         // If this is generated content, then we need to initialize the accumulator with the
         // fragment corresponding to that content. Otherwise, just initialize with the ordinary
         // fragment that needs to be generated for this inline node.
         let fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal {
             let fragment_info =
@@ -854,17 +854,17 @@ impl<'a> FlowConstructor<'a> {
     }
 
     /// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with
     /// possibly other `TableCaptionFlow`s or `TableFlow`s underneath it.
     fn build_flow_for_table_wrapper(&mut self, node: &ThreadSafeLayoutNode,
                                     float_value: float::T) -> ConstructionResult {
         let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableWrapper);
         let wrapper_flow = match float_value {
-            float::none => box TableWrapperFlow::from_node_and_fragment(node, fragment),
+            float::T::none => box TableWrapperFlow::from_node_and_fragment(node, fragment),
             _ => {
                 let float_kind = FloatKind::from_property(float_value);
                 box TableWrapperFlow::float_from_node_and_fragment(node, fragment, float_kind)
             }
         };
         let mut wrapper_flow = FlowRef::new(wrapper_flow as Box<Flow>);
 
         let table_fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::Table);
@@ -877,30 +877,30 @@ impl<'a> FlowConstructor<'a> {
         let mut abs_descendants = Descendants::new();
         let mut fixed_descendants = Descendants::new();
 
         // The order of the caption and the table are not necessarily the same order as in the DOM
         // tree. All caption blocks are placed before or after the table flow, depending on the
         // value of `caption-side`.
         self.place_table_caption_under_table_wrapper_on_side(&mut wrapper_flow,
                                                              node,
-                                                             caption_side::top);
+                                                             caption_side::T::top);
 
         match construction_result {
             ConstructionResult::Flow(table_flow, table_abs_descendants) => {
                 wrapper_flow.add_new_child(table_flow);
                 abs_descendants.push_descendants(table_abs_descendants);
             }
             _ => {}
         }
 
         // If the value of `caption-side` is `bottom`, place it now.
         self.place_table_caption_under_table_wrapper_on_side(&mut wrapper_flow,
                                                              node,
-                                                             caption_side::bottom);
+                                                             caption_side::T::bottom);
 
         // The flow is done.
         wrapper_flow.finish();
         let is_positioned = wrapper_flow.as_block().is_positioned();
         let is_fixed_positioned = wrapper_flow.as_block().is_fixed();
         let is_absolutely_positioned = flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
         if is_positioned {
             // This is the containing block for all the absolute descendants.
@@ -949,20 +949,22 @@ impl<'a> FlowConstructor<'a> {
     /// Builds a flow for a node with `display: table-cell`. This yields a `TableCellFlow` with
     /// possibly other `BlockFlow`s or `InlineFlow`s underneath it.
     fn build_flow_for_table_cell(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
         let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableCell);
 
         // Determine if the table cell should be hidden. Per CSS 2.1 § 17.6.1.1, this will be true
         // if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to
         // `hide`.
-        let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide &&
+        let hide = node.style().get_inheritedtable().empty_cells == empty_cells::T::hide &&
             node.children().all(|kid| {
                 let position = kid.style().get_box().position;
-                !kid.is_content() || position == position::absolute || position == position::fixed
+                !kid.is_content() ||
+                position == position::T::absolute ||
+                position == position::T::fixed
             });
 
         let flow = box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide)
             as Box<Flow>;
         self.build_flow_for_block(FlowRef::new(flow), node)
     }
 
     /// Builds a flow for a node with `display: list-item`. This yields a `ListItemFlow` with
@@ -998,21 +1000,21 @@ impl<'a> FlowConstructor<'a> {
         // If the list marker is outside, it becomes the special "outside fragment" that list item
         // flows have. If it's inside, it's just a plain old fragment. Note that this means that
         // we adopt Gecko's behavior rather than WebKit's when the marker causes an {ib} split,
         // which has caused some malaise (Bugzilla #36854) but CSS 2.1 § 12.5.1 lets me do it, so
         // there.
         let flow;
         let initial_fragment;
         match node.style().get_list().list_style_position {
-            list_style_position::outside => {
+            list_style_position::T::outside => {
                 flow = box ListItemFlow::from_node_and_marker(self, node, marker_fragment);
                 initial_fragment = None;
             }
-            list_style_position::inside => {
+            list_style_position::T::inside => {
                 flow = box ListItemFlow::from_node_and_marker(self, node, None);
                 initial_fragment = marker_fragment;
             }
         }
 
         self.build_flow_for_block_starting_with_fragment(FlowRef::new(flow as Box<Flow>),
                                                          node,
                                                          initial_fragment)
@@ -1112,140 +1114,142 @@ impl<'a> PostorderNodeMutTraversal for F
     // final computed value for 'display'.
     fn process(&mut self, node: &ThreadSafeLayoutNode) -> bool {
         // Get the `display` property for this node, and determine whether this node is floated.
         let (display, float, positioning) = match node.type_id() {
             None => {
                 // Pseudo-element.
                 let style = node.style();
                 let display = match node.get_pseudo_element_type() {
-                    PseudoElementType::Normal => display::inline,
+                    PseudoElementType::Normal => display::T::inline,
                     PseudoElementType::Before(display) => display,
                     PseudoElementType::After(display) => display,
                 };
                 (display, style.get_box().float, style.get_box().position)
             }
             Some(NodeTypeId::Element(_)) => {
                 let style = node.style();
                 let munged_display = if style.get_box()._servo_display_for_hypothetical_box ==
-                        display::inline {
-                    display::inline
+                        display::T::inline {
+                    display::T::inline
                 } else {
                     style.get_box().display
                 };
                 (munged_display, style.get_box().float, style.get_box().position)
             }
-            Some(NodeTypeId::Text) => (display::inline, float::none, position::static_),
+            Some(NodeTypeId::Text) => (display::T::inline, float::T::none, position::T::static_),
             Some(NodeTypeId::Comment) |
             Some(NodeTypeId::DocumentType) |
             Some(NodeTypeId::DocumentFragment) |
             Some(NodeTypeId::Document) |
             Some(NodeTypeId::ProcessingInstruction) => {
-                (display::none, float::none, position::static_)
+                (display::T::none, float::T::none, position::T::static_)
             }
         };
 
         debug!("building flow for node: {} {}", display, float);
 
         // Switch on display and floatedness.
         match (display, float, positioning) {
             // `display: none` contributes no flow construction result. Nuke the flow construction
             // results of children.
-            (display::none, _, _) => {
+            (display::T::none, _, _) => {
                 for child in node.children() {
                     drop(child.swap_out_construction_result())
                 }
             }
 
             // Table items contribute table flow construction results.
-            (display::table, float_value, _) => {
+            (display::T::table, float_value, _) => {
                 let construction_result = self.build_flow_for_table_wrapper(node, float_value);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Absolutely positioned elements will have computed value of
             // `float` as 'none' and `display` as per the table.
             // Only match here for block items. If an item is absolutely
             // positioned, but inline we shouldn't try to construct a block
             // flow here - instead, let it match the inline case
             // below.
-            (display::block, _, position::absolute) | (_, _, position::fixed) => {
+            (display::T::block, _, position::T::absolute) |
+            (_, _, position::T::fixed) => {
                 node.set_flow_construction_result(self.build_flow_for_nonfloated_block(node))
             }
 
             // List items contribute their own special flows.
-            (display::list_item, _, _) => {
+            (display::T::list_item, _, _) => {
                 node.set_flow_construction_result(self.build_flow_for_list_item(node))
             }
 
             // Inline items that are absolutely-positioned contribute inline fragment construction
             // results with a hypothetical fragment.
-            (display::inline, _, position::absolute) => {
+            (display::T::inline, _, position::T::absolute) => {
                 let construction_result =
                     self.build_fragment_for_absolutely_positioned_inline(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Inline items contribute inline fragment construction results.
             //
             // FIXME(pcwalton, #3307): This is not sufficient to handle floated generated content.
-            (display::inline, float::none, _) => {
+            (display::T::inline, float::T::none, _) => {
                 let construction_result = self.build_fragments_for_inline(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Inline-block items contribute inline fragment construction results.
-            (display::inline_block, float::none, _) => {
+            (display::T::inline_block, float::T::none, _) => {
                 let construction_result = self.build_fragment_for_inline_block(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Table items contribute table flow construction results.
-            (display::table_caption, _, _) => {
+            (display::T::table_caption, _, _) => {
                 let construction_result = self.build_flow_for_table_caption(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Table items contribute table flow construction results.
-            (display::table_column_group, _, _) => {
+            (display::T::table_column_group, _, _) => {
                 let construction_result = self.build_flow_for_table_colgroup(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Table items contribute table flow construction results.
-            (display::table_column, _, _) => {
+            (display::T::table_column, _, _) => {
                 let construction_result = self.build_fragments_for_table_column(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Table items contribute table flow construction results.
-            (display::table_row_group, _, _) | (display::table_header_group, _, _) |
-            (display::table_footer_group, _, _) => {
+            (display::T::table_row_group, _, _) |
+            (display::T::table_header_group, _, _) |
+            (display::T::table_footer_group, _, _) => {
                 let construction_result = self.build_flow_for_table_rowgroup(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Table items contribute table flow construction results.
-            (display::table_row, _, _) => {
+            (display::T::table_row, _, _) => {
                 let construction_result = self.build_flow_for_table_row(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Table items contribute table flow construction results.
-            (display::table_cell, _, _) => {
+            (display::T::table_cell, _, _) => {
                 let construction_result = self.build_flow_for_table_cell(node);
                 node.set_flow_construction_result(construction_result)
             }
 
             // Block flows that are not floated contribute block flow construction results.
             //
             // TODO(pcwalton): Make this only trigger for blocks and handle the other `display`
             // properties separately.
 
-            (_, float::none, _) => {
+            (_, float::T::none, _) => {
                 node.set_flow_construction_result(self.build_flow_for_nonfloated_block(node))
             }
 
             // Floated flows contribute float flow construction results.
             (_, float_value, _) => {
                 let float_kind = FloatKind::from_property(float_value);
                 node.set_flow_construction_result(
                     self.build_flow_for_floated_block(node, float_kind))
--- a/servo/components/layout/context.rs
+++ b/servo/components/layout/context.rs
@@ -10,46 +10,44 @@ use geom::{Rect, Size2D};
 use gfx::display_list::OpaqueNode;
 use gfx::font_context::FontContext;
 use gfx::font_cache_task::FontCacheTask;
 use script::layout_interface::LayoutChan;
 use script_traits::UntrustedNodeAddress;
 use servo_msg::constellation_msg::ConstellationChan;
 use servo_net::local_image_cache::LocalImageCache;
 use servo_util::geometry::Au;
-use sync::{Arc, Mutex};
+use std::cell::Cell;
 use std::mem;
+use std::ptr;
+use std::sync::{Arc, Mutex};
 use style::Stylist;
 use url::Url;
 
 struct LocalLayoutContext {
     font_context: FontContext,
     applicable_declarations_cache: ApplicableDeclarationsCache,
     style_sharing_candidate_cache: StyleSharingCandidateCache,
 }
 
-local_data_key!(local_context_key: *mut LocalLayoutContext)
+thread_local!(static local_context_key: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut()))
 
 fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext {
-    let maybe_context = local_context_key.get();
-
-    let context = match maybe_context {
-        None => {
+    local_context_key.with(|ref r| {
+        if r.get().is_null() {
             let context = box LocalLayoutContext {
                 font_context: FontContext::new(shared_layout_context.font_cache_task.clone()),
                 applicable_declarations_cache: ApplicableDeclarationsCache::new(),
                 style_sharing_candidate_cache: StyleSharingCandidateCache::new(),
             };
-            local_context_key.replace(Some(unsafe { mem::transmute(context) }));
-            local_context_key.get().unwrap()
-        },
-        Some(context) => context
-    };
+            r.set(unsafe { mem::transmute(context) });
+        }
 
-    *context
+        r.get()
+    })
 }
 
 pub struct SharedLayoutContext {
     /// The local image cache.
     pub image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>,
 
     /// The current screen size.
     pub screen_size: Size2D<Au>,
--- a/servo/components/layout/css/matching.rs
+++ b/servo/components/layout/css/matching.rs
@@ -15,17 +15,17 @@ use servo_util::cache::{Cache, LRUCache,
 use servo_util::smallvec::{SmallVec, SmallVec16};
 use servo_util::arc_ptr_eq;
 use std::mem;
 use std::hash::{Hash, sip};
 use std::slice::Items;
 use string_cache::{Atom, Namespace};
 use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
 use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade};
-use sync::Arc;
+use std::sync::Arc;
 
 pub struct ApplicableDeclarations {
     pub normal: SmallVec16<DeclarationBlock>,
     pub before: Vec<DeclarationBlock>,
     pub after: Vec<DeclarationBlock>,
 
     /// Whether the `normal` declarations are shareable with other nodes.
     pub normal_shareable: bool,
--- a/servo/components/layout/css/node_style.rs
+++ b/servo/components/layout/css/node_style.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Style retrieval from DOM elements.
 
 use wrapper::{PseudoElementType, ThreadSafeLayoutNode};
 
 use std::mem;
 use style::ComputedValues;
-use sync::Arc;
+use std::sync::Arc;
 
 /// Node mixin providing `style` method that returns a `NodeStyle`
 pub trait StyledNode {
     /// Returns the style results for the given node. If CSS selector matching has not yet been
     /// performed, fails.
     fn style<'a>(&'a self) -> &'a Arc<ComputedValues>;
     /// Does this node have a computed style yet?
     fn has_style(&self) -> bool;
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -23,37 +23,37 @@ use util::{OpaqueNodeMethods, ToGfxColor
 use geom::approxeq::ApproxEq;
 use geom::{Point2D, Rect, Size2D, SideOffsets2D};
 use gfx::color;
 use gfx::display_list::{BOX_SHADOW_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
 use gfx::display_list::{BorderRadii, BoxShadowDisplayItem, ClippingRegion};
 use gfx::display_list::{DisplayItem, DisplayList, DisplayItemMetadata};
 use gfx::display_list::{GradientDisplayItem};
 use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem};
-use gfx::display_list::{SidewaysLeft};
-use gfx::display_list::{SidewaysRight, SolidColorDisplayItem};
-use gfx::display_list::{StackingContext, TextDisplayItem, Upright};
+use gfx::display_list::TextOrientation;
+use gfx::display_list::{SolidColorDisplayItem};
+use gfx::display_list::{StackingContext, TextDisplayItem};
 use gfx::paint_task::PaintLayer;
-use servo_msg::compositor_msg::{FixedPosition, Scrollable};
+use servo_msg::compositor_msg::ScrollPolicy;
 use servo_msg::constellation_msg::Msg as ConstellationMsg;
 use servo_msg::constellation_msg::ConstellationChan;
 use servo_net::image::holder::ImageHolder;
-use servo_util::cursor::{DefaultCursor, TextCursor, VerticalTextCursor};
+use servo_util::cursor::Cursor;
 use servo_util::geometry::{mod, Au};
 use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
 use servo_util::opts;
 use std::default::Default;
 use std::num::FloatMath;
 use style::computed::{AngleOrCorner, LengthOrPercentage, HorizontalDirection, VerticalDirection};
 use style::computed::{Image, LinearGradient};
 use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
 use style::computed_values::{position, visibility};
 use style::style_structs::Border;
 use style::{ComputedValues, RGBA};
-use sync::Arc;
+use std::sync::Arc;
 use url::Url;
 
 /// The results of display list building for a single flow.
 pub enum DisplayListBuildingResult {
     None,
     StackingContext(Arc<StackingContext>),
     Normal(Box<DisplayList>),
 }
@@ -248,17 +248,17 @@ impl FragmentDisplayListBuilding for Fra
         // inefficient. What we really want is something like "nearest ancestor element that
         // doesn't have a fragment".
         let background_color = style.resolve_color(style.get_background().background_color);
         if !background_color.alpha.approx_eq(&0.0) {
             display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
                 base: BaseDisplayItem::new(*absolute_bounds,
                                            DisplayItemMetadata::new(self.node,
                                                                     style,
-                                                                    DefaultCursor),
+                                                                    Cursor::DefaultCursor),
                                            clip.clone()),
                 color: background_color.to_gfx_color(),
             }), level);
         }
 
         // The background image is painted on top of the background color.
         // Implements background image, per spec:
         // http://www.w3.org/TR/CSS21/colors.html#background
@@ -314,65 +314,65 @@ impl FragmentDisplayListBuilding for Fra
 
         // Clip.
         //
         // TODO: Check the bounds to see if a clip item is actually required.
         let clip = clip.clone().intersect_rect(&bounds);
 
         // Use background-attachment to get the initial virtual origin
         let (virtual_origin_x, virtual_origin_y) = match background.background_attachment {
-            background_attachment::scroll => {
+            background_attachment::T::scroll => {
                 (absolute_bounds.origin.x, absolute_bounds.origin.y)
             }
-            background_attachment::fixed => {
+            background_attachment::T::fixed => {
                 (Au(0), Au(0))
             }
         };
 
         // Use background-position to get the offset
         let horizontal_position = model::specified(background.background_position.horizontal,
                                                    bounds.size.width - image_width);
         let vertical_position = model::specified(background.background_position.vertical,
                                                  bounds.size.height - image_height);
 
         let abs_x = virtual_origin_x + horizontal_position;
         let abs_y = virtual_origin_y + vertical_position;
 
         // Adjust origin and size based on background-repeat
         match background.background_repeat {
-            background_repeat::no_repeat => {
+            background_repeat::T::no_repeat => {
                 bounds.origin.x = abs_x;
                 bounds.origin.y = abs_y;
                 bounds.size.width = image_width;
                 bounds.size.height = image_height;
             }
-            background_repeat::repeat_x => {
+            background_repeat::T::repeat_x => {
                 bounds.origin.y = abs_y;
                 bounds.size.height = image_height;
                 ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width,
                                                 abs_x, image.width);
             }
-            background_repeat::repeat_y => {
+            background_repeat::T::repeat_y => {
                 bounds.origin.x = abs_x;
                 bounds.size.width = image_width;
                 ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height,
                                                 abs_y, image.height);
             }
-            background_repeat::repeat => {
+            background_repeat::T::repeat => {
                 ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width,
                                                 abs_x, image.width);
                 ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height,
                                                 abs_y, image.height);
             }
         };
 
         // Create the image display item.
         display_list.push(DisplayItem::ImageClass(box ImageDisplayItem {
             base: BaseDisplayItem::new(bounds,
-                                       DisplayItemMetadata::new(self.node, style, DefaultCursor),
+                                       DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor),
                                        clip),
             image: image.clone(),
             stretch_size: Size2D(Au::from_px(image.width as int),
                                  Au::from_px(image.height as int)),
         }), level);
     }
 
     fn build_display_list_for_background_linear_gradient(&self,
@@ -472,17 +472,17 @@ impl FragmentDisplayListBuilding for Fra
             })
         }
 
         let center = Point2D(absolute_bounds.origin.x + absolute_bounds.size.width / 2,
                              absolute_bounds.origin.y + absolute_bounds.size.height / 2);
 
         let gradient_display_item = DisplayItem::GradientClass(box GradientDisplayItem {
             base: BaseDisplayItem::new(*absolute_bounds,
-                                       DisplayItemMetadata::new(self.node, style, DefaultCursor),
+                                       DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor),
                                        clip),
             start_point: center - delta,
             end_point: center + delta,
             stops: stops,
         });
 
         display_list.push(gradient_display_item, level)
     }
@@ -500,17 +500,17 @@ impl FragmentDisplayListBuilding for Fra
                 BOX_SHADOW_INFLATION_FACTOR;
             let bounds =
                 absolute_bounds.translate(&Point2D(box_shadow.offset_x, box_shadow.offset_y))
                                .inflate(inflation, inflation);
             list.push(DisplayItem::BoxShadowClass(box BoxShadowDisplayItem {
                 base: BaseDisplayItem::new(bounds,
                                            DisplayItemMetadata::new(self.node,
                                                                     style,
-                                                                    DefaultCursor),
+                                                                    Cursor::DefaultCursor),
                                            (*clip).clone()),
                 box_bounds: *absolute_bounds,
                 color: style.resolve_color(box_shadow.color).to_gfx_color(),
                 offset: Point2D(box_shadow.offset_x, box_shadow.offset_y),
                 blur_radius: box_shadow.blur_radius,
                 spread_radius: box_shadow.spread_radius,
                 inset: box_shadow.inset,
             }), level);
@@ -531,17 +531,17 @@ impl FragmentDisplayListBuilding for Fra
         let top_color = style.resolve_color(style.get_border().border_top_color);
         let right_color = style.resolve_color(style.get_border().border_right_color);
         let bottom_color = style.resolve_color(style.get_border().border_bottom_color);
         let left_color = style.resolve_color(style.get_border().border_left_color);
 
         // Append the border to the display list.
         display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
             base: BaseDisplayItem::new(*abs_bounds,
-                                       DisplayItemMetadata::new(self.node, style, DefaultCursor),
+                                       DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor),
                                        (*clip).clone()),
             border_widths: border.to_physical(style.writing_mode),
             color: SideOffsets2D::new(top_color.to_gfx_color(),
                                       right_color.to_gfx_color(),
                                       bottom_color.to_gfx_color(),
                                       left_color.to_gfx_color()),
             style: SideOffsets2D::new(style.get_border().border_top_style,
                                       style.get_border().border_right_style,
@@ -557,33 +557,33 @@ impl FragmentDisplayListBuilding for Fra
                                                     bounds: &Rect<Au>,
                                                     clip: &ClippingRegion) {
         let width = style.get_outline().outline_width;
         if width == Au(0) {
             return
         }
 
         let outline_style = style.get_outline().outline_style;
-        if outline_style == border_style::none {
+        if outline_style == border_style::T::none {
             return
         }
 
         // Outlines are not accounted for in the dimensions of the border box, so adjust the
         // absolute bounds.
         let mut bounds = *bounds;
         bounds.origin.x = bounds.origin.x - width;
         bounds.origin.y = bounds.origin.y - width;
         bounds.size.width = bounds.size.width + width + width;
         bounds.size.height = bounds.size.height + width + width;
 
         // Append the outline to the display list.
         let color = style.resolve_color(style.get_outline().outline_color).to_gfx_color();
         display_list.outlines.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
             base: BaseDisplayItem::new(bounds,
-                                       DisplayItemMetadata::new(self.node, style, DefaultCursor),
+                                       DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor),
                                        (*clip).clone()),
             border_widths: SideOffsets2D::new_all_same(width),
             color: SideOffsets2D::new_all_same(color),
             style: SideOffsets2D::new_all_same(outline_style),
             radius: Default::default(),
         }))
     }
 
@@ -595,68 +595,68 @@ impl FragmentDisplayListBuilding for Fra
                                                  text_fragment: &ScannedTextFragmentInfo,
                                                  clip: &ClippingRegion) {
         // FIXME(pcwalton, #2795): Get the real container size.
         let container_size = Size2D::zero();
 
         // Compute the text fragment bounds and draw a border surrounding them.
         display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
             base: BaseDisplayItem::new(*stacking_relative_border_box,
-                                       DisplayItemMetadata::new(self.node, style, DefaultCursor),
+                                       DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor),
                                        (*clip).clone()),
             border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
             color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
-            style: SideOffsets2D::new_all_same(border_style::solid),
+            style: SideOffsets2D::new_all_same(border_style::T::solid),
             radius: Default::default(),
         }));
 
         // Draw a rectangle representing the baselines.
         let mut baseline = LogicalRect::from_physical(self.style.writing_mode,
                                                       *stacking_relative_content_box,
                                                       container_size);
         baseline.start.b = baseline.start.b + text_fragment.run.ascent();
         baseline.size.block = Au(0);
         let baseline = baseline.to_physical(self.style.writing_mode, container_size);
 
         let line_display_item = box LineDisplayItem {
             base: BaseDisplayItem::new(baseline,
-                                       DisplayItemMetadata::new(self.node, style, DefaultCursor),
+                                       DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor),
                                        (*clip).clone()),
             color: color::rgb(0, 200, 0),
-            style: border_style::dashed,
+            style: border_style::T::dashed,
         };
         display_list.content.push_back(DisplayItem::LineClass(line_display_item));
     }
 
     fn build_debug_borders_around_fragment(&self,
                                            display_list: &mut DisplayList,
                                            stacking_relative_border_box: &Rect<Au>,
                                            clip: &ClippingRegion) {
         // This prints a debug border around the border of this fragment.
         display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
             base: BaseDisplayItem::new(*stacking_relative_border_box,
                                        DisplayItemMetadata::new(self.node,
                                                                 &*self.style,
-                                                                DefaultCursor),
+                                                                Cursor::DefaultCursor),
                                        (*clip).clone()),
             border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
             color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
-            style: SideOffsets2D::new_all_same(border_style::solid),
+            style: SideOffsets2D::new_all_same(border_style::T::solid),
             radius: Default::default(),
         }));
     }
 
     fn calculate_style_specified_clip(&self,
                                       parent_clip: &ClippingRegion,
                                       stacking_relative_border_box: &Rect<Au>)
                                       -> ClippingRegion {
         // Account for `clip` per CSS 2.1 § 11.1.2.
         let style_clip_rect = match (self.style().get_box().position,
                                      self.style().get_effects().clip) {
-            (position::absolute, Some(style_clip_rect)) => style_clip_rect,
+            (position::T::absolute, Some(style_clip_rect)) => style_clip_rect,
             _ => return (*parent_clip).clone(),
         };
 
         // FIXME(pcwalton, #2795): Get the real container size.
         let clip_origin = Point2D(stacking_relative_border_box.origin.x + style_clip_rect.left,
                                   stacking_relative_border_box.origin.y + style_clip_rect.top);
         let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
         let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
@@ -681,17 +681,17 @@ impl FragmentDisplayListBuilding for Fra
 
         debug!("Fragment::build_display_list at rel={}, abs={}, dirty={}, flow origin={}: {}",
                self.border_box,
                stacking_relative_border_box,
                layout_context.shared.dirty,
                stacking_relative_flow_origin,
                self);
 
-        if self.style().get_inheritedbox().visibility != visibility::visible {
+        if self.style().get_inheritedbox().visibility != visibility::T::visible {
             return
         }
 
         if !stacking_relative_border_box.intersects(&layout_context.shared.dirty) {
             debug!("Fragment::build_display_list: Did not intersect...");
             return
         }
 
@@ -843,17 +843,17 @@ impl FragmentDisplayListBuilding for Fra
                 if let Some(image) = image_ref.get_image(self.node.to_untrusted_node_address()) {
                     debug!("(building display list) building image fragment");
 
                     // Place the image into the display list.
                     display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem {
                         base: BaseDisplayItem::new(stacking_relative_content_box,
                                                    DisplayItemMetadata::new(self.node,
                                                                             &*self.style,
-                                                                            DefaultCursor),
+                                                                            Cursor::DefaultCursor),
                                                    (*clip).clone()),
                         image: image.clone(),
                         stretch_size: stacking_relative_content_box.size,
                     }));
                 } else {
                     // No image data at all? Do nothing.
                     //
                     // TODO: Add some kind of placeholder image.
@@ -894,39 +894,39 @@ impl FragmentDisplayListBuilding for Fra
         }
 
         // Account for style-specified `clip`.
         let current_clip = self.calculate_style_specified_clip(current_clip,
                                                                stacking_relative_border_box);
 
         // Only clip if `overflow` tells us to.
         match self.style.get_box().overflow {
-            overflow::hidden | overflow::auto | overflow::scroll => {
+            overflow::T::hidden | overflow::T::auto | overflow::T::scroll => {
                 // Create a new clip rect.
                 current_clip.intersect_rect(stacking_relative_border_box)
             }
             _ => current_clip,
         }
     }
 
     fn build_display_list_for_text_fragment(&self,
                                             display_list: &mut DisplayList,
                                             text_fragment: &ScannedTextFragmentInfo,
                                             text_color: RGBA,
                                             stacking_relative_content_box: &Rect<Au>,
                                             clip: &ClippingRegion) {
         // Determine the orientation and cursor to use.
         let (orientation, cursor) = if self.style.writing_mode.is_vertical() {
             if self.style.writing_mode.is_sideways_left() {
-                (SidewaysLeft, VerticalTextCursor)
+                (TextOrientation::SidewaysLeft, Cursor::VerticalTextCursor)
             } else {
-                (SidewaysRight, VerticalTextCursor)
+                (TextOrientation::SidewaysRight, Cursor::VerticalTextCursor)
             }
         } else {
-            (Upright, TextCursor)
+            (TextOrientation::Upright, Cursor::TextCursor)
         };
 
         // Compute location of the baseline.
         //
         // FIXME(pcwalton): Get the real container size.
         let container_size = Size2D::zero();
         let metrics = &text_fragment.run.font_metrics;
         let baseline_origin = stacking_relative_content_box.origin +
@@ -990,17 +990,17 @@ impl FragmentDisplayListBuilding for Fra
                                               color: &RGBA,
                                               stacking_relative_box: &LogicalRect<Au>,
                                               clip: &ClippingRegion) {
         // FIXME(pcwalton, #2795): Get the real container size.
         let container_size = Size2D::zero();
         let stacking_relative_box = stacking_relative_box.to_physical(self.style.writing_mode,
                                                                       container_size);
 
-        let metadata = DisplayItemMetadata::new(self.node, &*self.style, DefaultCursor);
+        let metadata = DisplayItemMetadata::new(self.node, &*self.style, Cursor::DefaultCursor);
         display_list.content.push_back(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
             base: BaseDisplayItem::new(stacking_relative_box, metadata, (*clip).clone()),
             color: color.to_gfx_color(),
         }))
     }
 }
 
 pub trait BlockFlowDisplayListBuilding {
@@ -1078,19 +1078,19 @@ impl BlockFlowDisplayListBuilding for Bl
                 DisplayListBuildingResult::StackingContext(self.create_stacking_context(
                         display_list,
                         None));
             return
         }
 
         // If we got here, then we need a new layer.
         let scroll_policy = if self.is_fixed() {
-            FixedPosition
+            ScrollPolicy::FixedPosition
         } else {
-            Scrollable
+            ScrollPolicy::Scrollable
         };
 
         let transparent = color::rgba(1.0, 1.0, 1.0, 0.0);
         let stacking_context =
             self.create_stacking_context(display_list,
                                          Some(Arc::new(PaintLayer::new(self.layer_id(0),
                                                                        transparent,
                                                                        scroll_policy))));
@@ -1158,17 +1158,17 @@ impl BlockFlowDisplayListBuilding for Bl
 pub trait InlineFlowDisplayListBuilding {
     fn build_display_list_for_inline(&mut self, layout_context: &LayoutContext);
 }
 
 impl InlineFlowDisplayListBuilding for InlineFlow {
     fn build_display_list_for_inline(&mut self, layout_context: &LayoutContext) {
         // TODO(#228): Once we form lines and have their cached bounds, we can be smarter and
         // not recurse on a line if nothing in it can intersect the dirty region.
-        debug!("Flow: building display list for {:u} inline fragments", self.fragments.len());
+        debug!("Flow: building display list for {} inline fragments", self.fragments.len());
 
         let mut display_list = box DisplayList::new();
         for fragment in self.fragments.fragments.iter_mut() {
             fragment.build_display_list(&mut *display_list,
                                         layout_context,
                                         &self.base.stacking_relative_position,
                                         &self.base
                                              .absolute_position_info
@@ -1222,16 +1222,17 @@ impl ListItemFlowDisplayListBuilding for
         }
 
         // Draw the rest of the block.
         self.block_flow.build_display_list_for_block(display_list, layout_context)
     }
 }
 
 // A helper data structure for gradients.
+#[deriving(Copy)]
 struct StopRun {
     start_offset: f32,
     end_offset: f32,
     start_index: uint,
     stop_count: uint,
 }
 
 fn fmin(a: f32, b: f32) -> f32 {
@@ -1245,17 +1246,17 @@ fn fmin(a: f32, b: f32) -> f32 {
 fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32 {
     match position {
         LengthOrPercentage::Length(Au(length)) => fmin(1.0, (length as f32) / (total_length as f32)),
         LengthOrPercentage::Percentage(percentage) => percentage as f32,
     }
 }
 
 /// "Steps" as defined by CSS 2.1 § E.2.
-#[deriving(Clone, PartialEq, Show)]
+#[deriving(Clone, PartialEq, Show, Copy)]
 pub enum StackingLevel {
     /// The border and backgrounds for the root of this stacking context: steps 1 and 2.
     BackgroundAndBorders,
     /// Borders and backgrounds for block-level descendants: step 4.
     BlockBackgroundsAndBorders,
     /// All other content.
     Content,
 }
--- a/servo/components/layout/floats.rs
+++ b/servo/components/layout/floats.rs
@@ -7,41 +7,42 @@ use servo_util::logical_geometry::Writin
 use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
 use servo_util::persistent_list::PersistentList;
 use std::cmp::{max, min};
 use std::i32;
 use std::fmt;
 use style::computed_values::float;
 
 /// The kind of float: left or right.
-#[deriving(Clone, Encodable, Show)]
+#[deriving(Clone, Encodable, Show, Copy)]
 pub enum FloatKind {
     Left,
     Right
 }
 
 impl FloatKind {
     pub fn from_property(property: float::T) -> FloatKind {
         match property {
-            float::none => panic!("can't create a float type from an unfloated property"),
-            float::left => FloatKind::Left,
-            float::right => FloatKind::Right,
+            float::T::none => panic!("can't create a float type from an unfloated property"),
+            float::T::left => FloatKind::Left,
+            float::T::right => FloatKind::Right,
         }
     }
 }
 
 /// The kind of clearance: left, right, or both.
+#[deriving(Copy)]
 pub enum ClearType {
     Left,
     Right,
     Both,
 }
 
 /// Information about a single float.
-#[deriving(Clone)]
+#[deriving(Clone, Copy)]
 struct Float {
     /// The boundaries of this float.
     bounds: LogicalRect<Au>,
     /// The kind of float: left or right.
     kind: FloatKind,
 }
 
 impl fmt::Show for Float {
--- a/servo/components/layout/flow.rs
+++ b/servo/components/layout/flow.rs
@@ -55,17 +55,17 @@ use servo_util::logical_geometry::{Logic
 use std::mem;
 use std::fmt;
 use std::iter::Zip;
 use std::raw;
 use std::sync::atomic::{AtomicUint, SeqCst};
 use std::slice::MutItems;
 use style::computed_values::{clear, empty_cells, float, position, text_align};
 use style::ComputedValues;
-use sync::Arc;
+use std::sync::Arc;
 
 /// Virtual methods that make up a float context.
 ///
 /// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding
 /// methods to `ImmutableFlowUtils` or `MutableFlowUtils` before adding more methods here.
 pub trait Flow: fmt::Show + ToString + Sync {
     // RTTI
     //
@@ -250,30 +250,30 @@ pub trait Flow: fmt::Show + ToString + S
     }
 
     fn is_root(&self) -> bool {
         false
     }
 
     /// The 'position' property of this flow.
     fn positioning(&self) -> position::T {
-        position::static_
+        position::T::static_
     }
 
     /// Return true if this flow has position 'fixed'.
     fn is_fixed(&self) -> bool {
-        self.positioning() == position::fixed
+        self.positioning() == position::T::fixed
     }
 
     fn is_positioned(&self) -> bool {
         self.is_relatively_positioned() || base(self).flags.contains(IS_ABSOLUTELY_POSITIONED)
     }
 
     fn is_relatively_positioned(&self) -> bool {
-        self.positioning() == position::relative
+        self.positioning() == position::T::relative
     }
 
     /// Return true if this is the root of an absolute flow tree.
     fn is_root_of_absolute_flow_tree(&self) -> bool {
         false
     }
 
     /// Returns true if this is an absolute containing block.
@@ -466,16 +466,17 @@ pub trait PostorderFlowTraversal {
     /// child nodes are visited.
     fn should_process(&self, _flow: &mut Flow) -> bool {
         true
     }
 }
 
 bitflags! {
     #[doc = "Flags used in flows."]
+    #[deriving(Copy)]
     flags FlowFlags: u16 {
         // floated descendants flags
         #[doc = "Whether this flow has descendants that float left in the same block formatting"]
         #[doc = "context."]
         const HAS_LEFT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0001,
         #[doc = "Whether this flow has descendants that float right in the same block formatting"]
         #[doc = "context."]
         const HAS_RIGHT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0010,
@@ -570,21 +571,21 @@ impl FlowFlags {
         } else {
             self.remove(flags);
         }
     }
 
     #[inline]
     pub fn float_kind(&self) -> float::T {
         if self.contains(FLOATS_LEFT) {
-            float::left
+            float::T::left
         } else if self.contains(FLOATS_RIGHT) {
-            float::right
+            float::T::right
         } else {
-            float::none
+            float::T::none
         }
     }
 
     #[inline]
     pub fn is_float(&self) -> bool {
         self.contains(FLOATS_LEFT) || self.contains(FLOATS_RIGHT)
     }
 
@@ -653,27 +654,27 @@ impl Descendants {
 }
 
 pub type AbsDescendants = Descendants;
 
 pub struct DescendantIter<'a> {
     iter: MutItems<'a, FlowRef>,
 }
 
-impl<'a> Iterator<&'a mut Flow + 'a> for DescendantIter<'a> {
-    fn next(&mut self) -> Option<&'a mut Flow + 'a> {
+impl<'a> Iterator<&'a mut (Flow + 'a)> for DescendantIter<'a> {
+    fn next(&mut self) -> Option<&'a mut (Flow + 'a)> {
         self.iter.next().map(|flow| &mut **flow)
     }
 }
 
 pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, MutItems<'a, Au>>;
 
 /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
 /// confused with absolutely-positioned flows).
-#[deriving(Encodable)]
+#[deriving(Encodable, Copy)]
 pub struct AbsolutePositionInfo {
     /// The size of the containing block for relatively-positioned descendants.
     pub relative_containing_block_size: LogicalSize<Au>,
 
     /// The position of the absolute containing block relative to the nearest ancestor stacking
     /// context. If the absolute containing block establishes the stacking context for this flow,
     /// and this flow is not itself absolutely-positioned, then this is (0, 0).
     pub stacking_relative_position_of_absolute_containing_block: Point2D<Au>,
@@ -858,35 +859,35 @@ impl BaseFlow {
                force_nonfloated: ForceNonfloatedFlag)
                -> BaseFlow {
         let mut flags = FlowFlags::empty();
         match node {
             None => {}
             Some(node) => {
                 let node_style = node.style();
                 match node_style.get_box().position {
-                    position::absolute | position::fixed => {
+                    position::T::absolute | position::T::fixed => {
                         flags.insert(IS_ABSOLUTELY_POSITIONED)
                     }
                     _ => {}
                 }
 
                 if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
                     match node_style.get_box().float {
-                        float::none => {}
-                        float::left => flags.insert(FLOATS_LEFT),
-                        float::right => flags.insert(FLOATS_RIGHT),
+                        float::T::none => {}
+                        float::T::left => flags.insert(FLOATS_LEFT),
+                        float::T::right => flags.insert(FLOATS_RIGHT),
                     }
                 }
 
                 match node_style.get_box().clear {
-                    clear::none => {}
-                    clear::left => flags.insert(CLEARS_LEFT),
-                    clear::right => flags.insert(CLEARS_RIGHT),
-                    clear::both => {
+                    clear::T::none => {}
+                    clear::T::left => flags.insert(CLEARS_LEFT),
+                    clear::T::right => flags.insert(CLEARS_RIGHT),
+                    clear::T::both => {
                         flags.insert(CLEARS_LEFT);
                         flags.insert(CLEARS_RIGHT);
                     }
                 }
             }
         }
 
         // New flows start out as fully damaged.
@@ -957,17 +958,17 @@ impl BaseFlow {
 
             if bounds.union(&paint_bounds.bounding_rect()) != bounds {
                 error!("DisplayList item {} outside of Flow overflow ({})", item, paint_bounds);
             }
         }
     }
 }
 
-impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
+impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) {
     /// Returns true if this flow is a block flow.
     fn is_block_like(self) -> bool {
         match self.class() {
             FlowClass::Block => true,
             _ => false,
         }
     }
 
@@ -1059,17 +1060,17 @@ impl<'a> ImmutableFlowUtils for &'a Flow
                     Fragment::new_anonymous_from_specific_info(node,
                                                                SpecificFragmentInfo::TableRow);
                 box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>
             },
             FlowClass::TableRow => {
                 let fragment =
                     Fragment::new_anonymous_from_specific_info(node,
                                                                SpecificFragmentInfo::TableCell);
-                let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide;
+                let hide = node.style().get_inheritedtable().empty_cells == empty_cells::T::hide;
                 box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide) as
                     Box<Flow>
             },
             _ => {
                 panic!("no need to generate a missing child")
             }
         };
         FlowRef::new(flow)
@@ -1133,17 +1134,17 @@ impl<'a> ImmutableFlowUtils for &'a Flow
         println!("{}+ {}", indent, self.to_string());
 
         for kid in imm_child_iter(self) {
             kid.dump_with_level(level + 1)
         }
     }
 }
 
-impl<'a> MutableFlowUtils for &'a mut Flow + 'a {
+impl<'a> MutableFlowUtils for &'a mut (Flow + 'a) {
     /// Traverses the tree in preorder.
     fn traverse_preorder<T:PreorderFlowTraversal>(self, traversal: &T) {
         if traversal.should_process(self) {
             traversal.process(self);
         }
 
         for kid in child_iter(self) {
             kid.traverse_preorder(traversal);
--- a/servo/components/layout/flow_list.rs
+++ b/servo/components/layout/flow_list.rs
@@ -100,31 +100,31 @@ impl FlowList {
 
     /// O(1)
     #[inline]
     pub fn len(&self) -> uint {
         self.flows.len()
     }
 }
 
-impl<'a> Iterator<&'a Flow + 'a> for FlowListIterator<'a> {
+impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> {
     #[inline]
-    fn next(&mut self) -> Option<&'a Flow + 'a> {
+    fn next(&mut self) -> Option<&'a (Flow + 'a)> {
         self.it.next().map(|x| x.deref())
     }
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         self.it.size_hint()
     }
 }
 
-impl<'a> Iterator<&'a mut Flow + 'a> for MutFlowListIterator<'a> {
+impl<'a> Iterator<&'a mut (Flow + 'a)> for MutFlowListIterator<'a> {
     #[inline]
-    fn next(&mut self) -> Option<&'a mut Flow + 'a> {
+    fn next(&mut self) -> Option<&'a mut (Flow + 'a)> {
         self.it.next().map(|x| x.deref_mut())
     }
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         self.it.size_hint()
     }
 }
--- a/servo/components/layout/flow_ref.rs
+++ b/servo/components/layout/flow_ref.rs
@@ -29,27 +29,27 @@ impl FlowRef {
             };
             mem::forget(flow);
             result
         }
     }
 }
 
 impl<'a> Deref<Flow + 'a> for FlowRef {
-    fn deref(&self) -> &Flow + 'a {
+    fn deref(&self) -> &(Flow + 'a) {
         unsafe {
-            mem::transmute_copy::<raw::TraitObject, &Flow + 'a>(&self.object)
+            mem::transmute_copy::<raw::TraitObject, &(Flow + 'a)>(&self.object)
         }
     }
 }
 
 impl<'a> DerefMut<Flow + 'a> for FlowRef {
-    fn deref_mut<'a>(&mut self) -> &mut Flow + 'a {
+    fn deref_mut<'a>(&mut self) -> &mut (Flow + 'a) {
         unsafe {
-            mem::transmute_copy::<raw::TraitObject, &mut Flow + 'a>(&self.object)
+            mem::transmute_copy::<raw::TraitObject, &mut (Flow + 'a)>(&self.object)
         }
     }
 }
 
 impl Drop for FlowRef {
     fn drop(&mut self) {
         unsafe {
             if self.object.vtable.is_null() {
--- a/servo/components/layout/fragment.rs
+++ b/servo/components/layout/fragment.rs
@@ -40,17 +40,17 @@ use std::cmp::{max, min};
 use std::fmt;
 use std::str::FromStr;
 use string_cache::Atom;
 use style::{ComputedValues, TElement, TNode, cascade_anonymous};
 use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto};
 use style::computed_values::{LengthOrPercentageOrNone};
 use style::computed_values::{clear, overflow_wrap, position, text_align};
 use style::computed_values::{text_decoration, vertical_align, white_space};
-use sync::{Arc, Mutex};
+use std::sync::{Arc, Mutex};
 use url::Url;
 
 /// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position
 /// themselves. In general, fragments do not have a simple correspondence with CSS fragments in the
 /// specification:
 ///
 /// * Several fragments may correspond to the same CSS box or DOM node. For example, a CSS text box
 /// broken across two lines is represented by two fragments.
@@ -393,17 +393,17 @@ impl ScannedTextFragmentInfo {
             original_new_line_pos: None,
             content_size: content_size,
         }
     }
 }
 
 /// Describes how to split a fragment. This is used during line breaking as part of the return
 /// value of `find_split_info_for_inline_size()`.
-#[deriving(Show)]
+#[deriving(Show, Clone)]
 pub struct SplitInfo {
     // TODO(bjz): this should only need to be a single character index, but both values are
     // currently needed for splitting in the `inline::try_append_*` functions.
     pub range: Range<CharIndex>,
     pub inline_size: Au,
 }
 
 impl SplitInfo {
@@ -450,17 +450,17 @@ impl UnscannedTextFragmentInfo {
     pub fn from_text(text: String) -> UnscannedTextFragmentInfo {
         UnscannedTextFragmentInfo {
             text: box text,
         }
     }
 }
 
 /// A fragment that represents a table column.
-#[deriving(Clone)]
+#[deriving(Copy, Clone)]
 pub struct TableColumnFragmentInfo {
     /// the number of columns a <col> element should span
     pub span: int,
 }
 
 impl TableColumnFragmentInfo {
     /// Create the information specific to an table column fragment.
     pub fn new(node: &ThreadSafeLayoutNode) -> TableColumnFragmentInfo {
@@ -872,46 +872,46 @@ impl Fragment {
                 MaybeAuto::from_style(offsets.block_start, container_size.inline).specified_or_zero()
             } else {
                 -MaybeAuto::from_style(offsets.block_end, container_size.inline).specified_or_zero()
             };
             LogicalSize::new(style.writing_mode, offset_i, offset_b)
         }
 
         // Go over the ancestor fragments and add all relative offsets (if any).
-        let mut rel_pos = if self.style().get_box().position == position::relative {
+        let mut rel_pos = if self.style().get_box().position == position::T::relative {
             from_style(self.style(), containing_block_size)
         } else {
             LogicalSize::zero(self.style.writing_mode)
         };
 
         match self.inline_context {
             None => {}
             Some(ref inline_fragment_context) => {
                 for style in inline_fragment_context.styles.iter() {
-                    if style.get_box().position == position::relative {
+                    if style.get_box().position == position::T::relative {
                         rel_pos = rel_pos + from_style(&**style, containing_block_size);
                     }
                 }
             },
         }
         rel_pos
     }
 
     /// Always inline for SCCP.
     ///
     /// FIXME(pcwalton): Just replace with the clear type from the style module for speed?
     #[inline(always)]
     pub fn clear(&self) -> Option<ClearType> {
         let style = self.style();
         match style.get_box().clear {
-            clear::none => None,
-            clear::left => Some(ClearType::Left),
-            clear::right => Some(ClearType::Right),
-            clear::both => Some(ClearType::Both),
+            clear::T::none => None,
+            clear::T::left => Some(ClearType::Left),
+            clear::T::right => Some(ClearType::Right),
+            clear::T::both => Some(ClearType::Both),
         }
     }
 
     #[inline(always)]
     pub fn style<'a>(&'a self) -> &'a ComputedValues {
         &*self.style
     }
 
@@ -1147,17 +1147,17 @@ impl Fragment {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
             SpecificFragmentInfo::ScannedText(ref text_fragment_info) => text_fragment_info,
         };
 
         let mut flags = SplitOptions::empty();
         if starts_line {
             flags.insert(STARTS_LINE);
-            if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::break_word {
+            if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::T::break_word {
                 flags.insert(RETRY_AT_CHARACTER_BOUNDARIES)
             }
         }
 
         let natural_word_breaking_strategy =
             text_fragment_info.run.natural_word_slices_in_range(&text_fragment_info.range);
         self.calculate_split_position_using_breaking_strategy(natural_word_breaking_strategy,
                                                               max_inline_size,
@@ -1274,18 +1274,18 @@ impl Fragment {
             text_run: text_fragment_info.run.clone(),
         })
     }
 
     /// Returns true if this fragment is an unscanned text fragment that consists entirely of
     /// whitespace that should be stripped.
     pub fn is_ignorable_whitespace(&self) -> bool {
         match self.white_space() {
-            white_space::pre => return false,
-            white_space::normal | white_space::nowrap => {}
+            white_space::T::pre => return false,
+            white_space::T::normal | white_space::T::nowrap => {}
         }
         match self.specific {
             SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => {
                 is_whitespace(text_fragment_info.text.as_slice())
             }
             _ => false,
         }
     }
@@ -1611,22 +1611,22 @@ impl Fragment {
     }
 
     /// Returns true if this fragment establishes a new stacking context and false otherwise.
     pub fn establishes_stacking_context(&self) -> bool {
         if self.style().get_effects().opacity != 1.0 {
             return true
         }
         match self.style().get_box().position {
-            position::absolute | position::fixed => {
+            position::T::absolute | position::T::fixed => {
                 // FIXME(pcwalton): This should only establish a new stacking context when
                 // `z-index` is not `auto`. But this matches what we did before.
                 true
             }
-            position::relative | position::static_ => {
+            position::T::relative | position::T::static_ => {
                 // FIXME(pcwalton): `position: relative` establishes a new stacking context if
                 // `z-index` is not `auto`. But this matches what we did before.
                 false
             }
         }
     }
 
     /// Computes the overflow rect of this fragment relative to the start of the flow.
--- a/servo/components/layout/incremental.rs
+++ b/servo/components/layout/incremental.rs
@@ -7,16 +7,17 @@ use flow::{IS_ABSOLUTELY_POSITIONED};
 
 use std::fmt;
 use std::sync::Arc;
 use style::computed_values::float;
 use style::ComputedValues;
 
 bitflags! {
     #[doc = "Individual layout actions that may be necessary after restyling."]
+    #[deriving(Copy)]
     flags RestyleDamage: u8 {
         #[doc = "Repaint the node itself."]
         #[doc = "Currently unused; need to decide how this propagates."]
         const REPAINT = 0x01,
 
         #[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."]
         #[doc = "Propagates down the flow tree because the computation is"]
         #[doc = "bottom-up."]
@@ -82,17 +83,17 @@ impl RestyleDamage {
                 // TODO(pcwalton): Take floatedness into account.
                 self & (REPAINT | REFLOW)
             }
         }
     }
 }
 
 impl fmt::Show for RestyleDamage {
-    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         let mut first_elem = true;
 
         let to_iter =
             [ (REPAINT,         "Repaint")
             , (BUBBLE_ISIZES,    "BubbleISizes")
             , (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow")
             , (REFLOW,          "Reflow")
             , (RECONSTRUCT_FLOW, "ReconstructFlow")
@@ -176,17 +177,17 @@ pub fn compute_damage(old: &Option<Arc<C
     damage
 }
 
 pub trait LayoutDamageComputation {
     fn compute_layout_damage(self) -> SpecialRestyleDamage;
     fn reflow_entire_document(self);
 }
 
-impl<'a> LayoutDamageComputation for &'a mut Flow+'a {
+impl<'a> LayoutDamageComputation for &'a mut (Flow + 'a) {
     fn compute_layout_damage(self) -> SpecialRestyleDamage {
         let mut special_damage = SpecialRestyleDamage::empty();
         let is_absolutely_positioned = flow::base(self).flags.contains(IS_ABSOLUTELY_POSITIONED);
 
         {
             let self_base = flow::mut_base(self);
             for kid in self_base.children.iter_mut() {
                 let child_is_absolutely_positioned =
@@ -198,17 +199,17 @@ impl<'a> LayoutDamageComputation for &'a
                 special_damage.insert(kid.compute_layout_damage());
                 self_base.restyle_damage
                          .insert(flow::base(kid).restyle_damage.damage_for_parent(
                                  child_is_absolutely_positioned));
             }
         }
 
         let self_base = flow::base(self);
-        if self_base.flags.float_kind() != float::none &&
+        if self_base.flags.float_kind() != float::T::none &&
                 self_base.restyle_damage.intersects(REFLOW) {
             special_damage.insert(REFLOW_ENTIRE_DOCUMENT);
         }
 
         special_damage
     }
 
     fn reflow_entire_document(self) {
--- a/servo/components/layout/inline.rs
+++ b/servo/components/layout/inline.rs
@@ -29,17 +29,17 @@ use servo_util::geometry::{Au, ZERO_RECT
 use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
 use servo_util::range::{Range, RangeIndex};
 use std::cmp::max;
 use std::fmt;
 use std::mem;
 use std::u16;
 use style::computed_values::{text_align, vertical_align, white_space};
 use style::ComputedValues;
-use sync::Arc;
+use std::sync::Arc;
 
 // From gfxFontConstants.h in Firefox
 static FONT_SUBSCRIPT_OFFSET_RATIO: f64 = 0.20;
 static FONT_SUPERSCRIPT_OFFSET_RATIO: f64 = 0.34;
 
 /// `Line`s are represented as offsets into the child list, rather than
 /// as an object that "owns" fragments. Choosing a different set of line
 /// breaks requires a new list of offsets, and possibly some splitting and
@@ -60,17 +60,17 @@ static FONT_SUPERSCRIPT_OFFSET_RATIO: f6
 /// serve as the starting point, but the current design doesn't make it
 /// hard to try out that alternative.
 ///
 /// Line fragments also contain some metadata used during line breaking. The
 /// green zone is the area that the line can expand to before it collides
 /// with a float or a horizontal wall of the containing block. The block-start
 /// inline-start corner of the green zone is the same as that of the line, but
 /// the green zone can be taller and wider than the line itself.
-#[deriving(Encodable, Show)]
+#[deriving(Encodable, Show, Copy)]
 pub struct Line {
     /// A range of line indices that describe line breaks.
     ///
     /// For example, consider the following HTML and rendered element with
     /// linebreaks:
     ///
     /// ~~~html
     /// <span>I <span>like truffles, <img></span> yes I do.</span>
@@ -262,32 +262,32 @@ impl LineBreaker {
             // appropriate.
             let fragment = match self.next_unbroken_fragment(&mut old_fragment_iter) {
                 None => break,
                 Some(fragment) => fragment,
             };
 
             // Set up our reflow flags.
             let flags = match fragment.style().get_inheritedtext().white_space {
-                white_space::normal => InlineReflowFlags::empty(),
-                white_space::pre | white_space::nowrap => NO_WRAP_INLINE_REFLOW_FLAG,
+                white_space::T::normal => InlineReflowFlags::empty(),
+                white_space::T::pre | white_space::T::nowrap => NO_WRAP_INLINE_REFLOW_FLAG,
             };
 
             // Try to append the fragment, and commit the line (so we can try again with the next
             // line) if we couldn't.
             match fragment.style().get_inheritedtext().white_space {
-                white_space::normal | white_space::nowrap => {
+                white_space::T::normal | white_space::T::nowrap => {
                     if !self.append_fragment_to_line_if_possible(fragment,
                                                                  flow,
                                                                  layout_context,
                                                                  flags) {
                         self.flush_current_line()
                     }
                 }
-                white_space::pre => {
+                white_space::T::pre => {
                     // FIXME(pcwalton): Surely we can unify
                     // `append_fragment_to_line_if_possible` and
                     // `try_append_to_line_by_new_line` by adding another bit in the reflow
                     // flags.
                     if !self.try_append_to_line_by_new_line(fragment) {
                         self.flush_current_line()
                     }
                 }
@@ -597,18 +597,18 @@ impl LineBreaker {
                                                                     split.range,
                                                                     Vec::new(),
                                                                     fragment.border_box.size);
                         let size = LogicalSize::new(self.floats.writing_mode,
                                                     split.inline_size,
                                                     fragment.border_box.size.block);
                         fragment.transform(size, info)
                     };
-                    (split_result.inline_start.map(|x| split_fragment(x)),
-                     split_result.inline_end.map(|x| split_fragment(x)))
+                    (split_result.inline_start.as_ref().map(|x| split_fragment(x.clone())),
+                     split_result.inline_end.as_ref().map(|x| split_fragment(x.clone())))
                 }
             };
 
         // Push the first fragment onto the line we're working on and start off the next line with
         // the second fragment. If there's no second fragment, the next line will start off empty.
         match (inline_start_fragment, inline_end_fragment) {
             (Some(inline_start_fragment), Some(inline_end_fragment)) => {
                 self.push_fragment_to_line(inline_start_fragment);
@@ -764,63 +764,63 @@ impl InlineFlow {
                               parent_text_block_end: Au,
                               block_size_above_baseline: &mut Au,
                               depth_below_baseline: &mut Au,
                               largest_block_size_for_top_fragments: &mut Au,
                               largest_block_size_for_bottom_fragments: &mut Au,
                               layout_context: &LayoutContext)
                               -> (Au, bool) {
         match fragment.vertical_align() {
-            vertical_align::baseline => (-ascent, false),
-            vertical_align::middle => {
+            vertical_align::T::baseline => (-ascent, false),
+            vertical_align::T::middle => {
                 // TODO: x-height value should be used from font info.
                 // TODO: The code below passes our current reftests but doesn't work in all
                 // situations. Add vertical align reftests and fix this.
                 (-ascent, false)
             },
-            vertical_align::sub => {
+            vertical_align::T::sub => {
                 let sub_offset = (parent_text_block_start + parent_text_block_end)
                                     .scale_by(FONT_SUBSCRIPT_OFFSET_RATIO);
                 (sub_offset - ascent, false)
             },
-            vertical_align::super_ => {
+            vertical_align::T::super_ => {
                 let super_offset = (parent_text_block_start + parent_text_block_end)
                                     .scale_by(FONT_SUPERSCRIPT_OFFSET_RATIO);
                 (-super_offset - ascent, false)
             },
-            vertical_align::text_top => {
+            vertical_align::T::text_top => {
                 let fragment_block_size = *block_size_above_baseline + *depth_below_baseline;
                 let prev_depth_below_baseline = *depth_below_baseline;
                 *block_size_above_baseline = parent_text_block_start;
                 *depth_below_baseline = fragment_block_size - *block_size_above_baseline;
                 (*depth_below_baseline - prev_depth_below_baseline - ascent, false)
             },
-            vertical_align::text_bottom => {
+            vertical_align::T::text_bottom => {
                 let fragment_block_size = *block_size_above_baseline + *depth_below_baseline;
                 let prev_depth_below_baseline = *depth_below_baseline;
                 *depth_below_baseline = parent_text_block_end;
                 *block_size_above_baseline = fragment_block_size - *depth_below_baseline;
                 (*depth_below_baseline - prev_depth_below_baseline - ascent, false)
             },
-            vertical_align::top => {
+            vertical_align::T::top => {
                 *largest_block_size_for_top_fragments =
                     max(*largest_block_size_for_top_fragments,
                         *block_size_above_baseline + *depth_below_baseline);
                 let offset_top = *block_size_above_baseline - ascent;
                 (offset_top, true)
             },
-            vertical_align::bottom => {
+            vertical_align::T::bottom => {
                 *largest_block_size_for_bottom_fragments =
                     max(*largest_block_size_for_bottom_fragments,
                         *block_size_above_baseline + *depth_below_baseline);
                 let offset_bottom = -(*depth_below_baseline + ascent);
                 (offset_bottom, true)
             },
-            vertical_align::Length(length) => (-(length + ascent), false),
-            vertical_align::Percentage(p) => {
+            vertical_align::T::Length(length) => (-(length + ascent), false),
+            vertical_align::T::Percentage(p) => {
                 let line_height = fragment.calculate_line_height(layout_context);
                 let percent_offset = line_height.scale_by(p);
                 (-(percent_offset + ascent), false)
             }
         }
     }
 
     /// Sets fragment positions in the inline direction based on alignment for one line.
@@ -833,19 +833,19 @@ impl InlineFlow {
 
         // Set the fragment inline positions based on that alignment.
         let mut inline_start_position_for_fragment = line.bounds.start.i + indentation +
                 match line_align {
                 // So sorry, but justified text is more complicated than shuffling line
                 // coordinates.
                 //
                 // TODO(burg, issue #213): Implement `text-align: justify`.
-                text_align::left | text_align::justify => Au(0),
-                text_align::center => slack_inline_size.scale_by(0.5),
-                text_align::right => slack_inline_size,
+                text_align::T::left | text_align::T::justify => Au(0),
+                text_align::T::center => slack_inline_size.scale_by(0.5),
+                text_align::T::right => slack_inline_size,
             };
 
         for fragment_index in range(line.range.begin(), line.range.end()) {
             let fragment = fragments.get_mut(fragment_index.to_uint());
             let size = fragment.border_box.size;
             fragment.border_box = LogicalRect::new(fragment.style.writing_mode,
                                                    inline_start_position_for_fragment,
                                                    fragment.border_box.start.b,
@@ -861,21 +861,21 @@ impl InlineFlow {
     fn set_block_fragment_positions(fragments: &mut InlineFragments,
                                     line: &Line,
                                     line_distance_from_flow_block_start: Au,
                                     baseline_distance_from_block_start: Au,
                                     largest_depth_below_baseline: Au) {
         for fragment_index in range(line.range.begin(), line.range.end()) {
             let fragment = fragments.get_mut(fragment_index.to_uint());
             match fragment.vertical_align() {
-                vertical_align::top => {
+                vertical_align::T::top => {
                     fragment.border_box.start.b = fragment.border_box.start.b +
                         line_distance_from_flow_block_start
                 }
-                vertical_align::bottom => {
+                vertical_align::T::bottom => {
                     fragment.border_box.start.b = fragment.border_box.start.b +
                         line_distance_from_flow_block_start + baseline_distance_from_block_start +
                         largest_depth_below_baseline
                 }
                 _ => {
                     fragment.border_box.start.b = fragment.border_box.start.b +
                         line_distance_from_flow_block_start + baseline_distance_from_block_start
                 }
--- a/servo/components/layout/layout_debug.rs
+++ b/servo/components/layout/layout_debug.rs
@@ -9,17 +9,17 @@
 
 use flow_ref::FlowRef;
 use flow;
 use serialize::json;
 use std::cell::RefCell;
 use std::io::File;
 use std::sync::atomic::{AtomicUint, SeqCst, INIT_ATOMIC_UINT};
 
-local_data_key!(state_key: RefCell<State>)
+thread_local!(static state_key: RefCell<Option<State>> = RefCell::new(None))
 
 static mut DEBUG_ID_COUNTER: AtomicUint = INIT_ATOMIC_UINT;
 
 pub struct Scope;
 
 #[macro_export]
 macro_rules! layout_debug_scope(
     ($($arg:tt)*) => (
@@ -54,73 +54,74 @@ struct State {
     flow_root: FlowRef,
     scope_stack: Vec<Box<ScopeData>>,
 }
 
 /// A layout debugging scope. The entire state of the flow tree
 /// will be output at the beginning and end of this scope.
 impl Scope {
     pub fn new(name: String) -> Scope {
-        let maybe_refcell = state_key.get();
-        match maybe_refcell {
-            Some(refcell) => {
-                let mut state = refcell.borrow_mut();
-                let flow_trace = json::encode(&flow::base(state.flow_root.deref()));
-                let data = box ScopeData::new(name, flow_trace);
-                state.scope_stack.push(data);
+        state_key.with(|ref r| {
+            match &mut *r.borrow_mut() {
+                &Some(ref mut state) => {
+                    let flow_trace = json::encode(&flow::base(state.flow_root.deref()));
+                    let data = box ScopeData::new(name.clone(), flow_trace);
+                    state.scope_stack.push(data);
+                }
+                &None => {}
             }
-            None => {}
-        }
+        });
         Scope
     }
 }
 
 #[cfg(not(ndebug))]
 impl Drop for Scope {
     fn drop(&mut self) {
-        let maybe_refcell = state_key.get();
-        match maybe_refcell {
-            Some(refcell) => {
-                let mut state = refcell.borrow_mut();
-                let mut current_scope = state.scope_stack.pop().unwrap();
-                current_scope.post = json::encode(&flow::base(state.flow_root.deref()));
-                let previous_scope = state.scope_stack.last_mut().unwrap();
-                previous_scope.children.push(current_scope);
+        state_key.with(|ref r| {
+            match &mut *r.borrow_mut() {
+                &Some(ref mut state) => {
+                    let mut current_scope = state.scope_stack.pop().unwrap();
+                    current_scope.post = json::encode(&flow::base(state.flow_root.deref()));
+                    let previous_scope = state.scope_stack.last_mut().unwrap();
+                    previous_scope.children.push(current_scope);
+                }
+                &None => {}
             }
-            None => {}
-        }
+        });
     }
 }
 
 /// Generate a unique ID. This is used for items such as Fragment
 /// which are often reallocated but represent essentially the
 /// same data.
 pub fn generate_unique_debug_id() -> u16 {
     unsafe { DEBUG_ID_COUNTER.fetch_add(1, SeqCst) as u16 }
 }
 
 /// Begin a layout debug trace. If this has not been called,
 /// creating debug scopes has no effect.
 pub fn begin_trace(flow_root: FlowRef) {
-    assert!(state_key.get().is_none());
+    assert!(state_key.with(|ref r| r.borrow().is_none()));
 
-    let flow_trace = json::encode(&flow::base(flow_root.deref()));
-    let state = State {
-        scope_stack: vec![box ScopeData::new("root".into_string(), flow_trace)],
-        flow_root: flow_root,
-    };
-    state_key.replace(Some(RefCell::new(state)));
+    state_key.with(|ref r| {
+        let flow_trace = json::encode(&flow::base(flow_root.deref()));
+        let state = State {
+            scope_stack: vec![box ScopeData::new("root".into_string(), flow_trace)],
+            flow_root: flow_root.clone(),
+        };
+        *r.borrow_mut() = Some(state);
+    });
 }
 
 /// End the debug layout trace. This will write the layout
 /// trace to disk in the current directory. The output
 /// file can then be viewed with an external tool.
 pub fn end_trace() {
-    let task_state_cell = state_key.replace(None).unwrap();
-    let mut task_state = task_state_cell.borrow_mut();
+    let mut task_state = state_key.with(|ref r| r.borrow_mut().take().unwrap());
     assert!(task_state.scope_stack.len() == 1);
     let mut root_scope = task_state.scope_stack.pop().unwrap();
     root_scope.post = json::encode(&flow::base(task_state.flow_root.deref()));
 
     let result = json::encode(&root_scope);
     let path = Path::new("layout_trace.json");
     let mut file = File::create(&path).unwrap();
     file.write_str(result.as_slice()).unwrap();
--- a/servo/components/layout/layout_task.rs
+++ b/servo/components/layout/layout_task.rs
@@ -25,53 +25,53 @@ use geom::rect::Rect;
 use geom::size::Size2D;
 use geom::scale_factor::ScaleFactor;
 use gfx::color;
 use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, OpaqueNode};
 use gfx::display_list::{StackingContext};
 use gfx::font_cache_task::FontCacheTask;
 use gfx::paint_task::{PaintChan, PaintLayer};
 use gfx::paint_task::Msg as PaintMsg;
-use layout_traits::{mod, LayoutControlMsg, LayoutTaskFactory};
+use layout_traits::{LayoutControlMsg, LayoutTaskFactory};
 use log;
 use script::dom::bindings::js::JS;
 use script::dom::node::{LayoutDataRef, Node, NodeTypeId};
 use script::dom::element::ElementTypeId;
 use script::dom::htmlelement::HTMLElementTypeId;
 use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse};
-use script::layout_interface::{ContentBoxesQuery, ContentBoxQuery};
+use script::layout_interface::ReflowQueryType;
 use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC};
-use script::layout_interface::{MouseOverResponse, Msg, NoQuery};
+use script::layout_interface::{MouseOverResponse, Msg};
 use script::layout_interface::{Reflow, ReflowGoal, ScriptLayoutChan, TrustedNodeAddress};
-use script_traits::{ConstellationControlMsg, ReflowEvent, OpaqueScriptLayoutChannel};
+use script_traits::{ConstellationControlMsg, CompositorEvent, OpaqueScriptLayoutChannel};
 use script_traits::{ScriptControlChan, UntrustedNodeAddress};
-use servo_msg::compositor_msg::Scrollable;
+use servo_msg::compositor_msg::ScrollPolicy;
 use servo_msg::constellation_msg::Msg as ConstellationMsg;
 use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType};
 use servo_msg::constellation_msg::PipelineId;
 use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg};
 use servo_net::local_image_cache::{ImageResponder, LocalImageCache};
 use servo_net::resource_task::{ResourceTask, load_bytes_iter};
-use servo_util::cursor::DefaultCursor;
+use servo_util::cursor::Cursor;
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::LogicalPoint;
 use servo_util::opts;
 use servo_util::smallvec::{SmallVec, SmallVec1, VecLike};
 use servo_util::task::spawn_named_with_send_on_failure;
 use servo_util::task_state;
 use servo_util::time::{TimeProfilerCategory, ProfilerMetadata, TimeProfilerChan, TimerMetadataFrameType};
 use servo_util::time::{TimerMetadataReflowType, profile};
 use servo_util::workqueue::WorkQueue;
 use std::cell::Cell;
 use std::comm::{channel, Sender, Receiver, Select};
 use std::mem;
 use std::ptr;
 use style::{StylesheetOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
 use style::{MediaType, Device};
-use sync::{Arc, Mutex, MutexGuard};
+use std::sync::{Arc, Mutex, MutexGuard};
 use url::Url;
 
 /// Mutable data belonging to the LayoutTask.
 ///
 /// This needs to be protected by a mutex so we can do fast RPCs.
 pub struct LayoutTaskData {
     /// The local image cache.
     pub local_image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>,
@@ -156,17 +156,18 @@ impl ImageResponder<UntrustedNodeAddress
         let id = self.id.clone();
         let script_chan = self.script_chan.clone();
         let f: proc(ImageResponseMsg, UntrustedNodeAddress):Send =
             proc(_, node_address) {
                 let ScriptControlChan(chan) = script_chan;
                 debug!("Dirtying {:x}", node_address as uint);
                 let mut nodes = SmallVec1::new();
                 nodes.vec_push(node_address);
-                drop(chan.send_opt(ConstellationControlMsg::SendEvent(id.clone(), ReflowEvent(nodes))))
+                drop(chan.send_opt(ConstellationControlMsg::SendEvent(
+                    id.clone(), CompositorEvent::ReflowEvent(nodes))))
             };
         f
     }
 }
 
 impl LayoutTaskFactory for LayoutTask {
     /// Spawns a new layout task.
     fn create(_phantom: Option<&mut LayoutTask>,
@@ -341,17 +342,17 @@ impl LayoutTask {
             } else {
                 panic!("invalid select result");
             }
         };
 
         match port_to_read {
             PortToRead::Pipeline => {
                 match self.pipeline_port.recv() {
-                    layout_traits::ExitNowMsg(exit_type) => {
+                    LayoutControlMsg::ExitNowMsg(exit_type) => {
                         self.handle_script_request(Msg::ExitNow(exit_type), possibly_locked_rw_data)
                     }
                 }
             },
             PortToRead::Script => {
                 let msg = self.port.recv();
                 self.handle_script_request(msg, possibly_locked_rw_data)
             }
@@ -685,17 +686,17 @@ impl LayoutTask {
                 let root_flow = flow::base(&**layout_root);
                 root_flow.position.size.to_physical(root_flow.writing_mode)
             };
             let mut display_list = box DisplayList::new();
             flow::mut_base(layout_root.deref_mut()).display_list_building_result
                                                    .add_to(&mut *display_list);
             let paint_layer = Arc::new(PaintLayer::new(layout_root.layer_id(0),
                                                        color,
-                                                       Scrollable));
+                                                       ScrollPolicy::Scrollable));
             let origin = Rect(Point2D(Au(0), Au(0)), root_size);
             let stacking_context = Arc::new(StackingContext::new(display_list,
                                                                  &origin,
                                                                  &origin,
                                                                  0,
                                                                  1.0,
                                                                  Some(paint_layer)));
 
@@ -841,23 +842,23 @@ impl LayoutTask {
                                                    &mut layout_root,
                                                    &mut shared_layout_context,
                                                    &mut rw_data);
             }
             ReflowGoal::ForScriptQuery => {}
         }
 
         match data.query_type {
-            ContentBoxQuery(node) => {
+            ReflowQueryType::ContentBoxQuery(node) => {
                 self.process_content_box_request(node, &mut layout_root, &mut rw_data)
             }
-            ContentBoxesQuery(node) => {
+            ReflowQueryType::ContentBoxesQuery(node) => {
                 self.process_content_boxes_request(node, &mut layout_root, &mut rw_data)
             }
-            NoQuery => {}
+            ReflowQueryType::NoQuery => {}
         }
 
         self.first_reflow.set(false);
 
         if opts::get().trace_layout {
             layout_debug::end_trace();
         }
 
@@ -994,17 +995,17 @@ impl LayoutRPC for LayoutRPCImpl {
                     stacking_context.hit_test(point, &mut mouse_over_list, false);
                 }
             }
 
             // Compute the new cursor.
             let cursor = if !mouse_over_list.is_empty() {
                 mouse_over_list[0].cursor
             } else {
-                DefaultCursor
+                Cursor::DefaultCursor
             };
             let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan;
             constellation_chan.send(ConstellationMsg::SetCursor(cursor));
         }
 
         if mouse_over_list.is_empty() {
             Err(())
         } else {
--- a/servo/components/layout/lib.rs
+++ b/servo/components/layout/lib.rs
@@ -28,17 +28,16 @@ extern crate "util" as servo_util;
 
 #[phase(plugin)]
 extern crate string_cache_macros;
 extern crate string_cache;
 
 extern crate collections;
 extern crate encoding;
 extern crate libc;
-extern crate sync;
 extern crate url;
 
 // Listed first because of macro definitions
 pub mod layout_debug;
 
 pub mod block;
 pub mod construct;
 pub mod context;
--- a/servo/components/layout/list_item.rs
+++ b/servo/components/layout/list_item.rs
@@ -16,17 +16,17 @@ use fragment::{Fragment, FragmentBorderB
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use gfx::display_list::DisplayList;
 use servo_util::geometry::Au;
 use servo_util::opts;
 use style::ComputedValues;
 use style::computed_values::list_style_type;
-use sync::Arc;
+use std::sync::Arc;
 
 /// A block with the CSS `display` property equal to `list-item`.
 #[deriving(Show)]
 pub struct ListItemFlow {
     /// Data common to all block flows.
     pub block_flow: BlockFlow,
     /// The marker, if outside. (Markers that are inside are instead just fragments on the interior
     /// `InlineFlow`.)
@@ -126,17 +126,17 @@ impl Flow for ListItemFlow {
 /// Returns the static text to be used for the given value of the `list-style-type` property.
 ///
 /// TODO(pcwalton): Return either a string or a counter descriptor, once we support counters.
 pub fn static_text_for_list_style_type(list_style_type: list_style_type::T)
                                        -> Option<&'static str> {
     // Just to keep things simple, use a nonbreaking space (Unicode 0xa0) to provide the marker
     // separation.
     match list_style_type {
-        list_style_type::none => None,
-        list_style_type::disc => Some("•\u00a0"),
-        list_style_type::circle => Some("◦\u00a0"),
-        list_style_type::square => Some("▪\u00a0"),
-        list_style_type::disclosure_open => Some("▾\u00a0"),
-        list_style_type::disclosure_closed => Some("‣\u00a0"),
+        list_style_type::T::none => None,
+        list_style_type::T::disc => Some("•\u{a0}"),
+        list_style_type::T::circle => Some("◦\u{a0}"),
+        list_style_type::T::square => Some("▪\u{a0}"),
+        list_style_type::T::disclosure_open => Some("▾\u{a0}"),
+        list_style_type::T::disclosure_closed => Some("‣\u{a0}"),
     }
 }
 
--- a/servo/components/layout/model.rs
+++ b/servo/components/layout/model.rs
@@ -13,16 +13,17 @@ use geom::SideOffsets2D;
 use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentage};
 use style::ComputedValues;
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::LogicalMargin;
 use std::cmp::{max, min};
 use std::fmt;
 
 /// A collapsible margin. See CSS 2.1 § 8.3.1.
+#[deriving(Copy)]
 pub struct AdjoiningMargins {
     /// The value of the greatest positive margin.
     pub most_positive: Au,
 
     /// The actual value (not the absolute value) of the negative margin with the largest absolute
     /// value. Since this is not the absolute value, this is always zero or negative.
     pub most_negative: Au,
 }
@@ -55,16 +56,17 @@ impl AdjoiningMargins {
     }
 
     pub fn collapse(&self) -> Au {
         self.most_positive + self.most_negative
     }
 }
 
 /// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1.
+#[deriving(Copy)]
 pub enum CollapsibleMargins {
     /// Margins may not collapse with this flow.
     None(Au, Au),
 
     /// Both the block-start and block-end margins (specified here in that order) may collapse, but the
     /// margins do not collapse through this flow.
     Collapse(AdjoiningMargins, AdjoiningMargins),
 
@@ -232,16 +234,17 @@ impl MarginCollapseInfo {
             (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::CollapseThrough(block_end)) => {
                 self.margin_in.union(block_end);
                 Au(0)
             }
         }
     }
 }
 
+#[deriving(Copy)]
 pub enum MarginCollapseState {
     AccumulatingCollapsibleTopMargin,
     AccumulatingMarginIn,
 }
 
 /// Intrinsic inline-sizes, which consist of minimum and preferred.
 #[deriving(Encodable)]
 pub struct IntrinsicISizes {
@@ -317,17 +320,17 @@ impl IntrinsicISizesContribution {
         self.content_intrinsic_sizes.minimum_inline_size =
             max(self.content_intrinsic_sizes.minimum_inline_size, sizes.minimum_inline_size);
         self.content_intrinsic_sizes.preferred_inline_size =
             max(self.content_intrinsic_sizes.preferred_inline_size, sizes.preferred_inline_size)
     }
 }
 
 /// Useful helper data type when computing values for blocks and positioned elements.
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 pub enum MaybeAuto {
     Auto,
     Specified(Au),
 }
 
 impl MaybeAuto {
     #[inline]
     pub fn from_style(length: computed::LengthOrPercentageOrAuto, containing_length: Au)
--- a/servo/components/layout/table.rs
+++ b/servo/components/layout/table.rs
@@ -22,17 +22,17 @@ use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::LogicalRect;
 use std::cmp::max;
 use std::fmt;
 use style::{ComputedValues, CSSFloat};
 use style::computed_values::{LengthOrPercentageOrAuto, table_layout};
-use sync::Arc;
+use std::sync::Arc;
 
 /// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
 /// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
 /// not table fragment per CSS 2.1 § 10.5.
 #[deriving(Encodable)]
 pub struct TableFlow {
     pub block_flow: BlockFlow,
 
@@ -49,17 +49,17 @@ pub struct TableFlow {
 }
 
 impl TableFlow {
     pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
                                   fragment: Fragment)
                                   -> TableFlow {
         let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
-                              table_layout::fixed {
+                              table_layout::T::fixed {
             TableLayout::Fixed
         } else {
             TableLayout::Auto
         };
         TableFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: Vec::new(),
             column_computed_inline_sizes: Vec::new(),
@@ -67,17 +67,17 @@ impl TableFlow {
         }
     }
 
     pub fn from_node(constructor: &mut FlowConstructor,
                      node: &ThreadSafeLayoutNode)
                      -> TableFlow {
         let mut block_flow = BlockFlow::from_node(constructor, node);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
-                              table_layout::fixed {
+                              table_layout::T::fixed {
             TableLayout::Fixed
         } else {
             TableLayout::Auto
         };
         TableFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: Vec::new(),
             column_computed_inline_sizes: Vec::new(),
@@ -86,17 +86,17 @@ impl TableFlow {
     }
 
     pub fn float_from_node(constructor: &mut FlowConstructor,
                            node: &ThreadSafeLayoutNode,
                            float_kind: FloatKind)
                            -> TableFlow {
         let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
-                              table_layout::fixed {
+                              table_layout::T::fixed {
             TableLayout::Fixed
         } else {
             TableLayout::Auto
         };
         TableFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: Vec::new(),
             column_computed_inline_sizes: Vec::new(),
@@ -436,17 +436,17 @@ impl ISizeAndMarginsComputer for Interna
 /// specific width constraint. For instance, one cell might say that it wants to be 100 pixels wide
 /// in the inline direction and another cell might say that it wants to take up 20% of the inline-
 /// size of the table. Now because we bubble up these constraints during the bubble-inline-sizes
 /// phase of layout, we don't know yet how wide the table is ultimately going to be in the inline
 /// direction. As we need to pick the maximum width of all cells for a column (in this case, the
 /// maximum of 100 pixels and 20% of the table), the preceding constraint means that we must
 /// potentially store both a specified width *and* a specified percentage, so that the inline-size
 /// assignment phase of layout will know which one to pick.
-#[deriving(Clone, Encodable, Show)]
+#[deriving(Clone, Encodable, Show, Copy)]
 pub struct ColumnIntrinsicInlineSize {
     /// The preferred intrinsic inline size.
     pub preferred: Au,
     /// The largest specified size of this column as a length.
     pub minimum_length: Au,
     /// The largest specified size of this column as a percentage (`width` property).
     pub percentage: CSSFloat,
     /// Whether the column inline size is *constrained* per INTRINSIC § 4.1.
@@ -480,13 +480,13 @@ impl ColumnIntrinsicInlineSize {
         }
     }
 }
 
 /// The actual inline size for each column.
 ///
 /// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too
 /// eventually.
-#[deriving(Encodable)]
+#[deriving(Encodable, Copy)]
 pub struct ColumnComputedInlineSize {
     /// The computed size of this inline column.
     pub size: Au,
 }
--- a/servo/components/layout/table_caption.rs
+++ b/servo/components/layout/table_caption.rs
@@ -12,17 +12,17 @@ use context::LayoutContext;
 use flow::{FlowClass, Flow};
 use fragment::FragmentBorderBoxIterator;
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::fmt;
 use style::ComputedValues;
-use sync::Arc;
+use std::sync::Arc;
 
 /// A table formatting context.
 pub struct TableCaptionFlow {
     pub block_flow: BlockFlow,
 }
 
 impl TableCaptionFlow {
     pub fn from_node(constructor: &mut FlowConstructor,
--- a/servo/components/layout/table_cell.rs
+++ b/servo/components/layout/table_cell.rs
@@ -14,17 +14,17 @@ use model::{MaybeAuto};
 use layout_debug;
 use table::InternalTable;
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::fmt;
 use style::{UnsignedIntegerAttribute, ComputedValues};
-use sync::Arc;
+use std::sync::Arc;
 
 /// A table formatting context.
 #[deriving(Encodable)]
 pub struct TableCellFlow {
     /// Data common to all block flows.
     pub block_flow: BlockFlow,
     /// The column span of this cell.
     pub column_span: u32,
--- a/servo/components/layout/table_colgroup.rs
+++ b/servo/components/layout/table_colgroup.rs
@@ -14,17 +14,17 @@ use layout_debug;
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::{Au, ZERO_RECT};
 use std::cmp::max;
 use std::fmt;
 use style::computed_values::LengthOrPercentageOrAuto;
 use style::ComputedValues;
-use sync::Arc;
+use std::sync::Arc;
 
 /// A table formatting context.
 pub struct TableColGroupFlow {
     /// Data common to all flows.
     pub base: BaseFlow,
 
     /// The associated fragment.
     pub fragment: Option<Fragment>,
--- a/servo/components/layout/table_row.rs
+++ b/servo/components/layout/table_row.rs
@@ -19,32 +19,32 @@ use model::MaybeAuto;
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::cmp::max;
 use std::fmt;
 use style::ComputedValues;
 use style::computed_values::LengthOrPercentageOrAuto;
-use sync::Arc;
+use std::sync::Arc;
 
 /// A single row of a table.
 #[deriving(Encodable)]
 pub struct TableRowFlow {
     pub block_flow: BlockFlow,
 
     /// Information about the intrinsic inline-sizes of each cell.
     pub cell_intrinsic_inline_sizes: Vec<CellIntrinsicInlineSize>,
 
     /// Information about the computed inline-sizes of each column.
     pub column_computed_inline_sizes: Vec<ColumnComputedInlineSize>,
 }
 
 /// Information about the column inline size and span for each cell.
-#[deriving(Encodable)]
+#[deriving(Encodable, Copy)]
 pub struct CellIntrinsicInlineSize {
     /// Inline sizes that this cell contributes to the column.
     pub column_size: ColumnIntrinsicInlineSize,
     /// The column span of this cell.
     pub column_span: u32,
 }
 
 impl TableRowFlow {
--- a/servo/components/layout/table_rowgroup.rs
+++ b/servo/components/layout/table_rowgroup.rs
@@ -14,17 +14,17 @@ use fragment::{Fragment, FragmentBorderB
 use layout_debug;
 use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::fmt;
 use style::ComputedValues;
-use sync::Arc;
+use std::sync::Arc;
 
 /// A table formatting context.
 #[deriving(Encodable)]
 pub struct TableRowGroupFlow {
     /// Fields common to all block flows.
     pub block_flow: BlockFlow,
 
     /// Information about the intrinsic inline-sizes of each column.
--- a/servo/components/layout/table_wrapper.rs
+++ b/servo/components/layout/table_wrapper.rs
@@ -24,19 +24,19 @@ use table::{ColumnComputedInlineSize, Co
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::cmp::{max, min};
 use std::fmt;
 use style::{ComputedValues, CSSFloat};
 use style::computed_values::table_layout;
-use sync::Arc;
+use std::sync::Arc;
 
-#[deriving(Encodable, Show)]
+#[deriving(Copy, Encodable, Show)]
 pub enum TableLayout {
     Fixed,
     Auto
 }
 
 /// A table wrapper flow based on a block formatting context.
 #[deriving(Encodable)]
 pub struct TableWrapperFlow {
@@ -50,34 +50,34 @@ pub struct TableWrapperFlow {
 }
 
 impl TableWrapperFlow {
     pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
                                   fragment: Fragment)
                                   -> TableWrapperFlow {
         let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
-                              table_layout::fixed {
+                              table_layout::T::fixed {
             TableLayout::Fixed
         } else {
             TableLayout::Auto
         };
         TableWrapperFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: vec!(),
             table_layout: table_layout
         }
     }
 
     pub fn from_node(constructor: &mut FlowConstructor,
                      node: &ThreadSafeLayoutNode)
                      -> TableWrapperFlow {
         let mut block_flow = BlockFlow::from_node(constructor, node);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
-                              table_layout::fixed {
+                              table_layout::T::fixed {
             TableLayout::Fixed
         } else {
             TableLayout::Auto
         };
         TableWrapperFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: vec!(),
             table_layout: table_layout
@@ -85,17 +85,17 @@ impl TableWrapperFlow {
     }
 
     pub fn float_from_node_and_fragment(node: &ThreadSafeLayoutNode,
                                         fragment: Fragment,
                                         float_kind: FloatKind)
                                         -> TableWrapperFlow {
         let mut block_flow = BlockFlow::float_from_node_and_fragment(node, fragment, float_kind);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
-                              table_layout::fixed {
+                              table_layout::T::fixed {
             TableLayout::Fixed
         } else {
             TableLayout::Auto
         };
         TableWrapperFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: vec!(),
             table_layout: table_layout
@@ -482,17 +482,17 @@ impl Add<AutoLayoutCandidateGuess,AutoLa
             minimum_specified_guess: self.minimum_specified_guess + other.minimum_specified_guess,
             preferred_guess: self.preferred_guess + other.preferred_guess,
         }
     }
 }
 
 /// The `CSSFloat` member specifies the weight of the smaller of the two guesses, on a scale from
 /// 0.0 to 1.0.
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 enum SelectedAutoLayoutCandidateGuess {
     UseMinimumGuess,
     InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(CSSFloat),
     InterpolateBetweenMinimumPercentageGuessAndMinimumSpecifiedGuess(CSSFloat),
     InterpolateBetweenMinimumSpecifiedGuessAndPreferredGuess(CSSFloat),
     UsePreferredGuessAndDistributeExcessInlineSize,
 }
 
--- a/servo/components/layout/text.rs
+++ b/servo/components/layout/text.rs
@@ -9,28 +9,28 @@
 use fragment::{Fragment, SpecificFragmentInfo, ScannedTextFragmentInfo};
 use inline::InlineFragments;
 
 use gfx::font::{FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG, RunMetrics, ShapingFlags};
 use gfx::font::{ShapingOptions};
 use gfx::font_context::FontContext;
 use gfx::text::glyph::CharIndex;
 use gfx::text::text_run::TextRun;
-use gfx::text::util::{mod, CompressWhitespaceNewline, CompressNone};
+use gfx::text::util::{mod, CompressionMode};
 use servo_util::dlist;
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::{LogicalSize, WritingMode};
 use servo_util::range::Range;
 use servo_util::smallvec::{SmallVec, SmallVec1};
 use std::collections::DList;
 use std::mem;
 use style::ComputedValues;
 use style::computed_values::{line_height, text_orientation, text_transform, white_space};
 use style::style_structs::Font as FontStyle;
-use sync::Arc;
+use std::sync::Arc;
 
 /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s.
 pub struct TextRunScanner {
     pub clump: DList<Fragment>,
 }
 
 impl TextRunScanner {
     pub fn new() -> TextRunScanner {
@@ -109,18 +109,18 @@ impl TextRunScanner {
             let letter_spacing;
             let word_spacing;
             {
                 let in_fragment = self.clump.front().unwrap();
                 let font_style = in_fragment.style().get_font_arc();
                 let inherited_text_style = in_fragment.style().get_inheritedtext();
                 fontgroup = font_context.get_layout_font_group_for_style(font_style);
                 compression = match in_fragment.white_space() {
-                    white_space::normal | white_space::nowrap => CompressWhitespaceNewline,
-                    white_space::pre => CompressNone,
+                    white_space::T::normal | white_space::T::nowrap => CompressionMode::CompressWhitespaceNewline,
+                    white_space::T::pre => CompressionMode::CompressNone,
                 };
                 text_transform = inherited_text_style.text_transform;
                 letter_spacing = inherited_text_style.letter_spacing;
                 word_spacing = inherited_text_style.word_spacing.unwrap_or(Au(0));
             }
 
             // First, transform/compress text of all the nodes.
             let mut run_text = String::new();
@@ -208,32 +208,32 @@ impl TextRunScanner {
     /// Accounts for `text-transform`.
     ///
     /// FIXME(#4311, pcwalton): Case mapping can change length of the string; case mapping should
     /// be language-specific; `full-width`; use graphemes instead of characters.
     fn apply_style_transform_if_necessary(&mut self,
                                           string: &mut String,
                                           text_transform: text_transform::T) {
         match text_transform {
-            text_transform::none => {}
-            text_transform::uppercase => {
+            text_transform::T::none => {}
+            text_transform::T::uppercase => {
                 let length = string.len();
                 let original = mem::replace(string, String::with_capacity(length));
                 for character in original.chars() {
                     string.push(character.to_uppercase())
                 }
             }
-            text_transform::lowercase => {
+            text_transform::T::lowercase => {
                 let length = string.len();
                 let original = mem::replace(string, String::with_capacity(length));
                 for character in original.chars() {
                     string.push(character.to_lowercase())
                 }
             }
-            text_transform::capitalize => {
+            text_transform::T::capitalize => {
                 let length = string.len();
                 let original = mem::replace(string, String::with_capacity(length));
                 let mut capitalize_next_letter = true;
                 for character in original.chars() {
                     // FIXME(#4311, pcwalton): Should be the CSS/Unicode notion of a *typographic
                     // letter unit*, not an *alphabetic* character:
                     //
                     //    http://dev.w3.org/csswg/css-text/#typographic-letter-unit
@@ -261,19 +261,19 @@ struct NewLinePositions(Vec<CharIndex>);
 fn bounding_box_for_run_metrics(metrics: &RunMetrics, writing_mode: WritingMode)
                                 -> LogicalSize<Au> {
 
     // This does nothing, but it will fail to build
     // when more values are added to the `text-orientation` CSS property.
     // This will be a reminder to update the code below.
     let dummy: Option<text_orientation::T> = None;
     match dummy {
-        Some(text_orientation::sideways_right) |
-        Some(text_orientation::sideways_left) |
-        Some(text_orientation::sideways) |
+        Some(text_orientation::T::sideways_right) |
+        Some(text_orientation::T::sideways_left) |
+        Some(text_orientation::T::sideways) |
         None => {}
     }
 
     // In vertical sideways or horizontal upright text,
     // the "width" of text metrics is always inline
     // This will need to be updated when other text orientations are supported.
     LogicalSize::new(
         writing_mode,
@@ -291,13 +291,13 @@ pub fn font_metrics_for_style(font_conte
     let fontgroup = font_context.get_layout_font_group_for_style(font_style);
     fontgroup.fonts.get(0).borrow().metrics.clone()
 }
 
 /// Returns the line block-size needed by the given computed style and font size.
 pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> Au {
     let font_size = style.get_font().font_size;
     match style.get_inheritedbox().line_height {
-        line_height::Normal => metrics.line_gap,
-        line_height::Number(l) => font_size.scale_by(l),
-        line_height::Length(l) => l
+        line_height::T::Normal => metrics.line_gap,
+        line_height::T::Number(l) => font_size.scale_by(l),
+        line_height::T::Length(l) => l
     }
 }
--- a/servo/components/layout/traversal.rs
+++ b/servo/components/layout/traversal.rs
@@ -16,16 +16,19 @@ use wrapper::{layout_node_to_unsafe_layo
 use wrapper::{PostorderNodeMutTraversal, ThreadSafeLayoutNode, UnsafeLayoutNode};
 use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
 
 use servo_util::bloom::BloomFilter;
 use servo_util::opts;
 use servo_util::tid::tid;
 use style::TNode;
 
+use std::cell::RefCell;
+use std::mem;
+
 /// Every time we do another layout, the old bloom filters are invalid. This is
 /// detected by ticking a generation number every layout.
 type Generation = uint;
 
 /// A pair of the bloom filter used for css selector matching, and the node to
 /// which it applies. This is used to efficiently do `Descendant` selector
 /// matches. Thanks to the bloom filter, we can avoid walking up the tree
 /// looking for ancestors that aren't there in the majority of cases.
@@ -40,61 +43,66 @@ type Generation = uint;
 /// rejected.
 ///
 /// When done styling a node, all selectors previously inserted into the filter
 /// are removed.
 ///
 /// Since a work-stealing queue is used for styling, sometimes, the bloom filter
 /// will no longer be the for the parent of the node we're currently on. When
 /// this happens, the task local bloom filter will be thrown away and rebuilt.
-local_data_key!(style_bloom: (Box<BloomFilter>, UnsafeLayoutNode, Generation))
+thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None))
 
 /// Returns the task local bloom filter.
 ///
 /// If one does not exist, a new one will be made for you. If it is out of date,
 /// it will be thrown out and a new one will be made for you.
 fn take_task_local_bloom_filter(parent_node: Option<LayoutNode>, layout_context: &LayoutContext)
                                 -> Box<BloomFilter> {
-    match (parent_node, style_bloom.replace(None)) {
-        // Root node. Needs new bloom filter.
-        (None,     _  ) => {
-            debug!("[{}] No parent, but new bloom filter!", tid());
-            box BloomFilter::new()
-        }
-        // No bloom filter for this thread yet.
-        (Some(parent), None) => {
-            let mut bloom_filter = box BloomFilter::new();
-            insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context);
-            bloom_filter
-        }
-        // Found cached bloom filter.
-        (Some(parent), Some((mut bloom_filter, old_node, old_generation))) => {
-            // Hey, the cached parent is our parent! We can reuse the bloom filter.
-            if old_node == layout_node_to_unsafe_layout_node(&parent) &&
-                old_generation == layout_context.shared.generation {
-                debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0());
-                bloom_filter
-            } else {
-                // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing
-                // allocation to avoid malloc churn.
-                *bloom_filter = BloomFilter::new();
+    STYLE_BLOOM.with(|style_bloom| {
+        match (parent_node, style_bloom.borrow_mut().take()) {
+            // Root node. Needs new bloom filter.
+            (None,     _  ) => {
+                debug!("[{}] No parent, but new bloom filter!", tid());
+                box BloomFilter::new()
+            }
+            // No bloom filter for this thread yet.
+            (Some(parent), None) => {
+                let mut bloom_filter = box BloomFilter::new();
                 insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context);
                 bloom_filter
             }
-        },
-    }
+            // Found cached bloom filter.
+            (Some(parent), Some((mut bloom_filter, old_node, old_generation))) => {
+                // Hey, the cached parent is our parent! We can reuse the bloom filter.
+                if old_node == layout_node_to_unsafe_layout_node(&parent) &&
+                    old_generation == layout_context.shared.generation {
+                    debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0());
+                    bloom_filter.clone()
+                } else {
+                    // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing
+                    // allocation to avoid malloc churn.
+                    *bloom_filter = BloomFilter::new();
+                    insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context);
+                    bloom_filter
+                }
+            },
+        }
+    })
 }
 
 fn put_task_local_bloom_filter(bf: Box<BloomFilter>,
                                unsafe_node: &UnsafeLayoutNode,
                                layout_context: &LayoutContext) {
-    match style_bloom.replace(Some((bf, *unsafe_node, layout_context.shared.generation))) {
-        None => {},
-        Some(_) => panic!("Putting into a never-taken task-local bloom filter"),
-    }
+    let bf: *mut BloomFilter = unsafe { mem::transmute(bf) };
+    STYLE_BLOOM.with(|style_bloom| {
+        assert!(style_bloom.borrow().is_none(),
+                "Putting into a never-taken task-local bloom filter");
+        let bf: Box<BloomFilter> = unsafe { mem::transmute(bf) };
+        *style_bloom.borrow_mut() = Some((bf, *unsafe_node, layout_context.shared.generation));
+    })
 }
 
 /// "Ancestors" in this context is inclusive of ourselves.
 fn insert_ancestors_into_bloom_filter(bf: &mut Box<BloomFilter>,
                                       mut n: LayoutNode,
                                       layout_context: &LayoutContext) {
     debug!("[{}] Inserting ancestors.", tid());
     let mut ancestors = 0u;
@@ -107,16 +115,17 @@ fn insert_ancestors_into_bloom_filter(bf
             Some(p) => p,
         };
     }
     debug!("[{}] Inserted {} ancestors.", tid(), ancestors);
 }
 
 /// The recalc-style-for-node traversal, which styles each node and must run before
 /// layout computation. This computes the styles applied to each node.
+#[deriving(Copy)]
 pub struct RecalcStyleForNode<'a> {
     pub layout_context: &'a LayoutContext<'a>,
 }
 
 impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
     #[inline]
     fn process(&self, node: LayoutNode) {
         // Initialize layout data.
@@ -195,16 +204,17 @@ impl<'a> PreorderDomTraversal for Recalc
         node.insert_into_bloom_filter(&mut *bf);
 
         // NB: flow construction updates the bloom filter on the way up.
         put_task_local_bloom_filter(bf, &unsafe_layout_node, self.layout_context);
     }
 }
 
 /// The flow construction traversal, which builds flows for styled nodes.
+#[deriving(Copy)]
 pub struct ConstructFlows<'a> {
     pub layout_context: &'a LayoutContext<'a>,
 }
 
 impl<'a> PostorderDomTraversal for ConstructFlows<'a> {
     #[inline]
     fn process(&self, node: LayoutNode) {
         // Construct flows for this node.
@@ -233,19 +243,20 @@ impl<'a> PostorderDomTraversal for Const
             node.set_dirty(false);
             node.set_dirty_siblings(false);
             node.set_dirty_descendants(false);
         }
 
         let unsafe_layout_node = layout_node_to_unsafe_layout_node(&node);
 
         let (mut bf, old_node, old_generation) =
-            style_bloom
-            .replace(None)
-            .expect("The bloom filter should have been set by style recalc.");
+            STYLE_BLOOM.with(|style_bloom| {
+                mem::replace(&mut *style_bloom.borrow_mut(), None)
+                .expect("The bloom filter should have been set by style recalc.")
+            });
 
         assert_eq!(old_node, unsafe_layout_node);
         assert_eq!(old_generation, self.layout_context.shared.generation);
 
         match node.layout_parent_node(self.layout_context.shared) {
             None => {
                 debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.val0());
                 // If this is the reflow root, eat the task-local bloom filter.
@@ -292,16 +303,17 @@ impl<'a> PostorderFlowTraversal for Bubb
 
     #[inline]
     fn should_process(&self, flow: &mut Flow) -> bool {
         flow::base(flow).restyle_damage.contains(BUBBLE_ISIZES)
     }
 }
 
 /// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`.
+#[deriving(Copy)]
 pub struct AssignISizes<'a> {
     pub layout_context: &'a LayoutContext<'a>,
 }
 
 impl<'a> PreorderFlowTraversal for AssignISizes<'a> {
     #[inline]
     fn process(&self, flow: &mut Flow) {
         flow.assign_inline_sizes(self.layout_context);
@@ -312,16 +324,17 @@ impl<'a> PreorderFlowTraversal for Assig
         flow::base(flow).restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW)
     }
 }
 
 /// The assign-block-sizes-and-store-overflow traversal, the last (and most expensive) part of
 /// layout computation. Determines the final block-sizes for all layout objects, computes
 /// positions, and computes overflow regions. In Gecko this corresponds to `Reflow` and
 /// `FinishAndStoreOverflow`.
+#[deriving(Copy)]
 pub struct AssignBSizesAndStoreOverflow<'a> {
     pub layout_context: &'a LayoutContext<'a>,
 }
 
 impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {
     #[inline]
     fn process(&self, flow: &mut Flow) {
         // Can't do anything with flows impacted by floats until we reach their inorder parent.
@@ -336,27 +349,29 @@ impl<'a> PostorderFlowTraversal for Assi
     }
 
     #[inline]
     fn should_process(&self, flow: &mut Flow) -> bool {
         flow::base(flow).restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW)
     }
 }
 
+#[deriving(Copy)]
 pub struct ComputeAbsolutePositions<'a> {
     pub layout_context: &'a LayoutContext<'a>,
 }
 
 impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> {
     #[inline]
     fn process(&self, flow: &mut Flow) {
         flow.compute_absolute_position();
     }
 }
 
+#[deriving(Copy)]
 pub struct BuildDisplayList<'a> {
     pub layout_context: &'a LayoutContext<'a>,
 }
 
 impl<'a> PostorderFlowTraversal for BuildDisplayList<'a> {
     #[inline]
     fn process(&self, flow: &mut Flow) {
         flow.build_display_list(self.layout_context);
--- a/servo/components/layout/util.rs
+++ b/servo/components/layout/util.rs
@@ -14,17 +14,17 @@ use script::dom::bindings::js::JS;
 use script::dom::bindings::utils::Reflectable;
 use script::dom::node::{Node, SharedLayoutData};
 use script::layout_interface::{LayoutChan, TrustedNodeAddress};
 use script_traits::UntrustedNodeAddress;
 use std::mem;
 use std::cell::{Ref, RefMut};
 use style::ComputedValues;
 use style;
-use sync::Arc;
+use std::sync::Arc;
 
 /// Data that layout associates with a node.
 pub struct PrivateLayoutData {
     /// The results of CSS styling for this node's `before` pseudo-element, if any.
     pub before_style: Option<Arc<ComputedValues>>,
 
     /// The results of CSS styling for this node's `after` pseudo-element, if any.
     pub after_style: Option<Arc<ComputedValues>>,
@@ -59,16 +59,17 @@ impl PrivateLayoutData {
             after_flow_construction_result: ConstructionResult::None,
             parallel: DomParallelInfo::new(),
             flags: LayoutDataFlags::empty(),
         }
     }
 }
 
 bitflags! {
+    #[deriving(Copy)]
     flags LayoutDataFlags: u8 {
         #[doc="Whether a flow has been newly constructed."]
         const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01
     }
 }
 
 pub struct LayoutDataWrapper {
     pub chan: Option<LayoutChan>,
--- a/servo/components/layout/wrapper.rs
+++ b/servo/components/layout/wrapper.rs
@@ -132,16 +132,17 @@ pub trait TLayoutNode {
     fn text(&self) -> String;
 
     /// Returns the first child of this node.
     fn first_child(&self) -> Option<Self>;
 }
 
 /// A wrapper so that layout can access only the methods that it should have access to. Layout must
 /// only ever see these and must never see instances of `JS`.
+#[deriving(Copy)]
 pub struct LayoutNode<'a> {
     /// The wrapped node.
     node: JS<Node>,
 
     /// Being chained to a ContravariantLifetime prevents `LayoutNode`s from escaping.
     pub chain: ContravariantLifetime<'a>,
 }
 
@@ -471,16 +472,17 @@ impl<'a> Iterator<LayoutNode<'a>> for La
     fn next(&mut self) -> Option<LayoutNode<'a>> {
         let ret = self.stack.pop();
         ret.map(|node| self.stack.extend(node.rev_children()));
         ret
     }
 }
 
 /// A wrapper around elements that ensures layout can only ever access safe properties.
+#[deriving(Copy)]
 pub struct LayoutElement<'le> {
     element: &'le Element,
 }
 
 impl<'le> LayoutElement<'le> {
     pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
         let style: &Option<PropertyDeclarationBlock> = unsafe {
             &*self.element.style_attribute().borrow_for_layout()
@@ -626,28 +628,28 @@ impl<'le> TElementAttributes for LayoutE
         unsafe {
             self.element.get_simple_color_attribute_for_layout(attribute)
         }
     }
 }
 
 fn get_content(content_list: &content::T) -> String {
     match *content_list {
-        content::Content(ref value) => {
+        content::T::Content(ref value) => {
             let iter = &mut value.clone().into_iter().peekable();
             match iter.next() {
-                Some(content::StringContent(content)) => content,
+                Some(content::ContentItem::StringContent(content)) => content,
                 _ => "".into_string(),
             }
         }
         _ => "".into_string(),
     }
 }
 
-#[deriving(PartialEq, Clone)]
+#[deriving(Copy, PartialEq, Clone)]
 pub enum PseudoElementType {
     Normal,
     Before(display::T),
     After(display::T),
 }
 
 impl PseudoElementType {
     pub fn is_before(&self) -> bool {
@@ -662,17 +664,17 @@ impl PseudoElementType {
             PseudoElementType::After(_) => true,
             _ => false,
         }
     }
 }
 
 /// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout
 /// node does not allow any parents or siblings of nodes to be accessed, to avoid races.
-#[deriving(Clone)]
+#[deriving(Copy, Clone)]
 pub struct ThreadSafeLayoutNode<'ln> {
     /// The wrapped node.
     node: LayoutNode<'ln>,
 
     pseudo: PseudoElementType,
 }
 
 impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
@@ -711,19 +713,19 @@ impl<'ln> TLayoutNode for ThreadSafeLayo
 
         if self.has_before_pseudo() {
             // FIXME(pcwalton): This logic looks weird. Is it right?
             match self.pseudo {
                 PseudoElementType::Normal => {
                     let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(self.get_before_display()));
                     return Some(pseudo_before_node)
                 }
-                PseudoElementType::Before(display::inline) => {}
+                PseudoElementType::Before(display::T::inline) => {}
                 PseudoElementType::Before(_) => {
-                    let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(display::inline));
+                    let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(display::T::inline));
                     return Some(pseudo_before_node)
                 }
                 _ => {}
             }
         }
 
         unsafe {
             self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(&node))
@@ -917,17 +919,17 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
 
             // NB: See the rules for `white-space` here:
             //
             //    http://www.w3.org/TR/CSS21/text.html#propdef-white-space
             //
             // If you implement other values for this property, you will almost certainly
             // want to update this check.
             match self.style().get_inheritedtext().white_space {
-                white_space::normal => true,
+                white_space::T::normal => true,
                 _ => false,
             }
         }
     }
 
     pub fn get_input_value(&self) -> String {
         unsafe {
             match HTMLInputElementCast::to_js(self.get_jsmanaged()) {
--- a/servo/components/msg/compositor_msg.rs
+++ b/servo/components/msg/compositor_msg.rs
@@ -9,46 +9,46 @@ use geom::rect::Rect;
 use layers::platform::surface::NativeGraphicsMetadata;
 use layers::layers::LayerBufferSet;
 use std::fmt::{Formatter, Show};
 use std::fmt;
 
 use constellation_msg::PipelineId;
 
 /// The status of the painter.
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Eq, Clone, Copy)]
 pub enum PaintState {
     Idle,
     Painting,
 }
 
-#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show)]
+#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Copy)]
 pub enum ReadyState {
     /// Informs the compositor that nothing has been done yet. Used for setting status
     Blank,
     /// Informs the compositor that a page is loading. Used for setting status
     Loading,
     /// Informs the compositor that a page is performing layout. Used for setting status
     PerformingLayout,
     /// Informs the compositor that a page is finished loading. Used for setting status
     FinishedLoading,
 }
 
 /// A newtype struct for denoting the age of messages; prevents race conditions.
-#[deriving(PartialEq, Show)]
+#[deriving(PartialEq, Eq, Show, Copy)]
 pub struct Epoch(pub uint);
 
 impl Epoch {
     pub fn next(&mut self) {
         let Epoch(ref mut u) = *self;
         *u += 1;
     }
 }
 
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq, Copy)]
 pub struct LayerId(pub uint, pub uint);
 
 impl Show for LayerId {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         let LayerId(a, b) = *self;
         write!(f, "Layer({}, {})", a, b)
     }
 }
@@ -56,26 +56,27 @@ impl Show for LayerId {
 impl LayerId {
     /// FIXME(#2011, pcwalton): This is unfortunate. Maybe remove this in the future.
     pub fn null() -> LayerId {
         LayerId(0, 0)
     }
 }
 
 /// The scrolling policy of a layer.
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq, Copy)]
 pub enum ScrollPolicy {
     /// These layers scroll when the parent receives a scrolling message.
     Scrollable,
     /// These layers do not scroll when the parent receives a scrolling message.
     FixedPosition,
 }
 
 /// All layer-specific information that the painting task sends to the compositor other than the
 /// buffer contents of the layer itself.
+#[deriving(Copy)]
 pub struct LayerMetadata {
     /// An opaque ID. This is usually the address of the flow and index of the box within it.
     pub id: LayerId,
     /// The position and size of the layer in pixels.
     pub position: Rect<i32>,
     /// The background color of the layer.
     pub background_color: Color,
     /// The scrolling policy of this layer.
--- a/servo/components/msg/constellation_msg.rs
+++ b/servo/components/msg/constellation_msg.rs
@@ -21,50 +21,51 @@ pub struct ConstellationChan(pub Sender<
 
 impl ConstellationChan {
     pub fn new() -> (Receiver<Msg>, ConstellationChan) {
         let (chan, port) = channel();
         (port, ConstellationChan(chan))
     }
 }
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Eq, Copy)]
 pub enum IFrameSandboxState {
     IFrameSandboxed,
     IFrameUnsandboxed
 }
 
 // We pass this info to various tasks, so it lives in a separate, cloneable struct.
-#[deriving(Clone)]
+#[deriving(Clone, Copy)]
 pub struct Failure {
     pub pipeline_id: PipelineId,
     pub subpage_id: Option<SubpageId>,
 }
 
+#[deriving(Copy)]
 pub struct WindowSizeData {
     /// The size of the initial layout viewport, before parsing an
     /// http://www.w3.org/TR/css-device-adapt/#initial-viewport
     pub initial_viewport: TypedSize2D<ViewportPx, f32>,
 
     /// The "viewing area" in page px. See `PagePx` documentation for details.
     pub visible_viewport: TypedSize2D<PagePx, f32>,
 
     /// The resolution of the window in dppx, not including any "pinch zoom" factor.
     pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>,
 }
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Eq, Copy, Clone)]
 pub enum KeyState {
     Pressed,
     Released,
     Repeated,
 }
 
 //N.B. Straight up copied from glfw-rs
-#[deriving(Show)]
+#[deriving(Show, PartialEq, Eq, Copy, Clone)]
 pub enum Key {
     Space,
     Apostrophe,
     Comma,
     Minus,
     Period,
     Slash,
     Num0,
@@ -180,16 +181,17 @@ pub enum Key {
     RightShift,
     RightControl,
     RightAlt,
     RightSuper,
     Menu,
 }
 
 bitflags! {
+    #[deriving(Copy)]
     flags KeyModifiers: u8 {
         const SHIFT = 0x01,
         const CONTROL = 0x02,
         const ALT = 0x04,
         const SUPER = 0x08,
     }
 }
 
@@ -231,32 +233,33 @@ impl LoadData {
             method: Method::Get,
             headers: Headers::new(),
             data: None,
         }
     }
 }
 
 /// Represents the two different ways to which a page can be navigated
-#[deriving(Clone, PartialEq, Hash, Show)]
+#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
 pub enum NavigationType {
     Load,               // entered or clicked on a url
     Navigate,           // browser forward/back buttons
 }
 
-#[deriving(Clone, PartialEq, Hash, Show)]
+#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
 pub enum NavigationDirection {
     Forward,
     Back,
 }
 
-#[deriving(Clone, PartialEq, Eq, Hash, Show)]
+#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
 pub struct PipelineId(pub uint);
 
-#[deriving(Clone, PartialEq, Eq, Hash, Show)]
+#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
 pub struct SubpageId(pub uint);
 
 // The type of pipeline exit. During complete shutdowns, pipelines do not have to
 // release resources automatically released on process termination.
+#[deriving(Copy)]
 pub enum PipelineExitType {
     PipelineOnly,
     Complete,
 }
--- a/servo/components/net/about_loader.rs
+++ b/servo/components/net/about_loader.rs
@@ -6,31 +6,30 @@ use resource_task::{TargetedLoadResponse
 use resource_task::ProgressMsg::Done;
 use file_loader;
 
 use url::Url;
 use hyper::http::RawStatus;
 use servo_util::resource_files::resources_dir_path;
 
 use std::io::fs::PathExtensions;
-use std::str::Slice;
 
 pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
     let senders = ResponseSenders {
         immediate_consumer: start_chan.clone(),
         eventual_consumer: load_data.consumer.clone(),
     };
     match load_data.url.non_relative_scheme_data().unwrap() {
         "blank" => {
             let chan = start_sending(senders, Metadata {
                 final_url: load_data.url,
                 content_type: Some(("text".to_string(), "html".to_string())),
                 charset: Some("utf-8".to_string()),
                 headers: None,
-                status: Some(RawStatus(200, Slice("OK")))
+                status: Some(RawStatus(200, "OK".into_string()))
             });
             chan.send(Done(Ok(())));
             return
         }
         "crash" => panic!("Loading the about:crash URL."),
         "failure" => {
             let mut path = resources_dir_path();
             path.push("failure.html");
--- a/servo/components/net/fetch/request.rs
+++ b/servo/components/net/fetch/request.rs
@@ -6,55 +6,60 @@ use url::Url;
 use hyper::method::Method;
 use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};
 use hyper::header::Headers;
 use hyper::header::common::ContentType;
 use fetch::cors_cache::CORSCache;
 use fetch::response::Response;
 
 /// A [request context](http://fetch.spec.whatwg.org/#concept-request-context)
+#[deriving(Copy)]
 pub enum Context {
     Audio, Beacon, CSPreport, Download, Embed, Eventsource,
     Favicon, Fetch, Font, Form, Frame, Hyperlink, IFrame, Image,
     ImageSet, Import, Internal, Location, Manifest, Object, Ping,
     Plugin, Prefetch, Script, ServiceWorker, SharedWorker, Subresource,
     Style, Track, Video, Worker, XMLHttpRequest, XSLT
 }
 
 /// A [request context frame type](http://fetch.spec.whatwg.org/#concept-request-context-frame-type)
+#[deriving(Copy)]
 pub enum ContextFrameType {
     Auxiliary,
     TopLevel,
     Nested,
     ContextNone
 }
 
 /// A [referer](http://fetch.spec.whatwg.org/#concept-request-referrer)
 pub enum Referer {
     RefererNone,
     Client,
     RefererUrl(Url)
 }
 
 /// A [request mode](http://fetch.spec.whatwg.org/#concept-request-mode)
+#[deriving(Copy)]
 pub enum RequestMode {
     SameOrigin,
     NoCORS,
     CORSMode,
     ForcedPreflightMode
 }
 
 /// Request [credentials mode](http://fetch.spec.whatwg.org/#concept-request-credentials-mode)
+#[deriving(Copy)]
 pub enum CredentialsMode {
     Omit,
     CredentialsSameOrigin,
     Include
 }
 
 /// [Response tainting](http://fetch.spec.whatwg.org/#concept-request-response-tainting)
+#[deriving(Copy)]
 pub enum ResponseTainting {
     Basic,
     CORSTainting,
     Opaque
 }
 
 /// A [Request](http://fetch.spec.whatwg.org/#requests) as defined by the Fetch spec
 pub struct Request {
--- a/servo/components/net/fetch/response.rs
+++ b/servo/components/net/fetch/response.rs
@@ -4,27 +4,27 @@
 
 use url::Url;
 use hyper::status::StatusCode;
 use hyper::header::Headers;
 use std::ascii::AsciiExt;
 use std::comm::Receiver;
 
 /// [Response type](http://fetch.spec.whatwg.org/#concept-response-type)
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Copy)]
 pub enum ResponseType {
     Basic,
     CORS,
     Default,
     Error,
     Opaque
 }
 
 /// [Response termination reason](http://fetch.spec.whatwg.org/#concept-response-termination-reason)
-#[deriving(Clone)]
+#[deriving(Clone, Copy)]
 pub enum TerminationReason {
     EndUserAbort,
     Fatal,
     Timeout
 }
 
 /// The response body can still be pushed to after fetch
 /// This provides a way to store unfinished response bodies
--- a/servo/components/net/http_loader.rs
+++ b/servo/components/net/http_loader.rs
@@ -80,17 +80,17 @@ fn load(load_data: LoadData, start_chan:
 
         // Preserve the `host` header set automatically by Request.
         let host = req.headers().get::<Host>().unwrap().clone();
         *req.headers_mut() = load_data.headers.clone();
         req.headers_mut().set(host);
         // FIXME(seanmonstar): use AcceptEncoding from Hyper once available
         //if !req.headers.has::<AcceptEncoding>() {
             // We currently don't support HTTP Compression (FIXME #2587)
-            req.headers_mut().set_raw("Accept-Encoding", vec![b"identity".to_vec()]);
+            req.headers_mut().set_raw("Accept-Encoding".into_string(), vec![b"identity".to_vec()]);
         //}
         let writer = match load_data.data {
             Some(ref data) => {
                 req.headers_mut().set(ContentLength(data.len()));
                 let mut writer = match req.start() {
                     Ok(w) => w,
                     Err(e) => {
                         send_error(url, e.to_string(), senders);
--- a/servo/components/net/image/holder.rs
+++ b/servo/components/net/image/holder.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use image::base::Image;
 use image_cache_task::ImageResponseMsg;
 use local_image_cache::LocalImageCache;
 
 use geom::size::Size2D;
-use sync::{Arc, Mutex};
+use std::sync::{Arc, Mutex};
 use url::Url;
 
 // FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from
 // the network stack. This should probably be factored out into an interface and use dependency
 // injection.
 
 /// A struct to store image data. The image will be loaded once the first time it is requested,
 /// and an Arc will be stored.  Clones of this Arc are given out on demand.
--- a/servo/components/net/image_cache_task.rs
+++ b/servo/components/net/image_cache_task.rs
@@ -8,17 +8,17 @@ use resource_task::{LoadData, ResourceTa
 use resource_task::ProgressMsg::{Payload, Done};
 
 use servo_util::task::spawn_named;
 use servo_util::taskpool::TaskPool;
 use std::comm::{channel, Receiver, Sender};
 use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
 use std::mem::replace;
-use sync::{Arc, Mutex};
+use std::sync::{Arc, Mutex};
 use serialize::{Encoder, Encodable};
 use url::Url;
 
 pub enum Msg {
     /// Tell the cache that we may need a particular image soon. Must be posted
     /// before Decode
     Prefetch(Url),
 
--- a/servo/components/net/lib.rs
+++ b/servo/components/net/lib.rs
@@ -11,17 +11,16 @@ extern crate collections;
 extern crate geom;
 extern crate hyper;
 extern crate png;
 #[phase(plugin, link)]
 extern crate log;
 extern crate serialize;
 extern crate "util" as servo_util;
 extern crate stb_image;
-extern crate sync;
 extern crate time;
 extern crate url;
 
 /// Image handling.
 ///
 /// It may be surprising that this goes in the network crate as opposed to the graphics crate.
 /// However, image handling is generally very integrated with the network stack (especially where
 /// caching is involved) and as a result it must live in here.
--- a/servo/components/net/resource_task.rs
+++ b/servo/components/net/resource_task.rs
@@ -16,17 +16,16 @@ use servo_util::task::spawn_named;
 use hyper::header::common::UserAgent;
 use hyper::header::Headers;
 use hyper::http::RawStatus;
 use hyper::method::Method;
 use hyper::mime::{Mime, Attr};
 use url::Url;
 
 use std::comm::{channel, Receiver, Sender};
-use std::str::Slice;
 
 pub enum ControlMsg {
     /// Request the data associated with a particular URL
     Load(LoadData),
     Exit
 }
 
 #[deriving(Clone)]
@@ -81,17 +80,18 @@ pub struct Metadata {
 impl Metadata {
     /// Metadata with defaults for everything optional.
     pub fn default(url: Url) -> Metadata {
         Metadata {
             final_url:    url,
             content_type: None,
             charset:      None,
             headers: None,
-            status: Some(RawStatus(200, Slice("OK"))) // http://fetch.spec.whatwg.org/#concept-response-status-message
+            // http://fetch.spec.whatwg.org/#concept-response-status-message
+            status: Some(RawStatus(200, "OK".into_string()))
         }
     }
 
     /// Extract the parts of a Mime that we care about.
     pub fn set_content_type(&mut self, content_type: Option<&Mime>) {
         match content_type {
             None => (),
             Some(&Mime(ref type_, ref subtype, ref parameters)) => {
--- a/servo/components/plugins/lib.rs
+++ b/servo/components/plugins/lib.rs
@@ -16,18 +16,16 @@
 
 #![deny(unused_imports)]
 #![deny(unused_variables)]
 
 #[phase(plugin,link)]
 extern crate syntax;
 #[phase(plugin, link)]
 extern crate rustc;
-#[cfg(test)]
-extern crate sync;
 
 use rustc::lint::LintPassObject;
 use rustc::plugin::Registry;
 use syntax::ext::base::{Decorator, Modifier};
 
 use syntax::parse::token::intern;
 
 // Public for documentation to show up
--- a/servo/components/plugins/lints/inheritance_integrity.rs
+++ b/servo/components/plugins/lints/inheritance_integrity.rs
@@ -1,16 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use syntax::{ast, ast_util};
 use rustc::lint::{Context, LintPass, LintArray, Level};
 use rustc::middle::{ty, def};
-use rustc::middle::typeck::astconv::AstConv;
 
 use utils::match_lang_ty;
 
 declare_lint!(INHERITANCE_INTEGRITY, Deny,
               "Ensures that struct fields are properly laid out for inheritance to work")
 
 /// Lint for ensuring proper layout of DOM structs
 ///
@@ -37,17 +36,17 @@ impl LintPass for InheritancePass {
                                             }
                                             return true;
                                         }
                                         false
                                     })
                                     .map(|(_, f)| f.span);
             // Find all #[dom_struct] fields
             let dom_spans: Vec<_> = def.fields.iter().enumerate().filter_map(|(ctr, f)| {
-                if let ast::TyPath(_, _, ty_id) = f.node.ty.node {
+                if let ast::TyPath(_, ty_id) = f.node.ty.node {
                     if let Some(def::DefTy(def_id, _)) = cx.tcx.def_map.borrow().get(&ty_id).cloned() {
                         if ty::has_attr(cx.tcx, def_id, "_dom_struct_marker") {
                             // If the field is not the first, it's probably
                             // being misused (a)
                             if ctr > 0 {
                                 cx.span_lint(INHERITANCE_INTEGRITY, f.span,
                                              "Bare DOM structs should only be used as the first field of a \
                                               DOM struct. Consider using JS<T> instead.");
--- a/servo/components/plugins/lints/privatize.rs
+++ b/servo/components/plugins/lints/privatize.rs
@@ -2,17 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use syntax::{ast, ast_util};
 use syntax::ast::Public;
 use syntax::attr::AttrMetaMethods;
 use rustc::lint::{Context, LintPass, LintArray};
 use rustc::middle::ty;
-use rustc::middle::typeck::astconv::AstConv;
 
 declare_lint!(PRIVATIZE, Deny,
               "Allows to enforce private fields for struct definitions")
 
 /// Lint for keeping DOM fields private
 ///
 /// This lint (disable with `-A privatize`/`#[allow(privatize)]`) ensures all types marked with `#[privatize]` have no private fields
 pub struct PrivatizePass;
--- a/servo/components/plugins/lints/str_to_string.rs
+++ b/servo/components/plugins/lints/str_to_string.rs
@@ -1,17 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use syntax::ast;
 use rustc::lint::{Context, LintPass, LintArray};
 use rustc::middle::ty::expr_ty;
 use rustc::middle::ty;
-use rustc::middle::typeck::astconv::AstConv;
 
 declare_lint!(STR_TO_STRING, Deny,
               "Warn when a String could use into_string() instead of to_string()")
 
 /// Prefer str.into_string() over str.to_string()
 ///
 /// The latter creates a `Formatter` and is 5x slower than the former
 pub struct StrToStringPass;
@@ -28,21 +27,21 @@ impl LintPass for StrToStringPass {
                 && is_str(cx, &*args[0]) => {
                 cx.span_lint(STR_TO_STRING, expr.span,
                              "str.into_string() is more efficient than str.to_string(), please use it instead");
             },
             _ => ()
         }
 
         fn is_str(cx: &Context, expr: &ast::Expr) -> bool {
-            fn walk_ty<'t>(ty: ty::t) -> ty::t {
-                match ty::get(ty).sty {
+            fn walk_ty<'t>(ty: ty::Ty<'t>) -> ty::Ty<'t> {
+                match ty.sty {
                     ty::ty_ptr(ref tm) | ty::ty_rptr(_, ref tm) => walk_ty(tm.ty),
                     _ => ty
                 }
             }
-            match ty::get(walk_ty(expr_ty(cx.tcx, expr))).sty {
+            match walk_ty(expr_ty(cx.tcx, expr)).sty {
                 ty::ty_str => true,
                 _ => false
             }
         }
     }
 }
--- a/servo/components/plugins/lints/transmute_type.rs
+++ b/servo/components/plugins/lints/transmute_type.rs
@@ -1,17 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use syntax::ast;
 use syntax::attr::AttrMetaMethods;
 use rustc::lint::{Context, LintPass, LintArray};
 use rustc::middle::ty::expr_ty;
-use rustc::middle::typeck::astconv::AstConv;
 use rustc::util::ppaux::Repr;
 
 declare_lint!(TRANSMUTE_TYPE_LINT, Allow,
               "Warn and report types being transmuted")
 
 /// Lint for auditing transmutes
 ///
 /// This lint (off by default, enable with `-W transmute-type-lint`) warns about all the transmutes
@@ -26,17 +25,17 @@ impl LintPass for TransmutePass {
     fn check_expr(&mut self, cx: &Context, ex: &ast::Expr) {
         match ex.node {
             ast::ExprCall(ref expr, ref args) => {
                 match expr.node {
                     ast::ExprPath(ref path) => {
                         if path.segments.last()
                                         .map_or(false, |ref segment| segment.identifier.name.as_str() == "transmute")
                            && args.len() == 1 {
-                            let tcx = cx.tcx();
+                            let tcx = cx.tcx;
                             cx.span_lint(TRANSMUTE_TYPE_LINT, ex.span,
                                          format!("Transmute to {} from {} detected",
                                                  expr_ty(tcx, ex).repr(tcx),
                                                  expr_ty(tcx, &**args.get(0).unwrap()).repr(tcx)
                                         ).as_slice());
                         }
                     }
                     _ => {}
--- a/servo/components/plugins/lints/unrooted_must_root.rs
+++ b/servo/components/plugins/lints/unrooted_must_root.rs
@@ -2,43 +2,43 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use syntax::{ast, codemap, visit};
 use syntax::attr::AttrMetaMethods;
 use rustc::lint::{Context, LintPass, LintArray};
 use rustc::middle::ty::expr_ty;
 use rustc::middle::{ty, def};
-use rustc::middle::typeck::astconv::AstConv;
 use rustc::util::ppaux::Repr;
 use utils::unsafe_context;
 
 declare_lint!(UNROOTED_MUST_ROOT, Deny,
               "Warn and report usage of unrooted jsmanaged objects")
 
 /// Lint for ensuring safe usage of unrooted pointers
 ///
 /// This lint (disable with `-A unrooted-must-root`/`#[allow(unrooted_must_root)]`) ensures that `#[must_root]` values are used correctly.
 /// "Incorrect" usage includes:
 ///
 ///  - Not being used in a struct/enum field which is not `#[must_root]` itself
 ///  - Not being used as an argument to a function (Except onces named `new` and `new_inherited`)
 ///  - Not being bound locally in a `let` statement, assignment, `for` loop, or `match` statement.
 ///
 /// This helps catch most situations where pointers like `JS<T>` are used in a way that they can be invalidated by a GC pass.
+#[allow(missing_copy_implementations)]
 pub struct UnrootedPass;
 
 // Checks if a type has the #[must_root] annotation.
 // Unwraps pointers as well
 // TODO (#3874, sort of): unwrap other types like Vec/Option/HashMap/etc
 fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) {
     match ty.node {
         ast::TyVec(ref t) | ast::TyFixedLengthVec(ref t, _) |
         ast::TyPtr(ast::MutTy { ty: ref t, ..}) | ast::TyRptr(_, ast::MutTy { ty: ref t, ..}) => lint_unrooted_ty(cx, &**t, warning),
-        ast::TyPath(_, _, id) => {
+        ast::TyPath(_, id) => {
                 match cx.tcx.def_map.borrow()[id].clone() {
                     def::DefTy(def_id, _) => {
                         if ty::has_attr(cx.tcx, def_id, "must_root") {
                             cx.span_lint(UNROOTED_MUST_ROOT, ty.span, warning);
                         }
                     }
                     _ => (),
                 }
@@ -141,17 +141,17 @@ impl LintPass for UnrootedPass {
                 ast::ExprForLoop(_, ref e, _, _) => &**e,
                 // XXXManishearth look into `if let` once it lands in our rustc
                 _ => return
             },
             _ => return
         };
 
         let t = expr_ty(cx.tcx, &*expr);
-        match ty::get(t).sty {
+        match t.sty {
             ty::ty_struct(did, _) |
             ty::ty_enum(did, _) => {
                 if ty::has_attr(cx.tcx, did, "must_root") {
                     cx.span_lint(UNROOTED_MUST_ROOT, expr.span,
                                  format!("Expression of type {} must be rooted", t.repr(cx.tcx)).as_slice());
                 }
             }
             _ => {}
--- a/servo/components/plugins/utils.rs
+++ b/servo/components/plugins/utils.rs
@@ -1,28 +1,27 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use rustc::lint::Context;
 use rustc::middle::{ty, def};
-use rustc::middle::typeck::astconv::AstConv;
 
 use syntax::ptr::P;
 use syntax::{ast, ast_map};
 use syntax::ast::{TyPath, Path, AngleBracketedParameters, PathSegment, Ty};
 use syntax::attr::mark_used;
 
 
 /// Matches a type with a provided string, and returns its type parameters if successful
 ///
 /// Try not to use this for types defined in crates you own, use match_lang_ty instead (for lint passes)
 pub fn match_ty_unwrap<'a>(ty: &'a Ty, segments: &[&str]) -> Option<&'a [P<Ty>]> {
     match ty.node {
-        TyPath(Path {segments: ref seg, ..}, _, _) => {
+        TyPath(Path {segments: ref seg, ..}, _) => {
             // So ast::Path isn't the full path, just the tokens that were provided.
             // I could muck around with the maps and find the full path
             // however the more efficient way is to simply reverse the iterators and zip them
             // which will compare them in reverse until one of them runs out of segments
             if seg.iter().rev().zip(segments.iter().rev()).all(|(a,b)| a.identifier.as_str() == *b) {
                 match seg.as_slice().last() {
                     Some(&PathSegment {parameters: AngleBracketedParameters(ref a), ..}) => {
                         Some(a.types.as_slice())
@@ -35,17 +34,17 @@ pub fn match_ty_unwrap<'a>(ty: &'a Ty, s
         },
         _ => None
     }
 }
 
 /// Checks if a type has a #[servo_lang = "str"] attribute
 pub fn match_lang_ty(cx: &Context, ty: &Ty, value: &str) -> bool {
     let mut found = false;
-    if let TyPath(_, _, ty_id) = ty.node {
+    if let TyPath(_, ty_id) = ty.node {
         if let Some(def::DefTy(def_id, _)) = cx.tcx.def_map.borrow().get(&ty_id).cloned() {
             // Iterating through attributes is hard because of cross-crate defs
             ty::each_attr(cx.tcx, def_id, |attr| {
                 if let ast::MetaNameValue(ref name, ref val) = attr.node.value.node {
                     if name.get() == "servo_lang" {
                         if let ast::LitStr(ref v, _) = val.node {
                             if v.get() == value {
                                 mark_used(attr);
--- a/servo/components/script/Cargo.toml
+++ b/servo/components/script/Cargo.toml
@@ -43,19 +43,16 @@ path = "../canvas"
 git = "https://github.com/servo/rust-cssparser"
 
 [dependencies.geom]
 git = "https://github.com/servo/rust-geom"
 
 [dependencies.html5ever]
 git = "https://github.com/servo/html5ever"
 
-[dependencies.encoding]
-git = "https://github.com/lifthrasiir/rust-encoding"
-
 [dependencies.hyper]
 git = "https://github.com/servo/hyper"
 branch = "servo"
 
 [dependencies.js]
 git = "https://github.com/servo/rust-mozjs"
 
 [dependencies.url]
@@ -67,8 +64,11 @@ git = "https://github.com/rust-lang/uuid
 [dependencies.string_cache]
 git = "https://github.com/servo/string-cache"
 
 [dependencies.string_cache_macros]
 git = "https://github.com/servo/string-cache"
 
 [dependencies.time]
 git = "https://github.com/rust-lang/time"
+
+[dependencies]
+encoding = "0.2"
--- a/servo/components/script/cors.rs
+++ b/servo/components/script/cors.rs
@@ -35,17 +35,17 @@ pub struct CORSRequest {
     /// CORS preflight flag (http://fetch.spec.whatwg.org/#concept-http-fetch)
     /// Indicates that a CORS preflight request and/or cache check is to be performed
     pub preflight_flag: bool
 }
 
 /// http://fetch.spec.whatwg.org/#concept-request-mode
 /// This only covers some of the request modes. The
 /// `same-origin` and `no CORS` modes are unnecessary for XHR.
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Copy, Clone)]
 pub enum RequestMode {
     CORS, // CORS
     ForcedPreflight // CORS-with-forced-preflight
 }
 
 impl CORSRequest {
     /// Creates a CORS request if necessary. Will return an error when fetching is forbidden
     pub fn maybe_new(referer: Url, destination: Url, mode: RequestMode,
--- a/servo/components/script/dom/bindings/callback.rs
+++ b/servo/components/script/dom/bindings/callback.rs
@@ -11,29 +11,30 @@ use dom::bindings::js::JSRef;
 use dom::bindings::utils::Reflectable;
 use js::jsapi::{JSContext, JSObject, JS_WrapObject, JS_ObjectIsCallable};
 use js::jsapi::JS_GetProperty;
 use js::jsval::{JSVal, UndefinedValue};
 
 use std::ptr;
 
 /// The exception handling used for a call.
+#[deriving(Copy)]
 pub enum ExceptionHandling {
     /// Report any exception and don't throw it to the caller code.
     ReportExceptions,
     /// Throw an exception to the caller code if the thrown exception is a
     /// binding object for a DOMError from the caller's scope, otherwise report
     /// it.
     RethrowContentExceptions,
     /// Throw any exception to the caller code.
     RethrowExceptions
 }
 
 /// A common base class for representing IDL callback function types.
-#[deriving(Clone,PartialEq)]
+#[deriving(Copy, Clone,PartialEq)]
 #[jstraceable]
 pub struct CallbackFunction {
     object: CallbackObject
 }
 
 impl CallbackFunction {
     /// Create a new `CallbackFunction` for this object.
     pub fn new(callback: *mut JSObject) -> CallbackFunction {
@@ -41,26 +42,26 @@ impl CallbackFunction {
             object: CallbackObject {
                 callback: callback
             }
         }
     }
 }
 
 /// A common base class for representing IDL callback interface types.
-#[deriving(Clone,PartialEq)]
+#[deriving(Copy, Clone,PartialEq)]
 #[jstraceable]
 pub struct CallbackInterface {
     object: CallbackObject
 }
 
 /// A common base class for representing IDL callback function and
 /// callback interface types.
 #[allow(raw_pointer_deriving)]
-#[deriving(Clone,PartialEq)]
+#[deriving(Copy, Clone,PartialEq)]
 #[jstraceable]
 struct CallbackObject {
     /// The underlying `JSObject`.
     callback: *mut JSObject,
 }
 
 /// A trait to be implemented by concrete IDL callback function and
 /// callback interface types.
--- a/servo/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/servo/components/script/dom/bindings/codegen/CodegenRust.py
@@ -2758,17 +2758,17 @@ def getEnumValueName(value):
     return MakeNativeName(value)
 
 class CGEnum(CGThing):
     def __init__(self, enum):
         CGThing.__init__(self)
 
         decl = """\
 #[repr(uint)]
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Copy)]
 #[jstraceable]
 pub enum %s {
     %s
 }
 """ % (enum.identifier.name, ",\n    ".join(map(getEnumValueName, enum.values())))
 
         inner = """\
 use dom::bindings::conversions::ToJSValConvertible;
@@ -4688,17 +4688,17 @@ class CGCallback(CGClass):
             if not method.needThisHandling:
                 realMethods.append(method)
             else:
                 realMethods.extend(self.getMethodImpls(method))
         CGClass.__init__(self, name,
                          bases=[ClassBase(baseName)],
                          constructors=self.getConstructors(),
                          methods=realMethods+getters+setters,
-                         decorators="#[deriving(PartialEq,Clone)]#[jstraceable]")
+                         decorators="#[deriving(PartialEq,Copy,Clone)]#[jstraceable]")
 
     def getConstructors(self):
         return [ClassConstructor(
             [Argument("*mut JSObject", "aCallback")],
             bodyInHeader=True,
             visibility="pub",
             explicit=False,
             baseConstructors=[
@@ -5184,18 +5184,18 @@ class GlobalGenRoots():
     def PrototypeList(config):
         # Prototype ID enum.
         protos = [d.name for d in config.getDescriptors(isCallback=False)]
         proxies = [d.name for d in config.getDescriptors(proxy=True)]
 
         return CGList([
             CGGeneric(AUTOGENERATED_WARNING_COMMENT),
             CGGeneric("pub const MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength),
-            CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq"),
-            CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq"),
+            CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq, Copy"),
+            CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq, Copy"),
         ])
 
 
     @staticmethod
     def RegisterBindings(config):
         # TODO - Generate the methods we want
         code = CGList([
             CGRegisterProtos(config),
--- a/servo/components/script/dom/bindings/global.rs
+++ b/servo/components/script/dom/bindings/global.rs
@@ -21,16 +21,17 @@ use js::glue::{GetGlobalForObjectCrossCo
 use js::jsapi::{JSContext, JSObject};
 use js::jsapi::{JS_GetClass};
 use js::jsval::ObjectOrNullValue;
 use url::Url;
 
 use std::ptr;
 
 /// A freely-copyable reference to a rooted global object.
+#[deriving(Copy)]
 pub enum GlobalRef<'a> {
     Window(JSRef<'a, window::Window>),
     Worker(JSRef<'a, WorkerGlobalScope>),
 }
 
 /// A stack-based rooted reference to a global object.
 pub enum GlobalRoot {
     Window(Root<window::Window>),
--- a/servo/components/script/dom/bindings/js.rs
+++ b/servo/components/script/dom/bindings/js.rs
@@ -65,16 +65,25 @@ use std::mem;
 /// `JS<T>::assign` method or `OptionalSettable::assign` (for `Option<JS<T>>` fields).
 #[allow(unrooted_must_root)]
 pub struct Temporary<T> {
     inner: JS<T>,
     /// On-stack JS pointer to assuage conservative stack scanner
     _js_ptr: *mut JSObject,
 }
 
+impl<T> Clone for Temporary<T> {
+    fn clone(&self) -> Temporary<T> {
+        Temporary {
+            inner: self.inner,
+            _js_ptr: self._js_ptr,
+        }
+    }
+}
+
 impl<T> PartialEq for Temporary<T> {
     fn eq(&self, other: &Temporary<T>) -> bool {
         self.inner == other.inner
     }
 }
 
 impl<T: Reflectable> Temporary<T> {
     /// Create a new `Temporary` value from a JS-owned value.
@@ -87,20 +96,22 @@ impl<T: Reflectable> Temporary<T> {
 
     /// Create a new `Temporary` value from a rooted value.
     pub fn from_rooted<'a>(root: JSRef<'a, T>) -> Temporary<T> {
         Temporary::new(JS::from_rooted(root))
     }
 
     /// Create a stack-bounded root for this value.
     pub fn root(self) -> Root<T> {
-        let collection = StackRoots.get().unwrap();
-        unsafe {
-            Root::new(&**collection, &self.inner)
-        }
+        StackRoots.with(|ref collection| {
+            let RootCollectionPtr(collection) = collection.get().unwrap();
+            unsafe {
+                Root::new(&*collection, &self.inner)
+            }
+        })
     }
 
     unsafe fn inner(&self) -> JS<T> {
         self.inner.clone()
     }
 
     //XXXjdm It would be lovely if this could be private.
     pub unsafe fn transmute<To>(self) -> Temporary<To> {
@@ -109,16 +120,18 @@ impl<T: Reflectable> Temporary<T> {
 }
 
 /// A rooted, JS-owned value. Must only be used as a field in other JS-owned types.
 #[must_root]
 pub struct JS<T> {
     ptr: *const T
 }
 
+impl<T> Copy for JS<T> {}
+
 impl<T> PartialEq for JS<T> {
     #[allow(unrooted_must_root)]
     fn eq(&self, other: &JS<T>) -> bool {
         self.ptr == other.ptr
     }
 }
 
 impl <T> Clone for JS<T> {
@@ -146,20 +159,22 @@ impl<T: Reflectable> JS<T> {
         JS {
             ptr: raw
         }
     }
 
 
     /// Root this JS-owned value to prevent its collection as garbage.
     pub fn root(&self) -> Root<T> {
-        let collection = StackRoots.get().unwrap();
-        unsafe {
-            Root::new(&**collection, self)
-        }
+        StackRoots.with(|ref collection| {
+            let RootCollectionPtr(collection) = collection.get().unwrap();
+            unsafe {
+                Root::new(&*collection, self)
+            }
+        })
     }
 }
 
 impl<T: Assignable<U>, U: Reflectable> JS<U> {
     pub fn from_rooted(root: T) -> JS<U> {
         unsafe {
             root.get_js()
         }
@@ -265,17 +280,17 @@ impl<T: Reflectable> MutNullableJS<T> {
         self.ptr.get()
     }
 
     pub fn or_init(&self, cb: || -> Temporary<T>) -> Temporary<T> {
         match self.get() {
             Some(inner) => inner,
             None => {
                 let inner = cb();
-                self.assign(Some(inner));
+                self.assign(Some(inner.clone()));
                 inner
             },
         }
     }
 }
 
 impl<T: Reflectable> JS<T> {
     /// Returns an unsafe pointer to the interior of this JS object without touching the borrow
@@ -445,16 +460,20 @@ impl<T: Assignable<U>, U: Reflectable> T
     }
 }
 
 /// An opaque, LIFO rooting mechanism.
 pub struct RootCollection {
     roots: UnsafeCell<SmallVec16<*mut JSObject>>,
 }
 
+pub struct RootCollectionPtr(pub *const RootCollection);
+
+impl Copy for RootCollectionPtr {}
+
 impl RootCollection {
     /// Create an empty collection of roots
     pub fn new() -> RootCollection {
         RootCollection {
             roots: UnsafeCell::new(SmallVec16::new()),
         }
     }
 
@@ -543,16 +562,18 @@ impl<'a, T: Reflectable> Deref<T> for JS
 }
 
 /// Encapsulates a reference to something that is guaranteed to be alive. This is freely copyable.
 pub struct JSRef<'a, T> {
     ptr: *const T,
     chain: ContravariantLifetime<'a>,
 }
 
+impl<'a, T> Copy for JSRef<'a, T> {}
+
 impl<'a, T> Clone for JSRef<'a, T> {
     fn clone(&self) -> JSRef<'a, T> {
         JSRef {
             ptr: self.ptr.clone(),
             chain: self.chain,
         }
     }
 }
--- a/servo/components/script/dom/bindings/refcounted.rs
+++ b/servo/components/script/dom/bindings/refcounted.rs
@@ -28,19 +28,21 @@ use dom::bindings::js::{Temporary, JS, J
 use dom::bindings::utils::{Reflector, Reflectable};
 use script_task::{ScriptMsg, ScriptChan};
 
 use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext};
 
 use libc;
 use std::cell::RefCell;
 use std::collections::hash_map::{HashMap, Vacant, Occupied};
+use std::rc::Rc;
 use std::sync::{Arc, Mutex};
 
-local_data_key!(pub LiveReferences: LiveDOMReferences)
+thread_local!(pub static LiveReferences: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None)))
+
 
 /// A safe wrapper around a raw pointer to a DOM object that can be
 /// shared among tasks for use in asynchronous operations. The underlying
 /// DOM object is guaranteed to live at least as long as the last outstanding
 /// `Trusted<T>` instance.
 pub struct Trusted<T> {
     /// A pointer to the Rust DOM object of type T, but void to allow
     /// sending `Trusted<T>` between tasks, regardless of T's sendability.
@@ -50,34 +52,38 @@ pub struct Trusted<T> {
     owner_thread: *const libc::c_void,
 }
 
 impl<T: Reflectable> Trusted<T> {
     /// Create a new `Trusted<T>` instance from an existing DOM pointer. The DOM object will
     /// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
     /// lifetime.
     pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: Box<ScriptChan + Send>) -> Trusted<T> {
-        let live_references = LiveReferences.get().unwrap();
-        let refcount = live_references.addref(cx, &*ptr as *const T);
-        Trusted {
-            ptr: &*ptr as *const T as *const libc::c_void,
-            refcount: refcount,
-            script_chan: script_chan,
-            owner_thread: (&*live_references) as *const _ as *const libc::c_void,
-        }
+        LiveReferences.with(|ref r| {
+            let r = r.borrow();
+            let live_references = r.as_ref().unwrap();
+            let refcount = live_references.addref(cx, &*ptr as *const T);
+            Trusted {
+                ptr: &*ptr as *const T as *const libc::c_void,
+                refcount: refcount,
+                script_chan: script_chan.clone(),
+                owner_thread: (&*live_references) as *const _ as *const libc::c_void,
+            }
+        })
     }
 
     /// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
     /// a different thread than the original value from which this `Trusted<T>` was
     /// obtained.
     pub fn to_temporary(&self) -> Temporary<T> {
-        assert!({
-            let live_references = LiveReferences.get().unwrap();
+        assert!(LiveReferences.with(|ref r| {
+            let r = r.borrow();
+            let live_references = r.as_ref().unwrap();
             self.owner_thread == (&*live_references) as *const _ as *const libc::c_void
-        });
+        }));
         unsafe {
             Temporary::new(JS::from_raw(self.ptr as *const T))
         }
     }
 }
 
 impl<T: Reflectable> Clone for Trusted<T> {
     fn clone(&self) -> Trusted<T> {
@@ -112,19 +118,21 @@ impl<T: Reflectable> Drop for Trusted<T>
 pub struct LiveDOMReferences {
     // keyed on pointer to Rust DOM object
     table: RefCell<HashMap<*const libc::c_void, Arc<Mutex<uint>>>>
 }
 
 impl LiveDOMReferences {
     /// Set up the task-local data required for storing the outstanding DOM references.
     pub fn initialize() {
-        LiveReferences.replace(Some(LiveDOMReferences {
-            table: RefCell::new(HashMap::new()),
-        }));
+        LiveReferences.with(|ref r| {
+            *r.borrow_mut() = Some(LiveDOMReferences {
+                table: RefCell::new(HashMap::new()),
+            })
+        });
     }
 
     fn addref<T: Reflectable>(&self, cx: *mut JSContext, ptr: *const T) -> Arc<Mutex<uint>> {
         let mut table = self.table.borrow_mut();
         match table.entry(ptr as *const libc::c_void) {
             Occupied(mut entry) => {
                 let refcount = entry.get_mut();
                 *refcount.lock() += 1;
@@ -139,40 +147,43 @@ impl LiveDOMReferences {
                 entry.set(refcount.clone());
                 refcount
             }
         }
     }
 
     /// Unpin the given DOM object if its refcount is 0.
     pub fn cleanup(cx: *mut JSContext, raw_reflectable: *const libc::c_void) {
-        let live_references = LiveReferences.get().unwrap();
-        let reflectable = raw_reflectable as *const Reflector;
-        let mut table = live_references.table.borrow_mut();
-        match table.entry(raw_reflectable) {
-            Occupied(entry) => {
-                if *entry.get().lock() != 0 {
-                    // there could have been a new reference taken since
-                    // this message was dispatched.
-                    return;
-                }
+        LiveReferences.with(|ref r| {
+            let r = r.borrow();
+            let live_references = r.as_ref().unwrap();
+            let reflectable = raw_reflectable as *const Reflector;
+            let mut table = live_references.table.borrow_mut();
+            match table.entry(raw_reflectable) {
+                Occupied(entry) => {
+                    if *entry.get().lock() != 0 {
+                        // there could have been a new reference taken since
+                        // this message was dispatched.
+                        return;
+                    }
 
-                unsafe {
-                    JS_RemoveObjectRoot(cx, (*reflectable).rootable());
+                    unsafe {
+                        JS_RemoveObjectRoot(cx, (*reflectable).rootable());
+                    }
+                    let _ = entry.take();
                 }
-                let _ = entry.take();
+                Vacant(_) => {
+                    // there could be a cleanup message dispatched, then a new
+                    // pinned reference obtained and released before the message
+                    // is processed, at which point there would be no matching
+                    // hashtable entry.
+                    info!("attempt to cleanup an unrecognized reflector");
+                }
             }
-            Vacant(_) => {
-                // there could be a cleanup message dispatched, then a new
-                // pinned reference obtained and released before the message
-                // is processed, at which point there would be no matching
-                // hashtable entry.
-                info!("attempt to cleanup an unrecognized reflector");
-            }
-        }
+        })
     }
 }
 
 impl Drop for LiveDOMReferences {
     fn drop(&mut self) {
         assert!(self.table.borrow().keys().count() == 0);
     }
 }
--- a/servo/components/script/dom/bindings/utils.rs
+++ b/servo/components/script/dom/bindings/utils.rs
@@ -124,26 +124,28 @@ pub struct NativePropertyHooks {
     /// The property arrays for this interface.
     pub native_properties: &'static NativeProperties,
 
     /// The NativePropertyHooks instance for the parent interface, if any.
     pub proto_hooks: Option<&'static NativePropertyHooks>,
 }
 
 /// The struct that holds inheritance information for DOM object reflectors.
+#[deriving(Copy)]
 pub struct DOMClass {
     /// A list of interfaces that this object implements, in order of decreasing
     /// derivedness.
     pub interface_chain: [PrototypeList::ID, ..MAX_PROTO_CHAIN_LENGTH],
 
     /// The NativePropertyHooks for the interface associated with this class.
     pub native_hooks: &'static NativePropertyHooks,
 }
 
 /// The JSClass used for DOM object reflectors.
+#[deriving(Copy)]
 pub struct DOMJSClass {
     /// The actual JSClass.
     pub base: js::Class,
     /// Associated data for DOM object reflectors.
     pub dom_class: DOMClass
 }
 
 /// Returns the ProtoOrIfaceArray for the given global object.
@@ -581,40 +583,40 @@ pub enum XMLName {
 /// for details.
 pub fn xml_name_type(name: &str) -> XMLName {
     fn is_valid_start(c: char) -> bool {
         match c {
             ':' |
             'A' ... 'Z' |
             '_' |
             'a' ... 'z' |
-            '\u00C0' ... '\u00D6' |
-            '\u00D8' ... '\u00F6' |
-            '\u00F8' ... '\u02FF' |
-            '\u0370' ... '\u037D' |
-            '\u037F' ... '\u1FFF' |
-            '\u200C' ... '\u200D' |
-            '\u2070' ... '\u218F' |
-            '\u2C00' ... '\u2FEF' |
-            '\u3001' ... '\uD7FF' |
-            '\uF900' ... '\uFDCF' |
-            '\uFDF0' ... '\uFFFD' |
-            '\U00010000' ... '\U000EFFFF' => true,
+            '\u{C0}' ... '\u{D6}' |
+            '\u{D8}' ... '\u{F6}' |
+            '\u{F8}' ... '\u{2FF}' |
+            '\u{370}' ... '\u{37D}' |
+            '\u{37F}' ... '\u{1FFF}' |
+            '\u{200C}' ... '\u{200D}' |
+            '\u{2070}' ... '\u{218F}' |
+            '\u{2C00}' ... '\u{2FEF}' |
+            '\u{3001}' ... '\u{D7FF}' |
+            '\u{F900}' ... '\u{FDCF}' |
+            '\u{FDF0}' ... '\u{FFFD}' |
+            '\u{10000}' ... '\u{EFFFF}' => true,
             _ => false,
         }
     }
 
     fn is_valid_continuation(c: char) -> bool {
         is_valid_start(c) || match c {
             '-' |
             '.' |
             '0' ... '9' |
-            '\u00B7' |
-            '\u0300' ... '\u036F' |
-            '\u203F' ... '\u2040' => true,
+            '\u{B7}' |
+            '\u{300}' ... '\u{36F}' |
+            '\u{203F}' ... '\u{2040}' => true,
             _ => false,
         }
     }
 
     let mut iter = name.chars();
     let mut non_qname_colons = false;
     let mut seen_colon = false;
     match iter.next() {
--- a/servo/components/script/dom/domexception.rs
+++ b/servo/components/script/dom/domexception.rs
@@ -7,17 +7,17 @@ use dom::bindings::codegen::Bindings::DO
 use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
 use dom::bindings::error::Error;
 use dom::bindings::global::GlobalRef;
 use dom::bindings::js::{JSRef, Temporary};
 use dom::bindings::utils::{Reflector, reflect_dom_object};
 use servo_util::str::DOMString;
 
 #[repr(uint)]
-#[deriving(Show)]
+#[deriving(Copy, Show)]
 #[jstraceable]
 pub enum DOMErrorName {
     IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR as uint,
     HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR as uint,
     WrongDocumentError = DOMExceptionConstants::WRONG_DOCUMENT_ERR as uint,
     InvalidCharacterError = DOMExceptionConstants::INVALID_CHARACTER_ERR as uint,
     NoModificationAllowedError = DOMExceptionConstants::NO_MODIFICATION_ALLOWED_ERR as uint,
     NotFoundError = DOMExceptionConstants::NOT_FOUND_ERR as uint,
--- a/servo/components/script/dom/element.rs
+++ b/servo/components/script/dom/element.rs
@@ -81,17 +81,17 @@ impl ElementDerived for EventTarget {
     fn is_element(&self) -> bool {
         match *self.type_id() {
             EventTargetTypeId::Node(NodeTypeId::Element(_)) => true,
             _ => false
         }
     }
 }
 
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 #[jstraceable]
 pub enum ElementTypeId {
     HTMLElement(HTMLElementTypeId),
     Element,
 }
 
 #[deriving(PartialEq)]
 pub enum ElementCreator {
@@ -586,17 +586,17 @@ pub trait AttributeHandlers {
     fn set_tokenlist_attribute(self, name: &Atom, value: DOMString);
     fn set_atomic_tokenlist_attribute(self, name: &Atom, tokens: Vec<Atom>);
     fn get_uint_attribute(self, name: &Atom) -> u32;
     fn set_uint_attribute(self, name: &Atom, value: u32);
 }
 
 impl<'a> AttributeHandlers for JSRef<'a, Element> {
     fn get_attribute(self, namespace: Namespace, local_name: &Atom) -> Option<Temporary<Attr>> {
-        self.get_attributes(local_name).iter().map(|attr| attr.root())
+        self.get_attributes(local_name).into_iter().map(|attr| attr.root())
             .find(|attr| *attr.r().namespace() == namespace)
             .map(|x| Temporary::from_rooted(x.r()))
     }
 
     fn get_attributes(self, local_name: &Atom) -> Vec<Temporary<Attr>> {
         self.attrs.borrow().iter().map(|attr| attr.root()).filter_map(|attr| {
             if *attr.r().local_name() == *local_name {
                 Some(Temporary::from_rooted(attr.r()))
@@ -836,19 +836,19 @@ impl<'a> ElementMethods for JSRef<'a, El
     }
 
     // http://dom.spec.whatwg.org/#dom-element-tagname
     fn TagName(self) -> DOMString {
         let qualified_name = match self.prefix {
             Some(ref prefix) => {
                 (format!("{}:{}",
                          prefix.as_slice(),
-                         self.local_name.as_slice())).into_maybe_owned()
+                         self.local_name.as_slice())).into_cow()
             },
-            None => self.local_name.as_slice().into_maybe_owned()
+            None => self.local_name.as_slice().into_cow()
         };
         if self.html_element_in_html_document() {
             qualified_name.as_slice().to_ascii_upper()
         } else {
             qualified_name.into_string()
         }
     }
 
@@ -1285,17 +1285,17 @@ impl<'a> VirtualMethods for JSRef<'a, El
 impl<'a> style::TElement<'a> for JSRef<'a, Element> {
     fn get_attr(self, namespace: &Namespace, attr: &Atom) -> Option<&'a str> {
         self.get_attribute(namespace.clone(), attr).root().map(|attr| {
             // This transmute is used to cheat the lifetime restriction.
             unsafe { mem::transmute(attr.r().value().as_slice()) }
         })
     }
     fn get_attrs(self, attr: &Atom) -> Vec<&'a str> {
-        self.get_attributes(attr).iter().map(|attr| attr.root()).map(|attr| {
+        self.get_attributes(attr).into_iter().map(|attr| attr.root()).map(|attr| {
             // This transmute is used to cheat the lifetime restriction.
             unsafe { mem::transmute(attr.r().value().as_slice()) }
         }).collect()
     }
     fn get_link(self) -> Option<&'a str> {
         // FIXME: This is HTML only.
         let node: JSRef<Node> = NodeCast::from_ref(self);
         match node.type_id() {
--- a/servo/components/script/dom/event.rs
+++ b/servo/components/script/dom/event.rs
@@ -12,16 +12,17 @@ use dom::bindings::utils::{Reflector, re
 use dom::eventtarget::EventTarget;
 use servo_util::str::DOMString;
 use std::cell::Cell;
 use std::default::Default;
 
 use time;
 
 #[jstraceable]
+#[deriving(Copy)]
 pub enum EventPhase {
     None      = EventConstants::NONE as int,
     Capturing = EventConstants::CAPTURING_PHASE as int,
     AtTarget  = EventConstants::AT_TARGET as int,
     Bubbling  = EventConstants::BUBBLING_PHASE as int,
 }
 
 #[deriving(PartialEq)]
--- a/servo/components/script/dom/eventtarget.rs
+++ b/servo/components/script/dom/eventtarget.rs
@@ -23,51 +23,51 @@ use servo_util::fnv::FnvHasher;
 use servo_util::str::DOMString;
 use libc::{c_char, size_t};
 use std::collections::hash_map::{Occupied, Vacant};
 use std::ptr;
 use url::Url;
 
 use std::collections::HashMap;
 
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 #[jstraceable]
 pub enum ListenerPhase {
     Capturing,
     Bubbling,
 }
 
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 #[jstraceable]
 pub enum EventTargetTypeId {
     Node(NodeTypeId),
     WebSocket,
     Window,
     Worker,
     WorkerGlobalScope(WorkerGlobalScopeTypeId),
     XMLHttpRequestEventTarget(XMLHttpRequestEventTargetTypeId)
 }
 
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 #[jstraceable]
 pub enum EventListenerType {
     Additive(EventListener),
     Inline(EventListener),
 }
 
 impl EventListenerType {
     fn get_listener(&self) -> EventListener {
         match *self {
             EventListenerType::Additive(listener) |
             EventListenerType::Inline(listener) => listener
         }
     }
 }
 
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 #[jstraceable]
 #[privatize]
 pub struct EventListenerEntry {
     phase: ListenerPhase,
     listener: EventListenerType
 }
 
 #[dom_struct]
--- a/servo/components/script/dom/htmlcanvaselement.rs
+++ b/servo/components/script/dom/htmlcanvaselement.rs
@@ -114,17 +114,17 @@ impl<'a> VirtualMethods for JSRef<'a, HT
                 true
             }
             _ => false,
         };
 
         if recreate {
             let (w, h) = (self.width.get() as i32, self.height.get() as i32);
             match self.context.get() {
-                Some(ref context) => context.root().r().recreate(Size2D(w, h)),
+                Some(context) => context.root().r().recreate(Size2D(w, h)),
                 None => ()
             }
         }
     }
 
     fn after_set_attr(&self, attr: JSRef<Attr>) {
         match self.super_type() {
             Some(ref s) => s.after_set_attr(attr),
@@ -142,15 +142,15 @@ impl<'a> VirtualMethods for JSRef<'a, HT
                 true
             }
             _ => false,
         };
 
         if recreate {
             let (w, h) = (self.width.get() as i32, self.height.get() as i32);
             match self.context.get() {
-                Some(ref context) => context.root().r().recreate(Size2D(w, h)),
+                Some(context) => context.root().r().recreate(Size2D(w, h)),
                 None => ()
             }
         }
     }
 }
 
--- a/servo/components/script/dom/htmlelement.rs
+++ b/servo/components/script/dom/htmlelement.rs
@@ -151,17 +151,17 @@ fn to_snake_case(name: DOMString) -> DOM
         }
     }
     attr_name
 }
 
 impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> {
     fn set_custom_attr(self, name: DOMString, value: DOMString) -> ErrorResult {
         if name.as_slice().chars()
-               .skip_while(|&ch| ch != '\u002d')
+               .skip_while(|&ch| ch != '\u{2d}')
                .nth(1).map_or(false, |ch| ch as u8 - b'a' < 26) {
             return Err(Syntax);
         }
         let element: JSRef<Element> = ElementCast::from_ref(self);
         element.set_custom_attribute(to_snake_case(name), value)
     }
 
     fn get_custom_attr(self, name: DOMString) -> Option<DOMString> {
@@ -199,17 +199,17 @@ impl<'a> VirtualMethods for JSRef<'a, HT
             let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
             evtarget.set_event_handler_uncompiled(cx, url, reflector,
                                                   name.slice_from(2),
                                                   attr.value().as_slice().into_string());
         }
     }
 }
 
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 #[jstraceable]
 pub enum HTMLElementTypeId {
     HTMLElement,
 
     HTMLAnchorElement,
     HTMLAppletElement,
     HTMLAreaElement,
     HTMLBaseElement,
--- a/servo/components/script/dom/htmlformelement.rs
+++ b/servo/components/script/dom/htmlformelement.rs
@@ -124,21 +124,23 @@ impl<'a> HTMLFormElementMethods for JSRe
     }
 
     // https://html.spec.whatwg.org/multipage/forms.html#dom-form-reset
     fn Reset(self) {
         self.reset(ResetFrom::FromFormResetMethod);
     }
 }
 
+#[deriving(Copy)]
 pub enum SubmittedFrom {
     FromFormSubmitMethod,
     NotFromFormSubmitMethod
 }
 
+#[deriving(Copy)]
 pub enum ResetFrom {
     FromFormResetMethod,
     NotFromFormResetMethod
 }
 
 pub trait HTMLFormElementHelpers {
     // https://html.spec.whatwg.org/multipage/forms.html#concept-form-submit
     fn submit(self, submit_method_flag: SubmittedFrom, submitter: FormSubmitter);
@@ -391,28 +393,31 @@ impl<'a> HTMLFormElementHelpers for JSRe
 
 // TODO: add file support
 pub struct FormDatum {
     pub ty: DOMString,
     pub name: DOMString,
     pub value: DOMString
 }
 
+#[deriving(Copy)]
 pub enum FormEncType {
     TextPlainEncoded,
     UrlEncoded,
     FormDataEncoded
 }
 
+#[deriving(Copy)]
 pub enum FormMethod {
     FormGet,
     FormPost,
     FormDialog
 }
 
+#[deriving(Copy)]
 pub enum FormSubmitter<'a> {
     FormElement(JSRef<'a, HTMLFormElement>),
     InputElement(JSRef<'a, HTMLInputElement>)
     // TODO: Submit buttons, image submit, etc etc
 }
 
 impl<'a> FormSubmitter<'a> {
     fn action(&self) -> DOMString {
--- a/servo/components/script/dom/htmliframeelement.rs
+++ b/servo/components/script/dom/htmliframeelement.rs
@@ -51,16 +51,17 @@ pub struct HTMLIFrameElement {
 impl HTMLIFrameElementDerived for EventTarget {
     fn is_htmliframeelement(&self) -> bool {
         *self.type_id() == EventTargetTypeId::Node(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement)))
     }
 }
 
 #[jstraceable]
 #[privatize]
+#[deriving(Copy)]
 pub struct IFrameSize {
     pipeline_id: PipelineId,
     subpage_id: SubpageId,
 }
 
 impl IFrameSize {
     #[inline]
     pub fn pipeline_id<'a>(&'a self) -> &'a PipelineId {
--- a/servo/components/script/dom/htmlinputelement.rs
+++ b/servo/components/script/dom/htmlinputelement.rs
@@ -40,17 +40,17 @@ use string_cache::Atom;
 use std::ascii::OwnedAsciiExt;
 use std::cell::Cell;
 use std::default::Default;
 
 const DEFAULT_SUBMIT_VALUE: &'static str = "Submit";
 const DEFAULT_RESET_VALUE: &'static str = "Reset";
 
 #[jstraceable]
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Copy)]
 #[allow(dead_code)]
 enum InputType {
     InputSubmit,
     InputReset,
     InputButton,
     InputText,
     InputFile,
     InputImage,
--- a/servo/components/script/dom/htmlmediaelement.rs
+++ b/servo/components/script/dom/htmlmediaelement.rs
@@ -33,15 +33,15 @@ impl HTMLMediaElement {
     }
 
     #[inline]
     pub fn htmlelement<'a>(&'a self) -> &'a HTMLElement {
         &self.htmlelement
     }
 }
 
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 #[jstraceable]
 pub enum HTMLMediaElementTypeId {
     HTMLAudioElement,
     HTMLVideoElement,
 }
 
--- a/servo/components/script/dom/htmlserializer.rs
+++ b/servo/components/script/dom/htmlserializer.rs
@@ -151,16 +151,16 @@ fn serialize_attr(attr: JSRef<Attr>, htm
     escape(attr.value().as_slice(), true, html);
     html.push('"');
 }
 
 fn escape(string: &str, attr_mode: bool, html: &mut String) {
     for c in string.chars() {
         match c {
             '&' => html.push_str("&amp;"),
-            '\u00A0' => html.push_str("&nbsp;"),
+            '\u{A0}' => html.push_str("&nbsp;"),
             '"' if attr_mode => html.push_str("&quot;"),
             '<' if !attr_mode => html.push_str("&lt;"),
             '>' if !attr_mode => html.push_str("&gt;"),
             c => html.push(c),
         }
     }
 }
--- a/servo/components/script/dom/htmltablecellelement.rs
+++ b/servo/components/script/dom/htmltablecellelement.rs
@@ -11,17 +11,17 @@ use dom::element::ElementTypeId;
 use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
 use dom::node::NodeTypeId;
 use dom::virtualmethods::VirtualMethods;
 
 use cssparser::RGBA;
 use servo_util::str::{mod, DOMString, LengthOrPercentageOrAuto};
 use std::cell::Cell;
 
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 #[jstraceable]
 pub enum HTMLTableCellElementTypeId {
     HTMLTableDataCellElement,
     HTMLTableHeaderCellElement,
 }
 
 #[dom_struct]
 pub struct HTMLTableCellElement {
--- a/servo/components/script/dom/node.rs
+++ b/servo/components/script/dom/node.rs
@@ -54,17 +54,17 @@ use js::jsapi::{JSContext, JSObject, JST
 use js::jsfriendapi;
 use libc;
 use libc::{uintptr_t, c_void};
 use std::cell::{Cell, RefCell, Ref, RefMut};
 use std::default::Default;
 use std::iter::{FilterMap, Peekable};
 use std::mem;
 use style::{mod, ComputedValues};
-use sync::Arc;
+use std::sync::Arc;
 use uuid;
 use string_cache::QualName;
 
 //
 // The basic Node structure
 //
 
 /// An HTML node.
@@ -116,16 +116,17 @@ impl NodeDerived for EventTarget {
             _ => false
         }
     }
 }
 
 bitflags! {
     #[doc = "Flags for node items."]
     #[jstraceable]
+    #[deriving(Copy)]
     flags NodeFlags: u16 {
         #[doc = "Specifies whether this node is in a document."]
         const IS_IN_DOC = 0x01,
         #[doc = "Specifies whether this node is in hover state."]
         const IN_HOVER_STATE = 0x02,
         #[doc = "Specifies whether this node is in disabled state."]
         const IN_DISABLED_STATE = 0x04,
         #[doc = "Specifies whether this node is in enabled state."]
@@ -175,16 +176,17 @@ impl Drop for Node {
             self.reap_layout_data();
         }
     }
 }
 
 /// suppress observers flag
 /// http://dom.spec.whatwg.org/#concept-node-insert
 /// http://dom.spec.whatwg.org/#concept-node-remove
+#[deriving(Copy)]
 enum SuppressObserver {
     Suppressed,
     Unsuppressed
 }
 
 /// Layout data that is shared between the script and layout tasks.
 pub struct SharedLayoutData {
     /// The results of CSS styling for this node.
@@ -247,17 +249,17 @@ impl LayoutDataRef {
     /// on it. This has already resulted in one bug!
     #[inline]
     pub fn borrow_mut<'a>(&'a self) -> RefMut<'a,Option<LayoutData>> {
         self.data_cell.borrow_mut()
     }
 }
 
 /// The different types of nodes.
-#[deriving(PartialEq, Show)]
+#[deriving(Copy, PartialEq, Show)]
 #[jstraceable]
 pub enum NodeTypeId {
     DocumentType,
     DocumentFragment,
     Comment,
     Document,
     Element(ElementTypeId),
     Text,
@@ -1141,17 +1143,17 @@ impl<'a> Iterator<JSRef<'a, Node>> for N
                 }
             }
         };
         self.current_node.map(|node| (*node.root()).clone())
     }
 }
 
 /// Specifies whether children must be recursively cloned or not.
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 pub enum CloneChildrenFlag {
     CloneChildren,
     DoNotCloneChildren
 }
 
 fn as_uintptr<T>(t: &T) -> uintptr_t { t as *const T as uintptr_t }
 
 impl Node {
@@ -2170,17 +2172,17 @@ impl<'a> NodeMethods for JSRef<'a, Node>
 }
 
 
 
 /// The address of a node known to be valid. These are sent from script to layout,
 /// and are also used in the HTML parser interface.
 
 #[allow(raw_pointer_deriving)]
-#[deriving(Clone, PartialEq, Eq)]
+#[deriving(Clone, PartialEq, Eq, Copy)]
 pub struct TrustedNodeAddress(pub *const c_void);
 
 pub fn document_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary<Document> {
     let node: JSRef<Node> = NodeCast::from_ref(derived);
     node.owner_doc()
 }
 
 pub fn window_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary<Window> {
@@ -2279,17 +2281,17 @@ impl<'a> style::TNode<'a, JSRef<'a, Elem
             }
         };
         match attr.namespace {
             style::NamespaceConstraint::Specific(ref ns) => {
                 self.as_element().get_attribute(ns.clone(), name).root()
                     .map_or(false, |attr| test(attr.r().value().as_slice()))
             },
             style::NamespaceConstraint::Any => {
-                self.as_element().get_attributes(name).iter()
+                self.as_element().get_attributes(name).into_iter()
                     .map(|attr| attr.root())
                     .any(|attr| test(attr.r().value().as_slice()))
             }
         }
     }
 
     fn is_html_element_in_html_document(self) -> bool {
         self.as_element().html_element_in_html_document()
@@ -2352,16 +2354,16 @@ impl<'a> DisabledStateHelpers for JSRef<
         let elem: JSRef<'a, Element> = ElementCast::to_ref(self).unwrap();
         let has_disabled_attrib = elem.has_attribute(&atom!("disabled"));
         self.set_disabled_state(has_disabled_attrib);
         self.set_enabled_state(!has_disabled_attrib);
     }
 }
 
 /// A summary of the changes that happened to a node.
-#[deriving(Clone, PartialEq)]
+#[deriving(Copy, Clone, PartialEq)]
 pub enum NodeDamage {
     /// The node's `style` attribute changed.
     NodeStyleDamaged,
     /// Other parts of a node changed; attributes, text content, etc.
     OtherNodeDamage,
 }
 
--- a/servo/components/script/dom/treewalker.rs
+++ b/servo/components/script/dom/treewalker.rs
@@ -251,19 +251,19 @@ impl<'a> PrivateTreeWalkerHelpers<'a> fo
                     _ => {}
                 }
                 // "4. Set sibling to node's first child if type is next,
                 //     and node's last child if type is previous."
                 sibling_op = next_child(node);
                 // "5. If result is FILTER_REJECT or sibling is null,
                 //     then set sibling to node's next sibling if type is next,
                 //     and node's previous sibling if type is previous."
-                match (result, sibling_op) {
+                match (result, &sibling_op) {
                     (Ok(NodeFilterConstants::FILTER_REJECT), _)
-                    | (_, None) => sibling_op = next_sibling(node),
+                    | (_, &None) => sibling_op = next_sibling(node),
                     _ => {}
                 }
             }
             // "3. Set node to its parent."
             match node.parent_node().map(|p| p.root().clone()) {
                 // "4. If node is null or is root, return null."
                 None => return Ok(None),
                 Some(n) if self.is_root_node(n) => return Ok(None),
--- a/servo/components/script/dom/window.rs
+++ b/servo/components/script/dom/window.rs
@@ -109,17 +109,17 @@ impl Window {
 }
 
 // http://www.whatwg.org/html/#atob
 pub fn base64_btoa(btoa: DOMString) -> Fallible<DOMString> {
     let input = btoa.as_slice();
     // "The btoa() method must throw an InvalidCharacterError exception if
     //  the method's first argument contains any character whose code point
     //  is greater than U+00FF."
-    if input.chars().any(|c: char| c > '\u00FF') {
+    if input.chars().any(|c: char| c > '\u{FF}') {
         Err(InvalidCharacter)
     } else {
         // "Otherwise, the user agent must convert that argument to a
         //  sequence of octets whose nth octet is the eight-bit
         //  representation of the code point of the nth character of
         //  the argument,"
         let octets = input.chars().map(|c: char| c as u8).collect::<Vec<u8>>();
 
--- a/servo/components/script/dom/workerglobalscope.rs
+++ b/servo/components/script/dom/workerglobalscope.rs
@@ -25,17 +25,17 @@ use servo_util::str::DOMString;
 use js::jsapi::JSContext;
 use js::jsval::JSVal;
 use js::rust::Cx;
 
 use std::default::Default;
 use std::rc::Rc;
 use url::{Url, UrlParser};
 
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 #[jstraceable]
 pub enum WorkerGlobalScopeTypeId {
     DedicatedGlobalScope,
 }
 
 #[dom_struct]
 pub struct WorkerGlobalScope {
     eventtarget: EventTarget,
--- a/servo/components/script/dom/xmlhttprequest.rs
+++ b/servo/components/script/dom/xmlhttprequest.rs
@@ -58,17 +58,17 @@ use std::str::FromStr;
 use std::time::duration::Duration;
 use time;
 use url::{Url, UrlParser};
 
 use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams;
 use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eString, eURLSearchParams};
 pub type SendParam = StringOrURLSearchParams;
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Copy)]
 #[jstraceable]
 enum XMLHttpRequestState {
     Unsent = 0,
     Opened = 1,
     HeadersReceived = 2,
     Loading = 3,
     XHRDone = 4, // So as not to conflict with the ProgressMsg `Done`
 }
@@ -85,17 +85,17 @@ impl XHRProgressHandler {
 }
 
 impl Runnable for XHRProgressHandler {
     fn handler(&self) {
         XMLHttpRequest::handle_progress(self.addr.clone(), self.progress.clone());
     }
 }
 
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Clone, Copy)]
 #[jstraceable]
 pub struct GenerationId(uint);
 
 #[deriving(Clone)]
 pub enum XHRProgress {
     /// Notify that headers have been received
     HeadersReceived(GenerationId, Option<Headers>, Option<RawStatus>),
     /// Partial progress (after receiving headers), containing portion of the response
@@ -555,20 +555,20 @@ impl<'a> XMLHttpRequestMethods for JSRef
             let ref mut request_headers = self.request_headers.borrow_mut();
             if !request_headers.has::<ContentType>() {
                 // XHR spec differs from http, and says UTF-8 should be in capitals,
                 // instead of "utf-8", which is what Hyper defaults to.
                 let params = ";charset=UTF-8";
                 let n = "content-type";
                 match data {
                     Some(eString(_)) =>
-                        request_headers.set_raw(n, vec![join_raw("text/plain", params)]),
+                        request_headers.set_raw(n.into_string(), vec![join_raw("text/plain", params)]),
                     Some(eURLSearchParams(_)) =>
                         request_headers.set_raw(
-                            n, vec![join_raw("application/x-www-form-urlencoded", params)]),
+                            n.into_string(), vec![join_raw("application/x-www-form-urlencoded", params)]),
                     None => ()
                 }
             }
 
 
             if !request_headers.has::<Accept>() {
                 request_headers.set(
                     Accept(vec![Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![])]));
@@ -808,17 +808,17 @@ impl<'a> PrivateXMLHttpRequestHelpers fo
                     self.dispatch_upload_progress_event("loadend".into_string(), None);
                     return_if_fetch_was_terminated!();
                 }
                 // Part of step 13, send() (processing response)
                 // XXXManishearth handle errors, if any (substep 1)
                 // Substep 2
                 status.map(|RawStatus(code, reason)| {
                     self.status.set(code);
-                    *self.status_text.borrow_mut() = ByteString::new(format!("{}", reason).into_bytes());
+                    *self.status_text.borrow_mut() = ByteString::new(reason.into_bytes());
                 });
                 headers.as_ref().map(|h| *self.response_headers.borrow_mut() = h.clone());
 
                 // Substep 3
                 if !self.sync.get() {
                     self.change_ready_state(XMLHttpRequestState::HeadersReceived);
                 }
             },
--- a/servo/components/script/dom/xmlhttprequesteventtarget.rs
+++ b/servo/components/script/dom/xmlhttprequesteventtarget.rs
@@ -4,17 +4,17 @@
 
 use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
 use dom::bindings::codegen::Bindings::XMLHttpRequestEventTargetBinding::XMLHttpRequestEventTargetMethods;
 use dom::bindings::codegen::InheritTypes::EventTargetCast;
 use dom::bindings::codegen::InheritTypes::XMLHttpRequestEventTargetDerived;
 use dom::bindings::js::JSRef;
 use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
 
-#[deriving(PartialEq)]
+#[deriving(Copy, PartialEq)]
 #[jstraceable]
 pub enum XMLHttpRequestEventTargetTypeId {
     XMLHttpRequest,
     XMLHttpRequestUpload,
 }
 
 #[dom_struct]
 pub struct XMLHttpRequestEventTarget {
--- a/servo/components/script/lib.rs
+++ b/servo/components/script/lib.rs
@@ -29,17 +29,16 @@ extern crate serialize;
 extern crate time;
 extern crate canvas;
 extern crate script_traits;
 #[phase(plugin)]
 extern crate "plugins" as servo_plugins;
 extern crate "net" as servo_net;
 extern crate "util" as servo_util;
 extern crate style;
-extern crate sync;
 extern crate "msg" as servo_msg;
 extern crate url;
 extern crate uuid;
 extern crate string_cache;
 #[phase(plugin)]
 extern crate string_cache_macros;
 
 pub mod cors;
--- a/servo/components/script/parse/html.rs
+++ b/servo/components/script/parse/html.rs
@@ -20,17 +20,17 @@ use parse::Parser;
 
 use encoding::all::UTF_8;
 use encoding::types::{Encoding, DecoderTrap};
 
 use servo_net::resource_task::{ProgressMsg, LoadResponse};
 use servo_util::task_state;
 use servo_util::task_state::IN_HTML_PARSER;
 use std::ascii::AsciiExt;
-use std::str::MaybeOwned;
+use std::str::CowString;
 use url::Url;
 use html5ever::Attribute;
 use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText, AppendNode, AppendText};
 use string_cache::QualName;
 
 pub enum HTMLInput {
     InputString(String),
     InputUrl(LoadResponse),
@@ -105,17 +105,17 @@ impl<'a> TreeSink<TrustedNodeAddress> fo
             None => return Err(new_node),
         };
 
         let child = self.get_or_create(new_node).root();
         assert!(parent.r().InsertBefore(child.r(), Some(sibling.r())).is_ok());
         Ok(())
     }
 
-    fn parse_error(&mut self, msg: MaybeOwned<'static>) {
+    fn parse_error(&mut self, msg: CowString<'static>) {
         debug!("Parse error: {}", msg);
     }
 
     fn set_quirks_mode(&mut self, mode: QuirksMode) {
         let doc = self.document.root();
         doc.r().set_quirks_mode(mode);
     }
 
--- a/servo/components/script/script_task.rs
+++ b/servo/components/script/script_task.rs
@@ -9,17 +9,18 @@ use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
 use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
 use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
 use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
 use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, NodeCast, EventCast};
 use dom::bindings::conversions::FromJSValConvertible;
 use dom::bindings::conversions::StringificationBehavior;
 use dom::bindings::global::GlobalRef;
-use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalRootable};
+use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
+use dom::bindings::js::{RootCollection, RootCollectionPtr};
 use dom::bindings::refcounted::LiveDOMReferences;
 use dom::bindings::trace::JSTraceable;
 use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap};
 use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentSource};
 use dom::element::{Element, ElementTypeId, ActivationElementHelpers};
 use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
 use dom::uievent::UIEvent;
 use dom::eventtarget::{EventTarget, EventTargetHelpers};
@@ -71,25 +72,27 @@ use js::jsapi::{JS_SetGCParameter, JSGC_
 use js::jsapi::{JS_SetGCCallback, JSGCStatus, JSGC_BEGIN, JSGC_END};
 use js::rust::{Cx, RtUtils};
 use js;
 use url::Url;
 
 use libc;
 use libc::size_t;
 use std::any::{Any, AnyRefExt};
+use std::cell::Cell;
 use std::comm::{channel, Sender, Receiver, Select};
 use std::fmt::{mod, Show};
 use std::mem::replace;
 use std::rc::Rc;
 use std::u32;
 use time::{Tm, strptime};
 
-local_data_key!(pub StackRoots: *const RootCollection)
+thread_local!(pub static StackRoots: Cell<Option<RootCollectionPtr>> = Cell::new(None))
 
+#[deriving(Copy)]
 pub enum TimerSource {
     FromWindow(PipelineId),
     FromWorker
 }
 
 pub trait Runnable {
     fn handler(&self);
 }
@@ -153,24 +156,26 @@ impl NonWorkerScriptChan {
         (port, box NonWorkerScriptChan(chan))
     }
 }
 
 pub struct StackRootTLS;
 
 impl StackRootTLS {
     pub fn new(roots: &RootCollection) -> StackRootTLS {
-        StackRoots.replace(Some(roots as *const RootCollection));
+        StackRoots.with(|ref r| {
+            r.set(Some(RootCollectionPtr(roots as *const _)))
+        });
         StackRootTLS
     }
 }
 
 impl Drop for StackRootTLS {
     fn drop(&mut self) {
-        let _ = StackRoots.replace(None);
+        StackRoots.with(|ref r| r.set(None));
     }
 }
 
 /// Information for an entire page. Pages are top-level browsing contexts and can contain multiple
 /// frames.
 ///
 /// FIXME: Rename to `Page`, following WebKit?
 pub struct ScriptTask {
--- a/servo/components/script/tests.rs
+++ b/servo/components/script/tests.rs
@@ -33,16 +33,16 @@ macro_rules! sizeof_checker (
                         avoids this increase. If you feel that the increase is necessary, \
                         update to the new size in script/tests.rs.",
                         stringify!($t), old, new)
         }
     });
 )
 
 // Update the sizes here
-sizeof_checker!(size_event_target, EventTarget, 56)
-sizeof_checker!(size_node, Node, 304)
-sizeof_checker!(size_element, Element, 448)
-sizeof_checker!(size_htmlelement, HTMLElement, 480)
-sizeof_checker!(size_div, HTMLDivElement, 480)
-sizeof_checker!(size_span, HTMLSpanElement, 480)
-sizeof_checker!(size_text, Text, 336)
-sizeof_checker!(size_characterdata, CharacterData, 336)
+sizeof_checker!(size_event_target, EventTarget, 48)
+sizeof_checker!(size_node, Node, 288)
+sizeof_checker!(size_element, Element, 432)
+sizeof_checker!(size_htmlelement, HTMLElement, 464)
+sizeof_checker!(size_div, HTMLDivElement, 464)
+sizeof_checker!(size_span, HTMLSpanElement, 464)
+sizeof_checker!(size_text, Text, 320)
+sizeof_checker!(size_characterdata, CharacterData, 320)
--- a/servo/components/script/textinput.rs
+++ b/servo/components/script/textinput.rs
@@ -9,16 +9,17 @@ use dom::bindings::js::JSRef;
 use dom::keyboardevent::KeyboardEvent;
 use servo_util::str::DOMString;
 
 use std::cmp::{min, max};
 use std::default::Default;
 use std::num::SignedInt;
 
 #[jstraceable]
+#[deriving(Copy)]
 struct TextPoint {
     /// 0-based line number
     line: uint,
     /// 0-based column number
     index: uint,
 }
 
 /// Encapsulated state for handling keyboard input in a single or multiline text input control.
--- a/servo/components/script/timers.rs
+++ b/servo/components/script/timers.rs
@@ -20,16 +20,17 @@ use std::collections::HashMap;
 use std::comm::{channel, Sender};
 use std::comm::Select;
 use std::hash::{Hash, sip};
 use std::io::timer::Timer;
 use std::time::duration::Duration;
 
 #[deriving(PartialEq, Eq)]
 #[jstraceable]
+#[deriving(Copy)]
 pub struct TimerId(i32);
 
 #[jstraceable]
 #[privatize]
 struct TimerHandle {
     handle: TimerId,
     data: TimerData,
     cancel_chan: Option<Sender<()>>,
@@ -62,17 +63,17 @@ impl Drop for TimerManager {
         for (_, timer_handle) in self.active_timers.borrow_mut().iter_mut() {
             timer_handle.cancel();
         }
     }
 }
 
 // Enum allowing more descriptive values for the is_interval field
 #[jstraceable]
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Copy, Clone)]
 pub enum IsInterval {
     Interval,
     NonInterval,
 }
 
 // Holder for the various JS values associated with setTimeout
 // (ie. function value to invoke and all arguments to pass
 //      to the function when calling it)
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -6,32 +6,32 @@ dependencies = [
  "gfx 0.0.1",
  "glfw_app 0.0.1",
  "glutin_app 0.0.1",
  "layout 0.0.1",
  "msg 0.0.1",
  "net 0.0.1",
  "script 0.0.1",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "android_glue"
 version = "0.0.1"
-source = "git+https://github.com/servo/android-rs-glue?ref=servo#de9f604bfc71e07f4e968d5dd393de5442dbb2c8"
+source = "git+https://github.com/servo/android-rs-glue?ref=servo#122bc28545b5e59a923c466a484c403fa691bd55"
 dependencies = [
  "compile_msg 0.1.1 (git+https://github.com/huonw/compile_msg)",
 ]
 
 [[package]]
 name = "azure"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-azure#fe95551ca22f2a75b0dd690a72841df39b33885d"
+source = "git+https://github.com/servo/rust-azure#6884d442052becfcafccc82b17ab316c7831d8d2"
 dependencies = [
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
  "core_text 0.1.0 (git+https://github.com/servo/rust-core-text)",
  "egl 0.1.0 (git+https://github.com/servo/rust-egl)",
  "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
@@ -80,59 +80,59 @@ dependencies = [
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "layout_traits 0.0.1",
  "msg 0.0.1",
  "net 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
  "script_traits 0.0.1",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "cookie"
-version = "0.0.1"
-source = "git+https://github.com/servo/cookie-rs#f82090b19c2738b90528167ef873d8eac0353294"
+version = "0.1.0"
+source = "git+https://github.com/alexcrichton/cookie-rs#8d1b4bb8d5ed06e58c162eb235a4ccd210b68108"
 dependencies = [
- "openssl 0.0.2 (git+https://github.com/servo/rust-openssl)",
+ "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
 ]
 
 [[package]]
 name = "core_foundation"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-core-foundation#d2dbe4fb6f6892521a37735cd7a97098d1b64808"
+source = "git+https://github.com/servo/rust-core-foundation#81db9ab15f67e16d7a3e9705a06cad65192014fd"
 
 [[package]]
 name = "core_graphics"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-core-graphics#9434e2bda65d259f825104170b5fa6cc6dbaf5a9"
 dependencies = [
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
 ]
 
 [[package]]
 name = "core_text"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-core-text#85784007b6fa1b8f9614059edcd0429b2bd69a11"
+source = "git+https://github.com/servo/rust-core-text#cb369a26a0eb4e83c2128ceb3c685a191113417a"
 dependencies = [
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
 ]
 
 [[package]]
 name = "cssparser"
-version = "0.1.0"
-source = "git+https://github.com/servo/rust-cssparser#a2b0b6b00ad84dc3a4b4faf77ddd63611c8ce58a"
+version = "0.1.1"
+source = "git+https://github.com/servo/rust-cssparser#110bf3052d016bf6eda0689fb21cf971e2c23dc8"
 dependencies = [
- "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)",
- "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "devtools"
 version = "0.0.1"
 dependencies = [
  "devtools_traits 0.0.1",
  "msg 0.0.1",
@@ -148,70 +148,70 @@ dependencies = [
 
 [[package]]
 name = "egl"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220"
 
 [[package]]
 name = "encoding"
-version = "0.2.3"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "encoding-index-japanese 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
- "encoding-index-korean 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
- "encoding-index-simpchinese 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
- "encoding-index-singlebyte 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
- "encoding-index-tradchinese 1.0.20140915 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding-index-japanese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding-index-korean 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding-index-simpchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding-index-singlebyte 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)",
+ "encoding-index-tradchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding-index-japanese"
 version = "1.0.20140915"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "encoding_index_tests 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding-index-korean"
 version = "1.0.20140915"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "encoding_index_tests 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding-index-simpchinese"
 version = "1.0.20140915"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "encoding_index_tests 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding-index-singlebyte"
 version = "1.0.20140915"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "encoding_index_tests 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding-index-tradchinese"
 version = "1.0.20140915"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "encoding_index_tests 0.1.0 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding_index_tests"
 version = "0.1.0"
-source = "git+https://github.com/lifthrasiir/rust-encoding#15ac0ded3ca592c31ded5b9ff6f9fe2fa4b73fc4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "expat-sys"
 version = "2.1.0"
 source = "git+https://github.com/servo/libexpat#da2ddaf78cbef836b8790807bb76b357c58df3a1"
 
 [[package]]
 name = "fontconfig"
@@ -241,19 +241,24 @@ version = "2.4.11"
 source = "git+https://github.com/servo/libfreetype2#f5c49c0da1d5bc6b206c4176344012ac37524243"
 
 [[package]]
 name = "gcc"
 version = "0.0.2"
 source = "git+https://github.com/alexcrichton/gcc-rs#903e8f8a2e3766ad3d514404d452dbaa1d3b2d79"
 
 [[package]]
+name = "gcc"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "geom"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-geom#0f77c6ad116748b7e6bedbf2414d4ceea17debc2"
+source = "git+https://github.com/servo/rust-geom#05f2d5494355adc78ad7d17286912f0d128f503b"
 
 [[package]]
 name = "gfx"
 version = "0.0.1"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
@@ -266,50 +271,50 @@ dependencies = [
  "msg 0.0.1",
  "net 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
  "script_traits 0.0.1",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "style 0.0.1",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "gl_common"
 version = "0.0.1"
-source = "git+https://github.com/bjz/gl-rs.git#c76c23fc9a0dae824b45550d4b823cdb726f242d"
+source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e"
 
 [[package]]
 name = "gl_generator"
 version = "0.0.1"
-source = "git+https://github.com/bjz/gl-rs.git#c76c23fc9a0dae824b45550d4b823cdb726f242d"
+source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e"
 dependencies = [
  "gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)",
  "khronos_api 0.0.2 (git+https://github.com/bjz/gl-rs.git)",
- "rust-xml 0.1.2-pre (git+https://github.com/netvl/rust-xml)",
+ "xml-rs 0.1.3 (git+https://github.com/netvl/xml-rs)",
 ]
 
 [[package]]
 name = "gleam"
 version = "0.0.1"
 source = "git+https://github.com/servo/gleam#c54eb9ad6d4b62b7effbe9c79a1b3720845b45b4"
 dependencies = [
  "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)",
 ]
 
 [[package]]
 name = "glfw"
 version = "0.0.1"
-source = "git+https://github.com/servo/glfw-rs?ref=servo#1b05fdc7eab45e1d462758ab991065ee78593b7f"
+source = "git+https://github.com/servo/glfw-rs?ref=servo#b186cb444e349a36b992445dc5cb2c99d38f2a42"
 dependencies = [
  "glfw-sys 3.0.4 (git+https://github.com/servo/glfw?ref=cargo-3.0.4)",
- "semver 0.1.3 (git+https://github.com/rust-lang/semver)",
+ "semver 0.1.4 (git+https://github.com/rust-lang/semver)",
 ]
 
 [[package]]
 name = "glfw-sys"
 version = "3.0.4"
 source = "git+https://github.com/servo/glfw?ref=cargo-3.0.4#765dace7e4125b87c764f5ac0e7a80eae5c550b2"
 
 [[package]]
@@ -366,100 +371,101 @@ dependencies = [
 [[package]]
 name = "harfbuzz"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-harfbuzz#8aab215463214647b7a81f66011da552bbb1121c"
 
 [[package]]
 name = "html5ever"
 version = "0.0.0"
-source = "git+https://github.com/servo/html5ever#e6f8d83de9fffe63a825d95d957ba6bcbc3e1632"
+source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3"
 dependencies = [
  "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)",
- "phf 0.0.0 (git+https://github.com/sfackler/rust-phf)",
- "phf_mac 0.0.0 (git+https://github.com/sfackler/rust-phf)",
+ "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)",
+ "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
 ]
 
 [[package]]
 name = "html5ever_macros"
 version = "0.0.0"
-source = "git+https://github.com/servo/html5ever#e6f8d83de9fffe63a825d95d957ba6bcbc3e1632"
+source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3"
 
 [[package]]
 name = "hyper"
 version = "0.0.1"
-source = "git+https://github.com/servo/hyper?ref=servo#4a2c82c75013f8ee55d2017876319b48d656dcb3"
+source = "git+https://github.com/servo/hyper?ref=servo#43becc919c24939b8b84fe541b0e0898a4827836"
 dependencies = [
- "cookie 0.0.1 (git+https://github.com/servo/cookie-rs)",
+ "cookie 0.1.0 (git+https://github.com/alexcrichton/cookie-rs)",
  "mime 0.0.1 (git+https://github.com/hyperium/mime.rs)",
- "openssl 0.0.2 (git+https://github.com/servo/rust-openssl)",
+ "mucell 0.1.2 (git+https://github.com/chris-morgan/mucell)",
+ "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "unsafe-any 0.1.0 (git+https://github.com/reem/rust-unsafe-any)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "unsafe-any 0.1.1 (git+https://github.com/reem/rust-unsafe-any)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
 ]
 
 [[package]]
 name = "io_surface"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-io-surface#691cbccc320c4fb9b75e215da9b0b82539d729bd"
 dependencies = [
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
 ]
 
 [[package]]
 name = "js"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-mozjs#2d86d6fb7ece49ff2f469c391e15e13f2b02af42"
+source = "git+https://github.com/servo/rust-mozjs#e01a846241bd98ac424878e3f8d3e9b989c79242"
 dependencies = [
  "mozjs-sys 0.0.0 (git+https://github.com/servo/mozjs)",
 ]
 
 [[package]]
 name = "khronos_api"
 version = "0.0.2"
-source = "git+https://github.com/bjz/gl-rs.git#c76c23fc9a0dae824b45550d4b823cdb726f242d"
+source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e"
 
 [[package]]
 name = "layers"
 version = "0.1.0"
-source = "git+https://github.com/servo/rust-layers#21798aac4de6bfd800836f419dd5b6a308edcaa4"
+source = "git+https://github.com/servo/rust-layers#574df7e1c1dd464af930d1cc735ca8d6af46bb90"
 dependencies = [
  "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "egl 0.1.0 (git+https://github.com/servo/rust-egl)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "glx 0.0.1 (git+https://github.com/servo/rust-glx)",
  "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
  "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)",
 ]
 
 [[package]]
 name = "layout"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
- "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)",
+ "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gfx 0.0.1",
  "layout_traits 0.0.1",
  "net 0.0.1",
  "plugins 0.0.1",
  "script 0.0.1",
  "script_traits 0.0.1",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "layout_traits"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
@@ -467,17 +473,17 @@ dependencies = [
  "net 0.0.1",
  "script_traits 0.0.1",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "lazy_static"
 version = "0.1.0"
-source = "git+https://github.com/Kimundi/lazy-static.rs#62976cb611c5396e11315ae64c9c389576240eb7"
+source = "git+https://github.com/Kimundi/lazy-static.rs#76f06e4fa7bc8c92f11d1def19bd4ddfd8017cd8"
 
 [[package]]
 name = "libressl-pnacl-sys"
 version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "pnacl-build-helper 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -498,65 +504,70 @@ version = "0.0.1"
 dependencies = [
  "azure 0.1.0 (git+https://github.com/servo/rust-azure)",
  "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)",
  "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "style 0.0.1",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
+name = "mucell"
+version = "0.1.2"
+source = "git+https://github.com/chris-morgan/mucell#d198c6605b3e688719db168db0939051c803b1ea"
+
+[[package]]
 name = "net"
 version = "0.0.1"
 dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "openssl"
-version = "0.0.2"
-source = "git+https://github.com/servo/rust-openssl#aed5df1036d6f4b5f7b8be6457d10f8a0379b39f"
+version = "0.2.4"
+source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe"
 dependencies = [
- "libressl-pnacl-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.0.2 (git+https://github.com/servo/rust-openssl)",
+ "openssl-sys 0.2.4 (git+https://github.com/sfackler/rust-openssl)",
 ]
 
 [[package]]
 name = "openssl-sys"
-version = "0.0.2"
-source = "git+https://github.com/servo/rust-openssl#aed5df1036d6f4b5f7b8be6457d10f8a0379b39f"
+version = "0.2.4"
+source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe"
 dependencies = [
+ "libressl-pnacl-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "phf"
-version = "0.0.0"
-source = "git+https://github.com/sfackler/rust-phf#aa3e2d0aedea4d55c2e4cea1bdf6e89418dc1206"
+version = "0.0.1"
+source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4"
 dependencies = [
- "xxhash 0.0.1 (git+https://github.com/Jurily/rust-xxhash)",
+ "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "phf_mac"
-version = "0.0.0"
-source = "git+https://github.com/sfackler/rust-phf#aa3e2d0aedea4d55c2e4cea1bdf6e89418dc1206"
+version = "0.0.1"
+source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4"
 dependencies = [
- "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "xxhash 0.0.1 (git+https://github.com/Jurily/rust-xxhash)",
+ "time 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pkg-config"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -577,62 +588,57 @@ dependencies = [
 ]
 
 [[package]]
 name = "png-sys"
 version = "1.6.3"
 source = "git+https://github.com/servo/libpng?ref=servo#d01f32b4eb86904695efe7fc02b574f902e21a98"
 
 [[package]]
-name = "rust-xml"
-version = "0.1.2-pre"
-source = "git+https://github.com/netvl/rust-xml#2d9df3267aeaa4d442e1e19a4dfed733cb1397ed"
-
-[[package]]
 name = "script"
 version = "0.0.1"
 dependencies = [
  "canvas 0.0.1",
- "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
+ "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)",
  "devtools_traits 0.0.1",
- "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gfx 0.0.1",
  "html5ever 0.0.0 (git+https://github.com/servo/html5ever)",
  "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)",
  "js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
  "msg 0.0.1",
  "net 0.0.1",
  "plugins 0.0.1",
  "script_traits 0.0.1",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
- "uuid 0.0.2 (git+https://github.com/rust-lang/uuid)",
+ "uuid 0.1.1 (git+https://github.com/rust-lang/uuid)",
 ]
 
 [[package]]
 name = "script_traits"
 version = "0.0.1"
 dependencies = [
  "devtools_traits 0.0.1",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "msg 0.0.1",
  "net 0.0.1",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "semver"
-version = "0.1.3"
-source = "git+https://github.com/rust-lang/semver#29212953f839337c672d185dde74e14b5dfb1f46"
+version = "0.1.4"
+source = "git+https://github.com/rust-lang/semver#58dc6b1999d345ca925a2f12a6a84676e823e179"
 
 [[package]]
 name = "skia-sys"
 version = "0.0.20130412"
 source = "git+https://github.com/servo/skia?ref=upstream-2014-06-16#35649d0cddfd89c0bfee0ff558da7291e26d30c3"
 dependencies = [
  "expat-sys 2.1.0 (git+https://github.com/servo/libexpat)",
  "freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)",
@@ -641,104 +647,117 @@ dependencies = [
 [[package]]
 name = "stb_image"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-stb-image#97d7e440e80e41a304647363c322eab68e3700aa"
 
 [[package]]
 name = "string_cache"
 version = "0.0.0"
-source = "git+https://github.com/servo/string-cache#a18a432fd274e816fc41876536f70e5380abb677"
+source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f"
 dependencies = [
  "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)",
- "phf 0.0.0 (git+https://github.com/sfackler/rust-phf)",
- "phf_mac 0.0.0 (git+https://github.com/sfackler/rust-phf)",
+ "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)",
+ "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)",
  "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
- "xxhash 0.0.1 (git+https://github.com/Jurily/rust-xxhash)",
+ "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "string_cache_macros"
 version = "0.0.0"
-source = "git+https://github.com/servo/string-cache#a18a432fd274e816fc41876536f70e5380abb677"
+source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f"
 dependencies = [
  "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)",
 ]
 
 [[package]]
 name = "style"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
- "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)",
+ "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)",
+ "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)",
  "plugins 0.0.1",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
- "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "task_info"
 version = "0.0.1"
 
 [[package]]
 name = "text_writer"
-version = "0.1.2"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "time"
 version = "0.1.0"
 source = "git+https://github.com/rust-lang/time#afab521f3b91658a3ba2d3e877b7e01699733bef"
 dependencies = [
  "gcc 0.0.2 (git+https://github.com/alexcrichton/gcc-rs)",
 ]
 
 [[package]]
+name = "time"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "unsafe-any"
-version = "0.1.0"
-source = "git+https://github.com/reem/rust-unsafe-any#2863af363bbd83079b6773920bba5b736408db33"
+version = "0.1.1"
+source = "git+https://github.com/reem/rust-unsafe-any#eb3fe87bea85f375b8fcefa0cdecfd131fae9624"
 
 [[package]]
 name = "url"
-version = "0.1.0"
-source = "git+https://github.com/servo/rust-url#46458f80e48c542b2f175e36e5b7d30782ca7dc5"
+version = "0.2.4"
+source = "git+https://github.com/servo/rust-url#79f8034a8e1815ffa1f49204572ddbf6eb747c75"
 
 [[package]]
 name = "util"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
+ "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "plugins 0.0.1",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
  "task_info 0.0.1",
- "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.0 (git+https://github.com/rust-lang/time)",
- "url 0.1.0 (git+https://github.com/servo/rust-url)",
+ "url 0.2.4 (git+https://github.com/servo/rust-url)",
 ]
 
 [[package]]
 name = "uuid"
-version = "0.0.2"
-source = "git+https://github.com/rust-lang/uuid#f5d94d0043a615756edefaf9c6041f11e52b8370"
+version = "0.1.1"
+source = "git+https://github.com/rust-lang/uuid#fc793c974a25c126c5cf5daa3b18973512a7a6a0"
 
 [[package]]
 name = "winapi"
 version = "0.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "xlib"
 version = "0.1.0"
 source = "git+https://github.com/servo/rust-xlib#58ec3847b592aeabdcfeb6a2d02033d3a2c7f427"
 
 [[package]]
+name = "xml-rs"
+version = "0.1.3"
+source = "git+https://github.com/netvl/xml-rs#1a812d3ba720afd768bd75d29a5b5f10ddcdfbeb"
+
+[[package]]
 name = "xxhash"
-version = "0.0.1"
-source = "git+https://github.com/Jurily/rust-xxhash#64f8d02314735f511cb4272563d0f703d575c159"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 
--- a/servo/components/servo/lib.rs
+++ b/servo/components/servo/lib.rs
@@ -106,17 +106,17 @@ impl<Window> Browser<Window> where Windo
                                                           resource_task,
                                                           image_cache_task,
                                                           font_cache_task,
                                                           time_profiler_chan_clone,
                                                           devtools_chan,
                                                           storage_task);
 
             // Send the URL command to the constellation.
-            let cwd = os::getcwd();
+            let cwd = os::getcwd().unwrap();
             for url in opts.urls.iter() {
                 let url = match url::Url::parse(url.as_slice()) {
                     Ok(url) => url,
                     Err(url::ParseError::RelativeUrlWithoutBase)
                     => url::Url::from_file_path(&cwd.join(url.as_slice())).unwrap(),
                     Err(_) => panic!("URL parsing failed"),
                 };
 
--- a/servo/components/servo/main.rs
+++ b/servo/components/servo/main.rs
@@ -27,18 +27,19 @@ extern crate compositing;
 extern crate android_glue;
 
 #[cfg(target_os="android")]
 use libc::c_int;
 
 #[cfg(not(test))]
 use servo_util::opts;
 
-#[cfg(not(test))]
-use servo_util::rtinstrument;
+// FIXME: Find replacement for this post-runtime removal
+//#[cfg(not(test))]
+//use servo_util::rtinstrument;
 
 #[cfg(not(test))]
 use servo::Browser;
 #[cfg(not(test))]
 use compositing::windowing::WindowEvent;
 
 #[cfg(not(any(test,target_os="android")))]
 use std::os;
@@ -153,17 +154,17 @@ fn main() {
             }
         }
 
         let BrowserWrapper {
             browser
         } = browser;
         browser.shutdown();
 
-        rtinstrument::teardown();
+        //rtinstrument::teardown();
     }
 }
 
 impl app::NestedEventLoopListener for BrowserWrapper {
     fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool {
         let is_resize = match event {
             WindowEvent::Resize(..) => true,
             _ => false,
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -19,22 +19,20 @@ path = "../util"
 git = "https://github.com/servo/rust-geom"
 
 [dependencies.url]
 git = "https://github.com/servo/rust-url"
 
 [dependencies.cssparser]
 git = "https://github.com/servo/rust-cssparser"
 
-[dependencies.encoding]
-git = "https://github.com/lifthrasiir/rust-encoding"
-
 [dependencies.lazy_static]
 git = "https://github.com/Kimundi/lazy-static.rs"
 
 [dependencies.string_cache]
 git = "https://github.com/servo/string-cache"
 
 [dependencies.string_cache_macros]
 git = "https://github.com/servo/string-cache"
 
 [dependencies]
 text_writer = "0.1.1"
+encoding = "0.2"
--- a/servo/components/style/legacy.rs
+++ b/servo/components/style/legacy.rs
@@ -13,38 +13,42 @@ use properties::{CSSFloat, specified};
 use selector_matching::{DeclarationBlock, Stylist};
 
 use cssparser::Color;
 use servo_util::geometry::Au;
 use servo_util::smallvec::VecLike;
 use servo_util::str::LengthOrPercentageOrAuto;
 
 /// Legacy presentational attributes that take a length as defined in HTML5 § 2.4.4.4.
+#[deriving(Copy, PartialEq, Eq)]
 pub enum LengthAttribute {
     /// `<td width>`
     Width,
 }
 
 /// Legacy presentational attributes that take an integer as defined in HTML5 § 2.4.4.2.
+#[deriving(Copy, PartialEq, Eq)]
 pub enum IntegerAttribute {
     /// `<input size>`
     Size,
     Cols,
     Rows,
 }
 
 /// Legacy presentational attributes that take a nonnegative integer as defined in HTML5 § 2.4.4.2.
+#[deriving(Copy, PartialEq, Eq)]
 pub enum UnsignedIntegerAttribute {
     /// `<td border>`
     Border,
     /// `<td colspan>`
     ColSpan,
 }
 
 /// Legacy presentational attributes that take a simple color as defined in HTML5 § 2.4.6.
+#[deriving(Copy, PartialEq, Eq)]
 pub enum SimpleColorAttribute {
     /// `<body bgcolor>`
     BgColor,
 }
 
 /// Extension methods for `Stylist` that cause rules to be synthesized for legacy attributes.
 pub trait PresentationalHintSynthesis {
     /// Synthesizes rules from various HTML attributes (mostly legacy junk from HTML4) that confer
--- a/servo/components/style/lib.rs
+++ b/servo/components/style/lib.rs
@@ -9,17 +9,16 @@
 
 #![feature(phase)]
 #[phase(plugin, link)] extern crate log;
 #[phase(plugin)] extern crate string_cache_macros;
 
 extern crate collections;
 extern crate geom;
 extern crate serialize;
-extern crate sync;
 extern crate text_writer;
 extern crate url;
 
 extern crate cssparser;
 extern crate encoding;
 extern crate string_cache;
 
 #[phase(plugin)]
--- a/servo/components/style/media_queries.rs
+++ b/servo/components/style/media_queries.rs
@@ -22,37 +22,39 @@ pub struct MediaRule {
     pub media_queries: MediaQueryList,
     pub rules: Vec<CSSRule>,
 }
 
 pub struct MediaQueryList {
     media_queries: Vec<MediaQuery>
 }
 
+#[deriving(PartialEq, Eq, Copy)]
 pub enum Range<T> {
     Min(T),
     Max(T),
     //Eq(T),    // FIXME: Implement parsing support for equality then re-enable this.
 }
 
 impl<T: Ord> Range<T> {
     fn evaluate(&self, value: T) -> bool {
         match *self {
             Range::Min(ref width) => { value >= *width },
             Range::Max(ref width) => { value <= *width },
             //Range::Eq(ref width) => { value == *width },
         }
     }
 }
 
+#[deriving(PartialEq, Eq, Copy)]
 pub enum Expression {
     Width(Range<Au>),
 }
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Eq, Copy)]
 pub enum Qualifier {
     Only,
     Not,
 }
 
 pub struct MediaQuery {
     qualifier: Option<Qualifier>,
     media_type: MediaQueryType,
@@ -65,23 +67,23 @@ impl MediaQuery {
         MediaQuery {
             qualifier: qualifier,
             media_type: media_type,
             expressions: expressions,
         }
     }
 }
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Eq, Copy)]
 pub enum MediaQueryType {
     All,  // Always true
     MediaType(MediaType),
 }
 
-#[deriving(PartialEq)]
+#[deriving(PartialEq, Eq, Copy)]
 pub enum MediaType {
     Screen,
     Print,
     Unknown,
 }
 
 pub struct Device {
     pub media_type: MediaType,
--- a/servo/components/style/properties/common_types.rs
+++ b/servo/components/style/properties/common_types.rs
@@ -11,17 +11,17 @@ pub use servo_util::geometry::Au;
 
 
 macro_rules! define_css_keyword_enum {
     ($name: ident: $( $css: expr => $variant: ident ),+,) => {
         define_css_keyword_enum!($name: $( $css => $variant ),+)
     };
     ($name: ident: $( $css: expr => $variant: ident ),+) => {
         #[allow(non_camel_case_types)]
-        #[deriving(Clone, Eq, PartialEq, FromPrimitive)]
+        #[deriving(Clone, Eq, PartialEq, FromPrimitive, Copy)]
         pub enum $name {
             $( $variant ),+
         }
 
         impl $name {
             pub fn parse(component_value: &::cssparser::ast::ComponentValue) -> Result<$name, ()> {
                 match component_value {
                     &::cssparser::ast::ComponentValue::Ident(ref value) => {
@@ -133,17 +133,17 @@ pub mod specified {
         fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
             match self {
                 &CSSImage(Some(ref image)) => image.to_css(dest),
                 &CSSImage(None) => dest.write_str("none"),
             }
         }
     }
 
-    #[deriving(Clone, PartialEq)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub enum Length {
         Au(Au),  // application units
         Em(CSSFloat),
         Ex(CSSFloat),
         Rem(CSSFloat),
 
         /// HTML5 "character width", as defined in HTML5 § 14.5.4.
         ///
@@ -214,17 +214,17 @@ pub mod specified {
             }
         }
         #[inline]
         pub fn from_px(px_value: CSSFloat) -> Length {
             Length::Au(Au((px_value * AU_PER_PX) as i32))
         }
     }
 
-    #[deriving(Clone, PartialEq)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub enum LengthOrPercentage {
         Length(Length),
         Percentage(CSSFloat),  // [0 .. 100%] maps to [0.0 .. 1.0]
     }
 
     impl fmt::Show for LengthOrPercentage {
         #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
     }
@@ -258,17 +258,17 @@ pub mod specified {
             LengthOrPercentage::parse_internal(input, /* negative_ok = */ true)
         }
         #[inline]
         pub fn parse_non_negative(input: &ComponentValue) -> Result<LengthOrPercentage, ()> {
             LengthOrPercentage::parse_internal(input, /* negative_ok = */ false)
         }
     }
 
-    #[deriving(Clone)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub enum LengthOrPercentageOrAuto {
         Length(Length),
         Percentage(CSSFloat),  // [0 .. 100%] maps to [0.0 .. 1.0]
         Auto,
     }
 
     impl fmt::Show for LengthOrPercentageOrAuto {
         #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
@@ -304,17 +304,17 @@ pub mod specified {
             LengthOrPercentageOrAuto::parse_internal(input, /* negative_ok = */ true)
         }
         #[inline]
         pub fn parse_non_negative(input: &ComponentValue) -> Result<LengthOrPercentageOrAuto, ()> {
             LengthOrPercentageOrAuto::parse_internal(input, /* negative_ok = */ false)
         }
     }
 
-    #[deriving(Clone)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub enum LengthOrPercentageOrNone {
         Length(Length),
         Percentage(CSSFloat),  // [0 .. 100%] maps to [0.0 .. 1.0]
         None,
     }
 
     impl fmt::Show for LengthOrPercentageOrNone {
         #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
@@ -350,17 +350,17 @@ pub mod specified {
         }
         #[inline]
         pub fn parse_non_negative(input: &ComponentValue) -> Result<LengthOrPercentageOrNone, ()> {
             LengthOrPercentageOrNone::parse_internal(input, /* negative_ok = */ false)
         }
     }
 
     // http://dev.w3.org/csswg/css2/colors.html#propdef-background-position
-    #[deriving(Clone)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub enum PositionComponent {
         Length(Length),
         Percentage(CSSFloat),  // [0 .. 100%] maps to [0.0 .. 1.0]
         Center,
         Left,
         Right,
         Top,
         Bottom,
@@ -390,17 +390,17 @@ pub mod specified {
                 PositionComponent::Percentage(x) => LengthOrPercentage::Percentage(x),
                 PositionComponent::Center => LengthOrPercentage::Percentage(0.5),
                 PositionComponent::Left | PositionComponent::Top => LengthOrPercentage::Percentage(0.0),
                 PositionComponent::Right | PositionComponent::Bottom => LengthOrPercentage::Percentage(1.0),
             }
         }
     }
 
-    #[deriving(Clone, PartialEq, PartialOrd)]
+    #[deriving(Clone, PartialEq, PartialOrd, Copy)]
     pub struct Angle(pub CSSFloat);
 
     impl fmt::Show for Angle {
         #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
     }
 
     impl ToCss for Angle {
         fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
@@ -447,17 +447,17 @@ pub mod specified {
         #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
     }
 
     impl ToCss for Image {
         fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
             match self {
                 &Image::Url(ref url) => {
                     try!(dest.write_str("url(\""));
-                    try!(write!(CssStringWriter::new(dest), "{}", url));
+                    try!(write!(&mut CssStringWriter::new(dest), "{}", url));
                     try!(dest.write_str("\")"));
                     Ok(())
                 }
                 &Image::LinearGradient(ref gradient) => gradient.to_css(dest)
             }
         }
     }
 
@@ -517,17 +517,17 @@ pub mod specified {
                 try!(stop.to_css(dest));
             }
             try!(dest.write_char(')'));
             Ok(())
         }
     }
 
     /// Specified values for an angle or a corner in a linear gradient.
-    #[deriving(Clone, PartialEq)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub enum AngleOrCorner {
         Angle(Angle),
         Corner(HorizontalDirection, VerticalDirection),
     }
 
     impl fmt::Show for AngleOrCorner {
         #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
     }
@@ -713,16 +713,17 @@ pub mod computed {
     pub use super::specified::{Angle, AngleOrCorner, HorizontalDirection};
     pub use super::specified::{VerticalDirection};
     pub use cssparser::Color as CSSColor;
     use super::*;
     use super::super::longhands;
     use std::fmt;
     use url::Url;
 
+    #[allow(missing_copy_implementations)]  // It’s kinda big
     pub struct Context {
         pub inherited_font_weight: longhands::font_weight::computed_value::T,
         pub inherited_font_size: longhands::font_size::computed_value::T,
         pub inherited_text_decorations_in_effect: longhands::_servo_text_decorations_in_effect::T,
         pub inherited_height: longhands::height::T,
         pub color: longhands::color::computed_value::T,
         pub text_decoration: longhands::text_decoration::computed_value::T,
         pub font_size: longhands::font_size::computed_value::T,
@@ -769,17 +770,17 @@ pub mod computed {
                 // TODO(pcwalton): Find these from the font.
                 let average_advance = reference_font_size.scale_by(0.5);
                 let max_advance = reference_font_size;
                 average_advance.scale_by(value as CSSFloat - 1.0) + max_advance
             }
         }
     }
 
-    #[deriving(PartialEq, Clone)]
+    #[deriving(PartialEq, Clone, Copy)]
     pub enum LengthOrPercentage {
         Length(Au),
         Percentage(CSSFloat),
     }
     impl fmt::Show for LengthOrPercentage {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             match self {
                 &LengthOrPercentage::Length(length) => write!(f, "{}", length),
@@ -794,17 +795,17 @@ pub mod computed {
         match value {
             specified::LengthOrPercentage::Length(value) =>
                 LengthOrPercentage::Length(compute_Au(value, context)),
             specified::LengthOrPercentage::Percentage(value) =>
                 LengthOrPercentage::Percentage(value),
         }
     }
 
-    #[deriving(PartialEq, Clone)]
+    #[deriving(PartialEq, Clone, Copy)]
     pub enum LengthOrPercentageOrAuto {
         Length(Au),
         Percentage(CSSFloat),
         Auto,
     }
     impl fmt::Show for LengthOrPercentageOrAuto {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             match self {
@@ -822,17 +823,17 @@ pub mod computed {
                 LengthOrPercentageOrAuto::Length(compute_Au(value, context)),
             specified::LengthOrPercentageOrAuto::Percentage(value) =>
                 LengthOrPercentageOrAuto::Percentage(value),
             specified::LengthOrPercentageOrAuto::Auto =>
                 LengthOrPercentageOrAuto::Auto,
         }
     }
 
-    #[deriving(PartialEq, Clone)]
+    #[deriving(PartialEq, Clone, Copy)]
     pub enum LengthOrPercentageOrNone {
         Length(Au),
         Percentage(CSSFloat),
         None,
     }
     impl fmt::Show for LengthOrPercentageOrNone {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             match self {
@@ -887,17 +888,17 @@ pub mod computed {
             for stop in self.stops.iter() {
                 let _ = write!(f, ", {}", stop);
             }
             Ok(())
         }
     }
 
     /// Computed values for one color stop in a linear gradient.
-    #[deriving(Clone, PartialEq)]
+    #[deriving(Clone, PartialEq, Copy)]
     pub struct ColorStop {
         /// The color of this stop.
         pub color: CSSColor,
 
         /// The position of this stop. If not specified, this stop is placed halfway between the
         /// point that precedes it and the point that follows it per CSS-IMAGES § 3.4.
         pub position: Option<LengthOrPercentage>,
     }
--- a/servo/components/style/properties/mod.rs.mako
+++ b/servo/components/style/properties/mod.rs.mako
@@ -2,19 +2,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This file is a Mako template: http://www.makotemplates.org/
 
 pub use std::ascii::AsciiExt;
 use std::fmt;
 use std::fmt::Show;
+use std::sync::Arc;
 
 use servo_util::logical_geometry::{WritingMode, LogicalMargin};
-use sync::Arc;
 pub use url::Url;
 
 pub use cssparser::*;
 pub use cssparser::ast::*;
 pub use cssparser::ast::ComponentValue::*;
 pub use geom::SideOffsets2D;
 pub use self::common_types::specified::{Angle, AngleOrCorner};
 pub use self::common_types::specified::{HorizontalDirection, VerticalDirection};
@@ -274,25 +274,25 @@ pub mod longhands {
                 } else {
                     computed::compute_Au(value, context)
                 }
             }
         </%self:longhand>
     % endfor
 
     <%self:longhand name="border-top-left-radius">
-        #[deriving(Clone, Show)]
+        #[deriving(Clone, Show, PartialEq, Copy)]
         pub struct SpecifiedValue {
             pub radius: specified::LengthOrPercentage,
         }
 
         pub mod computed_value {
             use super::super::computed;
 
-            #[deriving(Clone, PartialEq, Show)]
+            #[deriving(Clone, PartialEq, Copy, Show)]
             pub struct T {
                 pub radius: computed::LengthOrPercentage,
             }
         }
 
         #[inline]
         pub fn get_initial_value() -> computed_value::T {
             computed_value::T {
@@ -446,17 +446,17 @@ pub mod longhands {
     </%self:longhand>
 
     <%self:single_component_value name="z-index">
         pub use super::computed_as_specified as to_computed_value;
         pub type SpecifiedValue = computed_value::T;
         pub mod computed_value {
             use std::fmt;
 
-            #[deriving(PartialEq, Clone)]
+            #[deriving(PartialEq, Clone, Eq, Copy)]
             pub enum T {
                 Auto,
                 Number(i32),
             }
             impl fmt::Show for T {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     match self {
                         &T::Auto => write!(f, "auto"),
@@ -538,17 +538,17 @@ pub mod longhands {
     ${predefined_type("max-height", "LengthOrPercentageOrNone",
                       "computed::LengthOrPercentageOrNone::None",
                       "parse_non_negative")}
 
     ${switch_to_style_struct("InheritedBox")}
 
     <%self:single_component_value name="line-height">
         use std::fmt;
-        #[deriving(Clone)]
+        #[deriving(Clone, PartialEq, Copy)]
         pub enum SpecifiedValue {
             Normal,
             Length(specified::Length),
             Number(CSSFloat),
             Percentage(CSSFloat),
         }
         impl fmt::Show for SpecifiedValue {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -574,17 +574,17 @@ pub mod longhands {
                 &Ident(ref value) if value.as_slice().eq_ignore_ascii_case("normal") =>
                     Ok(SpecifiedValue::Normal),
                 _ => Err(()),
             }
         }
         pub mod computed_value {
             use super::super::{Au, CSSFloat};
             use std::fmt;
-            #[deriving(PartialEq, Clone)]
+            #[deriving(PartialEq, Copy, Clone)]
             pub enum T {
                 Normal,
                 Length(Au),
                 Number(CSSFloat),
             }
             impl fmt::Show for T {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     match self {
@@ -611,17 +611,17 @@ pub mod longhands {
 
     ${switch_to_style_struct("Box")}
 
     <%self:single_component_value name="vertical-align">
         use std::fmt;
         <% vertical_align_keywords = (
             "baseline sub super top text-top middle bottom text-bottom".split()) %>
         #[allow(non_camel_case_types)]
-        #[deriving(Clone)]
+        #[deriving(Clone, PartialEq, Copy)]
         pub enum SpecifiedValue {
             % for keyword in vertical_align_keywords:
                 ${to_rust_ident(keyword)},
             % endfor
             LengthOrPercentage(specified::LengthOrPercentage),
         }
         impl fmt::Show for SpecifiedValue {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -649,17 +649,17 @@ pub mod longhands {
                 _ => specified::LengthOrPercentage::parse_non_negative(input)
                      .map(SpecifiedValue::LengthOrPercentage)
             }
         }
         pub mod computed_value {
             use super::super::{Au, CSSFloat};
             use std::fmt;
             #[allow(non_camel_case_types)]
-            #[deriving(PartialEq, Clone)]
+            #[deriving(PartialEq, Copy, Clone)]
             pub enum T {
                 % for keyword in vertical_align_keywords:
                     ${to_rust_ident(keyword)},
                 % endfor
                 Length(Au),
                 Percentage(CSSFloat),
             }
             impl fmt::Show for T {
@@ -705,29 +705,29 @@ pub mod longhands {
     // CSS 2.1, Section 12 - Generated content, automatic numbering, and lists
 
     ${switch_to_style_struct("Box")}
 
     <%self:longhand name="content">
             pub use super::computed_as_specified as to_computed_value;
             pub mod computed_value {
             use std::fmt;
-                #[deriving(PartialEq, Clone)]
+                #[deriving(PartialEq, Eq, Clone)]
                 pub enum ContentItem {
                     StringContent(String),
                 }
                 impl fmt::Show for ContentItem {
                     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                         match self {
                             &ContentItem::StringContent(ref s) => write!(f, "\"{}\"", s),
                         }
                     }
                 }
                 #[allow(non_camel_case_types)]
-                #[deriving(PartialEq, Clone)]
+                #[deriving(PartialEq, Eq, Clone)]
                 pub enum T {
                     normal,
                     none,
                     Content(Vec<ContentItem>),
                 }
                 impl fmt::Show for T {
                     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                         match self {
@@ -854,29 +854,29 @@ pub mod longhands {
 
     <%self:longhand name="background-position">
             use std::fmt;
 
             pub mod computed_value {
                 use super::super::super::common_types::computed::LengthOrPercentage;
                 use std::fmt;
 
-                #[deriving(PartialEq, Clone)]
+                #[deriving(PartialEq, Copy, Clone)]
                 pub struct T {
                     pub horizontal: LengthOrPercentage,
                     pub vertical: LengthOrPercentage,
                 }
                 impl fmt::Show for T {
                     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                         write!(f, "{} {}", self.horizontal, self.vertical)
                     }
                 }
             }
 
-            #[deriving(Clone)]
+            #[deriving(Clone, PartialEq, Copy)]
             pub struct SpecifiedValue {
                 pub horizontal: specified::LengthOrPercentage,
                 pub vertical: specified::LengthOrPercentage,
             }
             impl fmt::Show for SpecifiedValue {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     write!(f, "{} {}", self.horizontal, self.vertical)
                 }
@@ -1018,17 +1018,17 @@ pub mod longhands {
     // CSS 2.1, Section 15 - Fonts
 
     ${new_style_struct("Font", is_inherited=True)}
 
     <%self:longhand name="font-family">
         pub use super::computed_as_specified as to_computed_value;
         pub mod computed_value {
             use std::fmt;
-            #[deriving(PartialEq, Clone)]
+            #[deriving(PartialEq, Eq, Clone)]
             pub enum FontFamily {
                 FamilyName(String),
                 // Generic
 //                Serif,
 //                SansSerif,
 //                Cursive,
 //                Fantasy,
 //                Monospace,
@@ -1105,17 +1105,17 @@ pub mod longhands {
     </%self:longhand>
 
 
     ${single_keyword("font-style", "normal italic oblique")}
     ${single_keyword("font-variant", "normal small-caps")}
 
     <%self:single_component_value name="font-weight">
         use std::fmt;
-        #[deriving(Clone)]
+        #[deriving(Clone, PartialEq, Eq, Copy)]
         pub enum SpecifiedValue {
             Bolder,
             Lighter,
             % for weight in range(100, 901, 100):
                 SpecifiedWeight${weight},
             % endfor
         }
         impl fmt::Show for SpecifiedValue {
@@ -1154,17 +1154,17 @@ pub mod longhands {
                     Some(900) => Ok(SpecifiedValue::SpecifiedWeight900),
                     _ => Err(()),
                 },
                 _ => Err(())
             }
         }
         pub mod computed_value {
             use std::fmt;
-            #[deriving(PartialEq, Clone)]
+            #[deriving(PartialEq, Eq, Copy, Clone)]
             pub enum T {
                 % for weight in range(100, 901, 100):
                     Weight${weight},
                 % endfor
             }
             impl fmt::Show for T {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     match self {
@@ -1322,17 +1322,17 @@ pub mod longhands {
     // name per CSS-TEXT 6.2.
     ${single_keyword("overflow-wrap", "normal break-word")}
 
     ${new_style_struct("Text", is_inherited=False)}
 
     <%self:longhand name="text-decoration">
         pub use super::computed_as_specified as to_computed_value;
         use std::fmt;
-        #[deriving(PartialEq, Clone)]
+        #[deriving(PartialEq, Eq, Copy, Clone)]
         pub struct SpecifiedValue {
             pub underline: bool,
             pub overline: bool,
             pub line_through: bool,
             // 'blink' is accepted in the parser but ignored.
             // Just not blinking the text is a conforming implementation per CSS 2.1.
         }
         impl fmt::Show for SpecifiedValue {
@@ -1399,17 +1399,17 @@ pub mod longhands {
     </%self:longhand>
 
     ${switch_to_style_struct("InheritedText")}
 
     <%self:longhand name="-servo-text-decorations-in-effect"
                     derived_from="display text-decoration">
         pub use super::computed_as_specified as to_computed_value;
 
-        #[deriving(Clone, PartialEq)]
+        #[deriving(Clone, PartialEq, Copy)]
         pub struct SpecifiedValue {
             pub underline: Option<RGBA>,
             pub overline: Option<RGBA>,
             pub line_through: Option<RGBA>,
         }
 
         pub mod computed_value {
             pub type T = super::SpecifiedValue;
@@ -1511,17 +1511,17 @@ pub mod longhands {
     ${new_style_struct("Pointing", is_inherited=True)}
 
     <%self:single_component_value name="cursor">
         use servo_util::cursor as util_cursor;
         pub use super::computed_as_specified as to_computed_value;
 
         pub mod computed_value {
             use servo_util::cursor::Cursor;
-            #[deriving(Clone, PartialEq, Show)]
+            #[deriving(Clone, PartialEq, Eq, Copy, Show)]
             pub enum T {
                 AutoCursor,
                 SpecifiedCursor(Cursor),
             }
         }
         pub type SpecifiedValue = computed_value::T;
         #[inline]
         pub fn get_initial_value() -> computed_value::T {
@@ -1576,17 +1576,17 @@ pub mod longhands {
     </%self:single_component_value>
 
     <%self:longhand name="box-shadow">
         use cssparser;
         use std::fmt;
 
         pub type SpecifiedValue = Vec<SpecifiedBoxShadow>;
 
-        #[deriving(Clone)]
+        #[deriving(Clone, PartialEq)]
         pub struct SpecifiedBoxShadow {
             pub offset_x: specified::Length,
             pub offset_y: specified::Length,
             pub blur_radius: specified::Length,
             pub spread_radius: specified::Length,
             pub color: Option<specified::CSSColor>,
             pub inset: bool,
         }
@@ -1607,17 +1607,17 @@ pub mod longhands {
 
         pub mod computed_value {
             use super::super::Au;
             use super::super::super::computed;
             use std::fmt;
 
             pub type T = Vec<BoxShadow>;
 
-            #[deriving(Clone, PartialEq)]
+            #[deriving(Clone, PartialEq, Copy)]
             pub struct BoxShadow {
                 pub offset_x: Au,
                 pub offset_y: Au,
                 pub blur_radius: Au,
                 pub spread_radius: Au,
                 pub color: computed::CSSColor,
                 pub inset: bool,
             }
@@ -1745,28 +1745,28 @@ pub mod longhands {
     </%self:longhand>
 
     <%self:single_component_value name="clip">
         // NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
 
         pub mod computed_value {
             use super::super::Au;
 
-            #[deriving(Clone, PartialEq, Show)]
+            #[deriving(Clone, PartialEq, Eq, Copy, Show)]
             pub struct ClipRect {
                 pub top: Au,
                 pub right: Option<Au>,
                 pub bottom: Option<Au>,
                 pub left: Au,
             }
 
             pub type T = Option<ClipRect>;
         }
 
-        #[deriving(Clone, Show)]
+        #[deriving(Clone, Show, PartialEq, Copy)]
         pub struct SpecifiedClipRect {
             pub top: specified::Length,
             pub right: Option<specified::Length>,
             pub bottom: Option<specified::Length>,
             pub left: specified::Length,
         }
 
         pub type SpecifiedValue = Option<SpecifiedClipRect>;
@@ -2463,17 +2463,17 @@ impl CSSWideKeyword {
                 "unset" => Ok(CSSWideKeyword::UnsetKeyword),
                 _ => Err(())
             }
         })
     }
 }
 
 
-#[deriving(Clone)]
+#[deriving(Clone, PartialEq, Eq, Copy)]
 pub enum DeclaredValue<T> {
     SpecifiedValue(T),
     Initial,
     Inherit,
     // There is no Unset variant here.
     // The 'unset' keyword is represented as either Initial or Inherit,
     // depending on whether the property is inherited.
 }
@@ -2491,16 +2491,17 @@ impl<T: Show> DeclaredValue<T> {
 #[deriving(Clone)]
 pub enum PropertyDeclaration {
     % for property in LONGHANDS:
         ${property.camel_case}Declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
     % endfor
 }
 
 
+#[deriving(Eq, PartialEq, Copy)]
 pub enum PropertyDeclarationParseResult {
     UnknownProperty,
     ExperimentalProperty,
     InvalidValue,
     ValidOrIgnoredDeclaration,
 }
 
 impl PropertyDeclaration {
@@ -2640,16 +2641,17 @@ impl Show for PropertyDeclaration {
     }
 }
 
 
 pub mod style_structs {
     use super::longhands;
 
     % for style_struct in STYLE_STRUCTS:
+        #[allow(missing_copy_implementations)]
         #[deriving(PartialEq, Clone)]
         pub struct ${style_struct.name} {
             % for longhand in style_struct.longhands:
                 pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T,
             % endfor
         }
     % endfor
 }
--- a/servo/components/style/selector_matching.rs
+++ b/servo/components/style/selector_matching.rs
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use std::ascii::AsciiExt;
 use std::collections::HashMap;
 use std::hash::Hash;
-use sync::Arc;
+use std::sync::Arc;
 
 use url::Url;
 
 use servo_util::bloom::BloomFilter;
 use servo_util::resource_files::read_resource_file;
 use servo_util::smallvec::VecLike;
 use servo_util::sort;
 use string_cache::Atom;
@@ -19,17 +19,17 @@ use legacy::PresentationalHintSynthesis;
 use media_queries::Device;
 use node::{TElement, TElementAttributes, TNode};
 use properties::{PropertyDeclaration, PropertyDeclarationBlock};
 use selectors::{CaseSensitivity, Combinator, CompoundSelector, LocalName};
 use selectors::{PseudoElement, SelectorList, SimpleSelector};
 use selectors::{get_selector_list_selectors};
 use stylesheets::{Stylesheet, iter_stylesheet_media_rules, iter_stylesheet_style_rules};
 
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq, Copy)]
 pub enum StylesheetOrigin {
     UserAgent,
     Author,
     User,
 }
 
 /// The definition of whitespace per CSS Selectors Level 3 § 4.
 pub static SELECTOR_WHITESPACE: &'static [char] = &[' ', '\t', '\n', '\r', '\x0C'];
@@ -619,16 +619,17 @@ fn matches_compound_selector<'a,E,N>(sel
 /// The selectors ("b1 + b2 ~") doesn't match and matching restart from "d1".
 ///
 /// The additional example is child and sibling. When the selector
 /// "b1 + c1 > b2 ~ d1 a" is provided and the selector "b1" doesn't match on
 /// the element, this "b1" raises NotMatchedAndRestartFromClosestLaterSibling.
 /// However since the selector "c1" raises
 /// NotMatchedAndRestartFromClosestDescendant. So the selector
 /// "b1 + c1 > b2 ~ " doesn't match and restart matching from "d1".
+#[deriving(PartialEq, Eq, Copy)]
 enum SelectorMatchingResult {
     Matched,
     NotMatchedAndRestartFromClosestLaterSibling,
     NotMatchedAndRestartFromClosestDescendant,
     NotMatchedGlobally,
 }
 
 /// Quickly figures out whether or not the compound selector is worth doing more
@@ -758,30 +759,32 @@ fn matches_compound_selector_internal<'a
                     }
                 }
             }
         }
     }
 }
 
 bitflags! {
+    #[deriving(Copy)]
     flags CommonStyleAffectingAttributes: u8 {
         const HIDDEN_ATTRIBUTE = 0x01,
         const NO_WRAP_ATTRIBUTE = 0x02,
         const ALIGN_LEFT_ATTRIBUTE = 0x04,
         const ALIGN_CENTER_ATTRIBUTE = 0x08,
         const ALIGN_RIGHT_ATTRIBUTE = 0x10,
     }
 }
 
 pub struct CommonStyleAffectingAttributeInfo {
     pub atom: Atom,
     pub mode: CommonStyleAffectingAttributeMode,
 }
 
+#[deriving(Copy)]
 pub enum CommonStyleAffectingAttributeMode {
     IsPresent(CommonStyleAffectingAttributes),
     IsEqual(&'static str, CommonStyleAffectingAttributes),
 }
 
 // NB: This must match the order in `layout::css::matching::CommonStyleAffectingAttributes`.
 #[inline]
 pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo, ..5] {
@@ -1159,17 +1162,17 @@ impl<K: Eq + Hash, V> FindPush<K, V> for
             None => {}
         }
         self.insert(key, vec![value]);
     }
 }
 
 #[cfg(test)]
 mod tests {
-    use sync::Arc;
+    use std::sync::Arc;
     use super::{DeclarationBlock, Rule, SelectorMap};
     use selectors::LocalName;
     use string_cache::Atom;
 
     /// Helper method to get some Rules from selector strings.
     /// Each sublist of the result contains the Rules for one StyleRule.
     fn get_mock_rules(css_selectors: &[&str]) -> Vec<Vec<Rule>> {
         use namespaces::NamespaceMap;
@@ -1193,55 +1196,55 @@ mod tests {
                     }
                 }
             }).collect()
         }).collect()
     }
 
     #[test]
     fn test_rule_ordering_same_specificity(){
-        let rules_list = get_mock_rules(["a.intro", "img.sidebar"]);
+        let rules_list = get_mock_rules(&["a.intro", "img.sidebar"]);
         let a = &rules_list[0][0].declarations;
         let b = &rules_list[1][0].declarations;
         assert!((a.specificity, a.source_order).cmp(&(b.specificity, b.source_order)) == Less,
                 "The rule that comes later should win.");
     }
 
     #[test]
     fn test_get_id_name(){
-        let rules_list = get_mock_rules([".intro", "#top"]);
+        let rules_list = get_mock_rules(&[".intro", "#top"]);
         assert_eq!(SelectorMap::get_id_name(&rules_list[0][0]), None);
         assert_eq!(SelectorMap::get_id_name(&rules_list[1][0]), Some(atom!("top")));
     }
 
     #[test]
     fn test_get_class_name(){
-        let rules_list = get_mock_rules([".intro.foo", "#top"]);
+        let rules_list = get_mock_rules(&[".intro.foo", "#top"]);
         assert_eq!(SelectorMap::get_class_name(&rules_list[0][0]), Some(Atom::from_slice("intro")));
         assert_eq!(SelectorMap::get_class_name(&rules_list[1][0]), None);
     }
 
     #[test]
     fn test_get_local_name(){
-        let rules_list = get_mock_rules(["img.foo", "#top", "IMG", "ImG"]);
+        let rules_list = get_mock_rules(&["img.foo", "#top", "IMG", "ImG"]);
         let check = |i, names: Option<(&str, &str)>| {
             assert!(SelectorMap::get_local_name(&rules_list[i][0])
                     == names.map(|(name, lower_name)| LocalName {
                             name: Atom::from_slice(name),
                             lower_name: Atom::from_slice(lower_name) }))
         };
         check(0, Some(("img", "img")));
         check(1, None);
         check(2, Some(("IMG", "img")));
         check(3, Some(("ImG", "img")));
     }
 
     #[test]
     fn test_insert(){
-        let rules_list = get_mock_rules([".intro.foo", "#top"]);
+        let rules_list = get_mock_rules(&[".intro.foo", "#top"]);
         let mut selector_map = SelectorMap::new();
         selector_map.insert(rules_list[1][0].clone());
         assert_eq!(1, selector_map.id_hash.get(&atom!("top")).unwrap()[0].declarations.source_order);
         selector_map.insert(rules_list[0][0].clone());
         assert_eq!(0, selector_map.class_hash.get(&Atom::from_slice("intro")).unwrap()[0].declarations.source_order);
         assert!(selector_map.class_hash.get(&Atom::from_slice("foo")).is_none());
     }
 }
--- a/servo/components/style/selectors.rs
+++ b/servo/components/style/selectors.rs
@@ -1,54 +1,55 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use std::{cmp, iter};
 use std::ascii::{AsciiExt, OwnedAsciiExt};
-use sync::Arc;
+use std::sync::Arc;
 
 use cssparser::ast::*;
 use cssparser::ast::ComponentValue::*;
 use cssparser::{tokenize, parse_nth};
 
 use selector_matching::StylesheetOrigin;
 use string_cache::{Atom, Namespace};
 
 use namespaces::NamespaceMap;
 
 /// Ambient data used by the parser.
+#[deriving(Copy)]
 pub struct ParserContext {
     /// The origin of this stylesheet.
     pub origin: StylesheetOrigin,
 }
 
 #[deriving(PartialEq, Clone)]
 pub struct Selector {
     pub compound_selectors: Arc<CompoundSelector>,
     pub pseudo_element: Option<PseudoElement>,
     pub specificity: u32,
 }
 
-#[deriving(Eq, PartialEq, Clone, Hash)]
+#[deriving(Eq, PartialEq, Clone, Hash, Copy)]
 pub enum PseudoElement {
     Before,
     After,
 //    FirstLine,
 //    FirstLetter,
 }
 
 
 #[deriving(PartialEq, Clone)]
 pub struct CompoundSelector {
     pub simple_selectors: Vec<SimpleSelector>,
     pub next: Option<(Box<CompoundSelector>, Combinator)>,  // c.next is left of c
 }
 
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Clone, Copy)]
 pub enum Combinator {
     Child,  //  >
     Descendant,  // space
     NextSibling,  // +
     LaterSibling,  // ~
 }
 
 #[deriving(Eq, PartialEq, Clone, Hash)]
@@ -88,17 +89,17 @@ pub enum SimpleSelector {
     FirstOfType,
     LastOfType,
     OnlyOfType,
     ServoNonzeroBorder,
     // ...
 }
 
 
-#[deriving(Eq, PartialEq, Clone, Hash)]
+#[deriving(Eq, PartialEq, Clone, Hash, Copy)]
 pub enum CaseSensitivity {
     CaseSensitive,  // Selectors spec says language-defined, but HTML says sensitive.
     CaseInsensitive,
 }
 
 
 #[deriving(Eq, PartialEq, Clone, Hash)]
 pub struct LocalName {
@@ -662,17 +663,17 @@ fn skip_whitespace<I: Iterator<Component
         any_whitespace = true;
         iter.next();
     }
 }
 
 
 #[cfg(test)]
 mod tests {
-    use sync::Arc;
+    use std::sync::Arc;
     use cssparser;
     use namespaces::NamespaceMap;
     use selector_matching::StylesheetOrigin;
     use string_cache::Atom;
     use super::*;
 
     fn parse(input: &str) -> Result<Vec<Selector>, ()> {
         parse_ns(input, &NamespaceMap::new())
--- a/servo/components/util/cache.rs
+++ b/servo/components/util/cache.rs
@@ -64,24 +64,22 @@ impl<K,V> HashCache<K,V> where K: Clone 
     pub fn find_equiv<'a,Sized? Q>(&'a self, key: &Q) -> Option<&'a V> where Q: Hash + Equiv<K> {
         self.entries.find_equiv(key)
     }
 }
 
 #[test]
 fn test_hashcache() {
     let mut cache: HashCache<uint, Cell<&str>> = HashCache::new();
-    let one = Cell::new("one");
-    let two = Cell::new("two");
 
-    cache.insert(1, one);
+    cache.insert(1, Cell::new("one"));
     assert!(cache.find(&1).is_some());
     assert!(cache.find(&2).is_none());
 
-    cache.find_or_create(&2, |_v| { two });
+    cache.find_or_create(&2, |_v| { Cell::new("two") });
     assert!(cache.find(&1).is_some());
     assert!(cache.find(&2).is_some());
 }
 
 pub struct LRUCache<K, V> {
     entries: Vec<(K, V)>,
     cache_size: uint,
 }
@@ -228,15 +226,15 @@ fn test_lru_cache() {
     cache.insert(4, four); // (2, 4)
 
     assert!(cache.find(&1).is_none());  // (2, 4) (no change)
     assert!(cache.find(&2).is_some());  // (4, 2)
     assert!(cache.find(&3).is_none());  // (4, 2) (no change)
     assert!(cache.find(&4).is_some());  // (2, 4) (no change)
 
     // Test find_or_create.
-    cache.find_or_create(&1, |_| { one }); // (4, 1)
+    cache.find_or_create(&1, |_| { Cell::new("one") }); // (4, 1)
 
     assert!(cache.find(&1).is_some()); // (4, 1) (no change)
     assert!(cache.find(&2).is_none()); // (4, 1) (no change)
     assert!(cache.find(&3).is_none()); // (4, 1) (no change)
     assert!(cache.find(&4).is_some()); // (1, 4)
 }
--- a/servo/components/util/cursor.rs
+++ b/servo/components/util/cursor.rs
@@ -6,17 +6,17 @@
 
 use cssparser::ToCss;
 use std::ascii::AsciiExt;
 use text_writer::TextWriter;
 
 
 macro_rules! define_cursor {
     ($( $css: expr => $variant: ident = $value: expr, )+) => {
-        #[deriving(Clone, PartialEq, Eq, FromPrimitive, Show)]
+        #[deriving(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)]
         #[repr(u8)]
         pub enum Cursor {
             $( $variant = $value ),+
         }
 
         impl Cursor {
             pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> {
                 match_ignore_ascii_case! { keyword:
new file mode 100644
--- /dev/null
+++ b/servo/components/util/deque/mod.rs
@@ -0,0 +1,660 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A (mostly) lock-free concurrent work-stealing deque
+//!
+//! This module contains an implementation of the Chase-Lev work stealing deque
+//! described in "Dynamic Circular Work-Stealing Deque". The implementation is
+//! heavily based on the pseudocode found in the paper.
+//!
+//! This implementation does not want to have the restriction of a garbage
+//! collector for reclamation of buffers, and instead it uses a shared pool of
+//! buffers. This shared pool is required for correctness in this
+//! implementation.
+//!
+//! The only lock-synchronized portions of this deque are the buffer allocation
+//! and deallocation portions. Otherwise all operations are lock-free.
+//!
+//! # Example
+//!
+//!     use util::deque::BufferPool;
+//!
+//!     let mut pool = BufferPool::new();
+//!     let (mut worker, mut stealer) = pool.deque();
+//!
+//!     // Only the worker may push/pop
+//!     worker.push(1i);
+//!     worker.pop();
+//!
+//!     // Stealers take data from the other end of the deque
+//!     worker.push(1i);
+//!     stealer.steal();
+//!
+//!     // Stealers can be cloned to have many stealers stealing in parallel
+//!     worker.push(1i);
+//!     let mut stealer2 = stealer.clone();
+//!     stealer2.steal();
+
+#![experimental]
+
+// NB: the "buffer pool" strategy is not done for speed, but rather for
+//     correctness. For more info, see the comment on `swap_buffer`
+
+// FIXME: all atomic operations in this module use a SeqCst ordering. That is
+//      probably overkill
+
+pub use self::Stolen::{Empty, Abort, Data};
+
+use alloc::arc::Arc;
+use alloc::heap::{allocate, deallocate};
+use std::kinds::marker;
+use std::mem::{forget, min_align_of, size_of, transmute};
+use std::ptr;
+
+use std::sync::Mutex;
+use std::sync::atomic::{AtomicInt, AtomicPtr, SeqCst};
+
+// Once the queue is less than 1/K full, then it will be downsized. Note that
+// the deque requires that this number be less than 2.
+static K: int = 4;
+
+// Minimum number of bits that a buffer size should be. No buffer will resize to
+// under this value, and all deques will initially contain a buffer of this
+// size.
+//
+// The size in question is 1 << MIN_BITS
+static MIN_BITS: uint = 7;
+
+struct Deque<T> {
+    bottom: AtomicInt,
+    top: AtomicInt,
+    array: AtomicPtr<Buffer<T>>,
+    pool: BufferPool<T>,
+}
+
+/// Worker half of the work-stealing deque. This worker has exclusive access to
+/// one side of the deque, and uses `push` and `pop` method to manipulate it.
+///
+/// There may only be one worker per deque.
+pub struct Worker<T> {
+    deque: Arc<Deque<T>>,
+    _noshare: marker::NoSync,
+}
+
+/// The stealing half of the work-stealing deque. Stealers have access to the
+/// opposite end of the deque from the worker, and they only have access to the
+/// `steal` method.
+pub struct Stealer<T> {
+    deque: Arc<Deque<T>>,
+    _noshare: marker::NoSync,
+}
+
+/// When stealing some data, this is an enumeration of the possible outcomes.
+#[deriving(PartialEq, Show)]
+pub enum Stolen<T> {
+    /// The deque was empty at the time of stealing
+    Empty,
+    /// The stealer lost the race for stealing data, and a retry may return more
+    /// data.
+    Abort,
+    /// The stealer has successfully stolen some data.
+    Data(T),
+}
+
+/// The allocation pool for buffers used by work-stealing deques. Right now this
+/// structure is used for reclamation of memory after it is no longer in use by
+/// deques.
+///
+/// This data structure is protected by a mutex, but it is rarely used. Deques
+/// will only use this structure when allocating a new buffer or deallocating a
+/// previous one.
+pub struct BufferPool<T> {
+    // FIXME: This entire file was copied from std::sync::deque before it was removed,
+    // I converted `Exclusive` to `Mutex` here, but that might not be ideal
+    pool: Arc<Mutex<Vec<Box<Buffer<T>>>>>,
+}
+
+/// An internal buffer used by the chase-lev deque. This structure is actually
+/// implemented as a circular buffer, and is used as the intermediate storage of
+/// the data in the deque.
+///
+/// This type is implemented with *T instead of Vec<T> for two reasons:
+///
+///   1. There is nothing safe about using this buffer. This easily allows the
+///      same value to be read twice in to rust, and there is nothing to
+///      prevent this. The usage by the deque must ensure that one of the
+///      values is forgotten. Furthermore, we only ever want to manually run
+///      destructors for values in this buffer (on drop) because the bounds
+///      are defined by the deque it's owned by.
+///
+///   2. We can certainly avoid bounds checks using *T instead of Vec<T>, although
+///      LLVM is probably pretty good at doing this already.
+struct Buffer<T> {
+    storage: *const T,
+    log_size: uint,
+}
+
+impl<T: Send> BufferPool<T> {
+    /// Allocates a new buffer pool which in turn can be used to allocate new
+    /// deques.
+    pub fn new() -> BufferPool<T> {
+        BufferPool { pool: Arc::new(Mutex::new(Vec::new())) }
+    }
+
+    /// Allocates a new work-stealing deque which will send/receiving memory to
+    /// and from this buffer pool.
+    pub fn deque(&self) -> (Worker<T>, Stealer<T>) {
+        let a = Arc::new(Deque::new(self.clone()));
+        let b = a.clone();
+        (Worker { deque: a, _noshare: marker::NoSync },
+         Stealer { deque: b, _noshare: marker::NoSync })
+    }
+
+    fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> {
+        unsafe {
+            let mut pool = self.pool.lock();
+            match pool.iter().position(|x| x.size() >= (1 << bits)) {
+                Some(i) => pool.remove(i).unwrap(),
+                None => box Buffer::new(bits)
+            }
+        }
+    }
+
+    fn free(&self, buf: Box<Buffer<T>>) {
+        unsafe {
+            let mut pool = self.pool.lock();
+            match pool.iter().position(|v| v.size() > buf.size()) {
+                Some(i) => pool.insert(i, buf),
+                None => pool.push(buf),
+            }
+        }
+    }
+}
+
+impl<T: Send> Clone for BufferPool<T> {
+    fn clone(&self) -> BufferPool<T> { BufferPool { pool: self.pool.clone() } }
+}
+
+impl<T: Send> Worker<T> {
+    /// Pushes data ont