about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/arc.rs49
-rw-r--r--src/libstd/arena.rs4
-rw-r--r--src/libstd/bitv.rs6
-rw-r--r--src/libstd/cell.rs2
-rw-r--r--src/libstd/comm.rs8
-rw-r--r--src/libstd/ebml.rs394
-rw-r--r--src/libstd/ebml2.rs644
-rw-r--r--src/libstd/getopts.rs412
-rw-r--r--src/libstd/json.rs103
-rw-r--r--src/libstd/map.rs5
-rw-r--r--src/libstd/net_ip.rs31
-rw-r--r--src/libstd/net_tcp.rs96
-rw-r--r--src/libstd/net_url.rs32
-rw-r--r--src/libstd/prettyprint.rs168
-rw-r--r--src/libstd/prettyprint2.rs176
-rw-r--r--src/libstd/serialization.rs1087
-rw-r--r--src/libstd/serialization2.rs563
-rw-r--r--src/libstd/sort.rs2
-rw-r--r--src/libstd/std.rc7
-rw-r--r--src/libstd/sync.rs80
-rw-r--r--src/libstd/test.rs10
-rw-r--r--src/libstd/time.rs3
-rw-r--r--src/libstd/timer.rs4
-rw-r--r--src/libstd/treemap.rs56
-rw-r--r--src/libstd/uv_ll.rs28
25 files changed, 2015 insertions, 1955 deletions
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs
index addabb2ddb9..9c793028a52 100644
--- a/src/libstd/arc.rs
+++ b/src/libstd/arc.rs
@@ -124,7 +124,7 @@ pub fn mutex_arc_with_condvars<T: Send>(user_data: T,
                                     num_condvars: uint) -> MutexARC<T> {
     let data =
         MutexARCInner { lock: mutex_with_condvars(num_condvars),
-                          failed: false, data: user_data };
+                          failed: false, data: move user_data };
     MutexARC { x: unsafe { shared_mutable_state(move data) } }
 }
 
@@ -190,7 +190,7 @@ impl<T: Send> &MutexARC<T> {
  *
  * Will additionally fail if another task has failed while accessing the arc.
  */
-// FIXME(#2585) make this a by-move method on the arc
+// FIXME(#3724) make this a by-move method on the arc
 pub fn unwrap_mutex_arc<T: Send>(arc: MutexARC<T>) -> T {
     let MutexARC { x: x } <- arc;
     let inner = unsafe { unwrap_shared_mutable_state(move x) };
@@ -258,7 +258,7 @@ pub fn rw_arc_with_condvars<T: Const Send>(user_data: T,
                                        num_condvars: uint) -> RWARC<T> {
     let data =
         RWARCInner { lock: rwlock_with_condvars(num_condvars),
-                     failed: false, data: user_data };
+                     failed: false, data: move user_data };
     RWARC { x: unsafe { shared_mutable_state(move data) }, cant_nest: () }
 }
 
@@ -368,7 +368,7 @@ impl<T: Const Send> &RWARC<T> {
  * Will additionally fail if another task has failed while accessing the arc
  * in write mode.
  */
-// FIXME(#2585) make this a by-move method on the arc
+// FIXME(#3724) make this a by-move method on the arc
 pub fn unwrap_rw_arc<T: Const Send>(arc: RWARC<T>) -> T {
     let RWARC { x: x, _ } <- arc;
     let inner = unsafe { unwrap_shared_mutable_state(move x) };
@@ -448,7 +448,7 @@ mod tests {
 
         let (c, p) = pipes::stream();
 
-        do task::spawn() {
+        do task::spawn() |move c| {
             let p = pipes::PortSet();
             c.send(p.chan());
 
@@ -471,8 +471,8 @@ mod tests {
         let arc = ~MutexARC(false);
         let arc2 = ~arc.clone();
         let (c,p) = pipes::oneshot();
-        let (c,p) = (~mut Some(c), ~mut Some(p));
-        do task::spawn {
+        let (c,p) = (~mut Some(move c), ~mut Some(move p));
+        do task::spawn |move arc2, move p| {
             // wait until parent gets in
             pipes::recv_one(option::swap_unwrap(p));
             do arc2.access_cond |state, cond| {
@@ -494,7 +494,7 @@ mod tests {
         let arc2 = ~arc.clone();
         let (c,p) = pipes::stream();
 
-        do task::spawn_unlinked {
+        do task::spawn_unlinked |move arc2, move p| {
             let _ = p.recv();
             do arc2.access_cond |one, cond| {
                 cond.signal();
@@ -513,7 +513,7 @@ mod tests {
     fn test_mutex_arc_poison() {
         let arc = ~MutexARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.access |one| {
                 assert *one == 2;
             }
@@ -527,21 +527,21 @@ mod tests {
         let arc = MutexARC(1);
         let arc2 = ~(&arc).clone();
         let (c,p) = pipes::stream();
-        do task::spawn {
+        do task::spawn |move c, move arc2| {
             do arc2.access |one| {
                 c.send(());
                 assert *one == 2;
             }
         }
         let _ = p.recv();
-        let one = unwrap_mutex_arc(arc);
+        let one = unwrap_mutex_arc(move arc);
         assert one == 1;
     }
     #[test] #[should_fail] #[ignore(cfg(windows))]
     fn test_rw_arc_poison_wr() {
         let arc = ~RWARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.write |one| {
                 assert *one == 2;
             }
@@ -554,7 +554,7 @@ mod tests {
     fn test_rw_arc_poison_ww() {
         let arc = ~RWARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.write |one| {
                 assert *one == 2;
             }
@@ -567,7 +567,7 @@ mod tests {
     fn test_rw_arc_poison_dw() {
         let arc = ~RWARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.write_downgrade |write_mode| {
                 do (&write_mode).write |one| {
                     assert *one == 2;
@@ -582,7 +582,7 @@ mod tests {
     fn test_rw_arc_no_poison_rr() {
         let arc = ~RWARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.read |one| {
                 assert *one == 2;
             }
@@ -595,7 +595,7 @@ mod tests {
     fn test_rw_arc_no_poison_rw() {
         let arc = ~RWARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.read |one| {
                 assert *one == 2;
             }
@@ -608,9 +608,9 @@ mod tests {
     fn test_rw_arc_no_poison_dr() {
         let arc = ~RWARC(1);
         let arc2 = ~arc.clone();
-        do task::try {
+        do task::try |move arc2| {
             do arc2.write_downgrade |write_mode| {
-                let read_mode = arc2.downgrade(write_mode);
+                let read_mode = arc2.downgrade(move write_mode);
                 do (&read_mode).read |one| {
                     assert *one == 2;
                 }
@@ -626,7 +626,7 @@ mod tests {
         let arc2 = ~arc.clone();
         let (c,p) = pipes::stream();
 
-        do task::spawn {
+        do task::spawn |move arc2, move c| {
             do arc2.write |num| {
                 for 10.times {
                     let tmp = *num;
@@ -642,7 +642,8 @@ mod tests {
         let mut children = ~[];
         for 5.times {
             let arc3 = ~arc.clone();
-            do task::task().future_result(|+r| children.push(r)).spawn {
+            do task::task().future_result(|+r| children.push(move r)).spawn
+                |move arc3| {
                 do arc3.read |num| {
                     assert *num >= 0;
                 }
@@ -670,9 +671,9 @@ mod tests {
         let mut reader_convos = ~[];
         for 10.times {
             let ((rc1,rp1),(rc2,rp2)) = (pipes::stream(),pipes::stream());
-            reader_convos.push((rc1,rp2));
+            reader_convos.push((move rc1, move rp2));
             let arcn = ~arc.clone();
-            do task::spawn {
+            do task::spawn |move rp1, move rc2, move arcn| {
                 rp1.recv(); // wait for downgrader to give go-ahead
                 do arcn.read |state| {
                     assert *state == 31337;
@@ -684,7 +685,7 @@ mod tests {
         // Writer task
         let arc2 = ~arc.clone();
         let ((wc1,wp1),(wc2,wp2)) = (pipes::stream(),pipes::stream());
-        do task::spawn {
+        do task::spawn |move arc2, move wc2, move wp1| {
             wp1.recv();
             do arc2.write_cond |state, cond| {
                 assert *state == 0;
@@ -717,7 +718,7 @@ mod tests {
                     }
                 }
             }
-            let read_mode = arc.downgrade(write_mode);
+            let read_mode = arc.downgrade(move write_mode);
             do (&read_mode).read |state| {
                 // complete handshake with other readers
                 for vec::each(reader_convos) |x| {
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 6a2ac88f714..9f40794b28a 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -244,7 +244,7 @@ fn test_arena_destructors() {
         do arena.alloc { @i };
         // Allocate something with funny size and alignment, to keep
         // things interesting.
-        do arena.alloc { [0u8, 1u8, 2u8]/3 };
+        do arena.alloc { [0u8, 1u8, 2u8] };
     }
 }
 
@@ -258,7 +258,7 @@ fn test_arena_destructors_fail() {
         do arena.alloc { @i };
         // Allocate something with funny size and alignment, to keep
         // things interesting.
-        do arena.alloc { [0u8, 1u8, 2u8]/3 };
+        do arena.alloc { [0u8, 1u8, 2u8] };
     }
     // Now, fail while allocating
     do arena.alloc::<@int> {
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index 91af4a3d653..2b8e9b6bbd9 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -96,7 +96,7 @@ struct BigBitv {
 }
 
 fn BigBitv(storage: ~[mut uint]) -> BigBitv {
-    BigBitv {storage: storage}
+    BigBitv {storage: move storage}
 }
 
 /**
@@ -223,7 +223,7 @@ pub fn Bitv (nbits: uint, init: bool) -> Bitv {
         let s = to_mut(from_elem(nelems, elem));
         Big(~BigBitv(move s))
     };
-    Bitv {rep: rep, nbits: nbits}
+    Bitv {rep: move rep, nbits: nbits}
 }
 
 priv impl Bitv {
@@ -301,7 +301,7 @@ impl Bitv {
             let st = to_mut(from_elem(self.nbits / uint_bits + 1, 0));
             let len = st.len();
             for uint::range(0, len) |i| { st[i] = b.storage[i]; };
-            Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})}
+            Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: move st})}
           }
         }
     }
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs
index c888957728a..4f79bf2b316 100644
--- a/src/libstd/cell.rs
+++ b/src/libstd/cell.rs
@@ -57,7 +57,7 @@ fn test_basic() {
     let value = value_cell.take();
     assert value == ~10;
     assert value_cell.is_empty();
-    value_cell.put_back(value);
+    value_cell.put_back(move value);
     assert !value_cell.is_empty();
 }
 
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index 1a897a2c2fa..e604b87b2af 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -52,12 +52,12 @@ pub fn DuplexStream<T: Send, U: Send>()
     let (c2, p1) = pipes::stream();
     let (c1, p2) = pipes::stream();
     (DuplexStream {
-        chan: c1,
-        port: p1
+        chan: move c1,
+        port: move p1
     },
      DuplexStream {
-         chan: c2,
-         port: p2
+         chan: move c2,
+         port: move p2
      })
 }
 
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 3df5a70a0c1..79e491e309b 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -1,21 +1,35 @@
 #[forbid(deprecated_mode)];
+use serialization;
+
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
 // cursor model. See the specification here:
 //     http://www.matroska.org/technical/specs/rfc/index.html
-use core::Option;
-use option::{Some, None};
 
-type EbmlTag = {id: uint, size: uint};
+struct EbmlTag {
+    id: uint,
+    size: uint,
+}
 
-type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint};
+struct EbmlState {
+    ebml_tag: EbmlTag,
+    tag_pos: uint,
+    data_pos: uint,
+}
 
 // FIXME (#2739): When we have module renaming, make "reader" and "writer"
 // separate modules within this file.
 
 // ebml reading
-pub type Doc = {data: @~[u8], start: uint, end: uint};
+struct Doc {
+    data: @~[u8],
+    start: uint,
+    end: uint,
+}
 
-type TaggedDoc = {tag: uint, doc: Doc};
+struct TaggedDoc {
+    tag: uint,
+    doc: Doc,
+}
 
 impl Doc: ops::Index<uint,Doc> {
     pure fn index(tag: uint) -> Doc {
@@ -49,15 +63,17 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
 }
 
 pub fn Doc(data: @~[u8]) -> Doc {
-    return {data: data, start: 0u, end: vec::len::<u8>(*data)};
+    Doc { data: data, start: 0u, end: vec::len::<u8>(*data) }
 }
 
 pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
     let elt_tag = vuint_at(*data, start);
     let elt_size = vuint_at(*data, elt_tag.next);
     let end = elt_size.next + elt_size.val;
-    return {tag: elt_tag.val,
-         doc: {data: data, start: elt_size.next, end: end}};
+    TaggedDoc {
+        tag: elt_tag.val,
+        doc: Doc { data: data, start: elt_size.next, end: end }
+    }
 }
 
 pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
@@ -67,19 +83,15 @@ pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
         let elt_size = vuint_at(*d.data, elt_tag.next);
         pos = elt_size.next + elt_size.val;
         if elt_tag.val == tg {
-            return Some::<Doc>({
-                data: d.data,
-                start: elt_size.next,
-                end: pos
-            });
+            return Some(Doc { data: d.data, start: elt_size.next, end: pos });
         }
     }
-    return None::<Doc>;
+    None
 }
 
 pub fn get_doc(d: Doc, tg: uint) -> Doc {
     match maybe_get_doc(d, tg) {
-      Some(d) => return d,
+      Some(d) => d,
       None => {
         error!("failed to find block with tag %u", tg);
         fail;
@@ -93,7 +105,8 @@ pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
         let elt_tag = vuint_at(*d.data, pos);
         let elt_size = vuint_at(*d.data, elt_tag.next);
         pos = elt_size.next + elt_size.val;
-        if !it(elt_tag.val, {data: d.data, start: elt_size.next, end: pos}) {
+        let doc = Doc { data: d.data, start: elt_size.next, end: pos };
+        if !it(elt_tag.val, doc) {
             break;
         }
     }
@@ -106,7 +119,8 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
         let elt_size = vuint_at(*d.data, elt_tag.next);
         pos = elt_size.next + elt_size.val;
         if elt_tag.val == tg {
-            if !it({data: d.data, start: elt_size.next, end: pos}) {
+            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
+            if !it(doc) {
                 break;
             }
         }
@@ -116,29 +130,29 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
 pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
 
 pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
-    return f(vec::view(*d.data, d.start, d.end));
+    f(vec::view(*d.data, d.start, d.end))
 }
 
-pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); }
+pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) }
 
 pub fn doc_as_u8(d: Doc) -> u8 {
     assert d.end == d.start + 1u;
-    return (*d.data)[d.start];
+    (*d.data)[d.start]
 }
 
 pub fn doc_as_u16(d: Doc) -> u16 {
     assert d.end == d.start + 2u;
-    return io::u64_from_be_bytes(*d.data, d.start, 2u) as u16;
+    io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
 }
 
 pub fn doc_as_u32(d: Doc) -> u32 {
     assert d.end == d.start + 4u;
-    return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32;
+    io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
 }
 
 pub fn doc_as_u64(d: Doc) -> u64 {
     assert d.end == d.start + 8u;
-    return io::u64_from_be_bytes(*d.data, d.start, 8u);
+    io::u64_from_be_bytes(*d.data, d.start, 8u)
 }
 
 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
@@ -147,10 +161,9 @@ pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
 
 // ebml writing
-type Writer_ = {writer: io::Writer, mut size_positions: ~[uint]};
-
-pub enum Writer {
-    Writer_(Writer_)
+struct Serializer {
+    writer: io::Writer,
+    priv mut size_positions: ~[uint],
 }
 
 fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
@@ -173,13 +186,13 @@ fn write_vuint(w: io::Writer, n: uint) {
     fail fmt!("vint to write too big: %?", n);
 }
 
-pub fn Writer(w: io::Writer) -> Writer {
+pub fn Serializer(w: io::Writer) -> Serializer {
     let size_positions: ~[uint] = ~[];
-    return Writer_({writer: w, mut size_positions: size_positions});
+    Serializer { writer: w, mut size_positions: size_positions }
 }
 
 // FIXME (#2741): Provide a function to write the standard ebml header.
-impl Writer {
+impl Serializer {
     fn start_tag(tag_id: uint) {
         debug!("Start tag %u", tag_id);
 
@@ -295,12 +308,7 @@ enum EbmlSerializerTag {
     EsLabel // Used only when debugging
 }
 
-trait SerializerPriv {
-    fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint);
-    fn _emit_label(label: &str);
-}
-
-impl ebml::Writer: SerializerPriv {
+priv impl Serializer {
     // used internally to emit things like the vector length and so on
     fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) {
         assert v <= 0xFFFF_FFFF_u;
@@ -318,89 +326,123 @@ impl ebml::Writer: SerializerPriv {
     }
 }
 
-impl ebml::Writer {
-    fn emit_opaque(f: fn()) {
+impl Serializer {
+    fn emit_opaque(&self, f: fn()) {
         do self.wr_tag(EsOpaque as uint) {
             f()
         }
     }
 }
 
-impl ebml::Writer: serialization::Serializer {
-    fn emit_nil() {}
+impl Serializer: serialization::Serializer {
+    fn emit_nil(&self) {}
 
-    fn emit_uint(v: uint) { self.wr_tagged_u64(EsUint as uint, v as u64); }
-    fn emit_u64(v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
-    fn emit_u32(v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
-    fn emit_u16(v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
-    fn emit_u8(v: u8)   { self.wr_tagged_u8 (EsU8  as uint, v); }
+    fn emit_uint(&self, v: uint) {
+        self.wr_tagged_u64(EsUint as uint, v as u64);
+    }
+    fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
+    fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
+    fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
+    fn emit_u8(&self, v: u8)   { self.wr_tagged_u8 (EsU8  as uint, v); }
 
-    fn emit_int(v: int) { self.wr_tagged_i64(EsInt as uint, v as i64); }
-    fn emit_i64(v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
-    fn emit_i32(v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
-    fn emit_i16(v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
-    fn emit_i8(v: i8)   { self.wr_tagged_i8 (EsI8  as uint, v); }
+    fn emit_int(&self, v: int) {
+        self.wr_tagged_i64(EsInt as uint, v as i64);
+    }
+    fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
+    fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
+    fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
+    fn emit_i8(&self, v: i8)   { self.wr_tagged_i8 (EsI8  as uint, v); }
 
-    fn emit_bool(v: bool) { self.wr_tagged_u8(EsBool as uint, v as u8) }
+    fn emit_bool(&self, v: bool) {
+        self.wr_tagged_u8(EsBool as uint, v as u8)
+    }
 
     // FIXME (#2742): implement these
-    fn emit_f64(_v: f64) { fail ~"Unimplemented: serializing an f64"; }
-    fn emit_f32(_v: f32) { fail ~"Unimplemented: serializing an f32"; }
-    fn emit_float(_v: float) { fail ~"Unimplemented: serializing a float"; }
+    fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; }
+    fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; }
+    fn emit_float(&self, _v: float) {
+        fail ~"Unimplemented: serializing a float";
+    }
+
+    fn emit_char(&self, _v: char) {
+        fail ~"Unimplemented: serializing a char";
+    }
 
-    fn emit_str(v: &str) { self.wr_tagged_str(EsStr as uint, v) }
+    fn emit_borrowed_str(&self, v: &str) {
+        self.wr_tagged_str(EsStr as uint, v)
+    }
 
-    fn emit_enum(name: &str, f: fn()) {
+    fn emit_owned_str(&self, v: &str) {
+        self.emit_borrowed_str(v)
+    }
+
+    fn emit_managed_str(&self, v: &str) {
+        self.emit_borrowed_str(v)
+    }
+
+    fn emit_borrowed(&self, f: fn()) { f() }
+    fn emit_owned(&self, f: fn()) { f() }
+    fn emit_managed(&self, f: fn()) { f() }
+
+    fn emit_enum(&self, name: &str, f: fn()) {
         self._emit_label(name);
         self.wr_tag(EsEnum as uint, f)
     }
-    fn emit_enum_variant(_v_name: &str, v_id: uint, _cnt: uint, f: fn()) {
+    fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint,
+                         f: fn()) {
         self._emit_tagged_uint(EsEnumVid, v_id);
         self.wr_tag(EsEnumBody as uint, f)
     }
-    fn emit_enum_variant_arg(_idx: uint, f: fn()) { f() }
+    fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
 
-    fn emit_vec(len: uint, f: fn()) {
+    fn emit_borrowed_vec(&self, len: uint, f: fn()) {
         do self.wr_tag(EsVec as uint) {
             self._emit_tagged_uint(EsVecLen, len);
             f()
         }
     }
 
-    fn emit_vec_elt(_idx: uint, f: fn()) {
+    fn emit_owned_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+
+    fn emit_managed_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+
+    fn emit_vec_elt(&self, _idx: uint, f: fn()) {
         self.wr_tag(EsVecElt as uint, f)
     }
 
-    fn emit_box(f: fn()) { f() }
-    fn emit_uniq(f: fn()) { f() }
-    fn emit_rec(f: fn()) { f() }
-    fn emit_rec_field(f_name: &str, _f_idx: uint, f: fn()) {
-        self._emit_label(f_name);
+    fn emit_rec(&self, f: fn()) { f() }
+    fn emit_struct(&self, _name: &str, f: fn()) { f() }
+    fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
+        self._emit_label(name);
         f()
     }
-    fn emit_tup(_sz: uint, f: fn()) { f() }
-    fn emit_tup_elt(_idx: uint, f: fn()) { f() }
-}
 
-type EbmlDeserializer_ = {mut parent: ebml::Doc,
-                          mut pos: uint};
+    fn emit_tup(&self, _len: uint, f: fn()) { f() }
+    fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
+}
 
-pub enum EbmlDeserializer {
-    EbmlDeserializer_(EbmlDeserializer_)
+struct Deserializer {
+    priv mut parent: Doc,
+    priv mut pos: uint,
 }
 
-pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer {
-    EbmlDeserializer_({mut parent: d, mut pos: d.start})
+pub fn Deserializer(d: Doc) -> Deserializer {
+    Deserializer { mut parent: d, mut pos: d.start }
 }
 
-priv impl EbmlDeserializer {
+priv impl Deserializer {
     fn _check_label(lbl: &str) {
         if self.pos < self.parent.end {
-            let {tag: r_tag, doc: r_doc} =
-                ebml::doc_at(self.parent.data, self.pos);
+            let TaggedDoc { tag: r_tag, doc: r_doc } =
+                doc_at(self.parent.data, self.pos);
+
             if r_tag == (EsLabel as uint) {
                 self.pos = r_doc.end;
-                let str = ebml::doc_as_str(r_doc);
+                let str = doc_as_str(r_doc);
                 if lbl != str {
                     fail fmt!("Expected label %s but found %s", lbl, str);
                 }
@@ -408,13 +450,13 @@ priv impl EbmlDeserializer {
         }
     }
 
-    fn next_doc(exp_tag: EbmlSerializerTag) -> ebml::Doc {
+    fn next_doc(exp_tag: EbmlSerializerTag) -> Doc {
         debug!(". next_doc(exp_tag=%?)", exp_tag);
         if self.pos >= self.parent.end {
             fail ~"no more documents in current node!";
         }
-        let {tag: r_tag, doc: r_doc} =
-            ebml::doc_at(self.parent.data, self.pos);
+        let TaggedDoc { tag: r_tag, doc: r_doc } =
+            doc_at(self.parent.data, self.pos);
         debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
                copy self.parent.start, copy self.parent.end,
                copy self.pos, r_tag, r_doc.start, r_doc.end);
@@ -427,10 +469,10 @@ priv impl EbmlDeserializer {
                       r_doc.end, self.parent.end);
         }
         self.pos = r_doc.end;
-        return r_doc;
+        r_doc
     }
 
-    fn push_doc<T>(d: ebml::Doc, f: fn() -> T) -> T{
+    fn push_doc<T>(d: Doc, f: fn() -> T) -> T{
         let old_parent = self.parent;
         let old_pos = self.pos;
         self.parent = d;
@@ -442,63 +484,76 @@ priv impl EbmlDeserializer {
     }
 
     fn _next_uint(exp_tag: EbmlSerializerTag) -> uint {
-        let r = ebml::doc_as_u32(self.next_doc(exp_tag));
+        let r = doc_as_u32(self.next_doc(exp_tag));
         debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
-        return r as uint;
+        r as uint
     }
 }
 
-impl EbmlDeserializer {
-    fn read_opaque<R>(op: fn(ebml::Doc) -> R) -> R {
+impl Deserializer {
+    fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R {
         do self.push_doc(self.next_doc(EsOpaque)) {
             op(copy self.parent)
         }
     }
 }
 
-impl EbmlDeserializer: serialization::Deserializer {
-    fn read_nil() -> () { () }
+impl Deserializer: serialization::Deserializer {
+    fn read_nil(&self) -> () { () }
 
-    fn read_u64() -> u64 { ebml::doc_as_u64(self.next_doc(EsU64)) }
-    fn read_u32() -> u32 { ebml::doc_as_u32(self.next_doc(EsU32)) }
-    fn read_u16() -> u16 { ebml::doc_as_u16(self.next_doc(EsU16)) }
-    fn read_u8 () -> u8  { ebml::doc_as_u8 (self.next_doc(EsU8 )) }
-    fn read_uint() -> uint {
-        let v = ebml::doc_as_u64(self.next_doc(EsUint));
+    fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
+    fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
+    fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
+    fn read_u8 (&self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
+    fn read_uint(&self) -> uint {
+        let v = doc_as_u64(self.next_doc(EsUint));
         if v > (core::uint::max_value as u64) {
             fail fmt!("uint %? too large for this architecture", v);
         }
-        return v as uint;
+        v as uint
     }
 
-    fn read_i64() -> i64 { ebml::doc_as_u64(self.next_doc(EsI64)) as i64 }
-    fn read_i32() -> i32 { ebml::doc_as_u32(self.next_doc(EsI32)) as i32 }
-    fn read_i16() -> i16 { ebml::doc_as_u16(self.next_doc(EsI16)) as i16 }
-    fn read_i8 () -> i8  { ebml::doc_as_u8 (self.next_doc(EsI8 )) as i8  }
-    fn read_int() -> int {
-        let v = ebml::doc_as_u64(self.next_doc(EsInt)) as i64;
+    fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 }
+    fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 }
+    fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 }
+    fn read_i8 (&self) -> i8  { doc_as_u8 (self.next_doc(EsI8 )) as i8  }
+    fn read_int(&self) -> int {
+        let v = doc_as_u64(self.next_doc(EsInt)) as i64;
         if v > (int::max_value as i64) || v < (int::min_value as i64) {
             fail fmt!("int %? out of range for this architecture", v);
         }
-        return v as int;
+        v as int
     }
 
-    fn read_bool() -> bool { ebml::doc_as_u8(self.next_doc(EsBool)) as bool }
+    fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool }
+
+    fn read_f64(&self) -> f64 { fail ~"read_f64()"; }
+    fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
+    fn read_float(&self) -> float { fail ~"read_float()"; }
 
-    fn read_f64() -> f64 { fail ~"read_f64()"; }
-    fn read_f32() -> f32 { fail ~"read_f32()"; }
-    fn read_float() -> float { fail ~"read_float()"; }
+    fn read_char(&self) -> char { fail ~"read_char()"; }
 
-    fn read_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) }
+    fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
+    fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
 
     // Compound types:
-    fn read_enum<T>(name: &str, f: fn() -> T) -> T {
+    fn read_owned<T>(&self, f: fn() -> T) -> T {
+        debug!("read_owned()");
+        f()
+    }
+
+    fn read_managed<T>(&self, f: fn() -> T) -> T {
+        debug!("read_managed()");
+        f()
+    }
+
+    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
         debug!("read_enum(%s)", name);
         self._check_label(name);
         self.push_doc(self.next_doc(EsEnum), f)
     }
 
-    fn read_enum_variant<T>(f: fn(uint) -> T) -> T {
+    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
         debug!("read_enum_variant()");
         let idx = self._next_uint(EsEnumVid);
         debug!("  idx=%u", idx);
@@ -507,13 +562,13 @@ impl EbmlDeserializer: serialization::Deserializer {
         }
     }
 
-    fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T {
+    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
         debug!("read_enum_variant_arg(idx=%u)", idx);
         f()
     }
 
-    fn read_vec<T>(f: fn(uint) -> T) -> T {
-        debug!("read_vec()");
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_owned_vec()");
         do self.push_doc(self.next_doc(EsVec)) {
             let len = self._next_uint(EsVecLen);
             debug!("  len=%u", len);
@@ -521,104 +576,69 @@ impl EbmlDeserializer: serialization::Deserializer {
         }
     }
 
-    fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T {
-        debug!("read_vec_elt(idx=%u)", idx);
-        self.push_doc(self.next_doc(EsVecElt), f)
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_managed_vec()");
+        do self.push_doc(self.next_doc(EsVec)) {
+            let len = self._next_uint(EsVecLen);
+            debug!("  len=%u", len);
+            f(len)
+        }
     }
 
-    fn read_box<T>(f: fn() -> T) -> T {
-        debug!("read_box()");
-        f()
+    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
+        debug!("read_vec_elt(idx=%u)", idx);
+        self.push_doc(self.next_doc(EsVecElt), f)
     }
 
-    fn read_uniq<T>(f: fn() -> T) -> T {
-        debug!("read_uniq()");
+    fn read_rec<T>(&self, f: fn() -> T) -> T {
+        debug!("read_rec()");
         f()
     }
 
-    fn read_rec<T>(f: fn() -> T) -> T {
-        debug!("read_rec()");
+    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
+        debug!("read_struct(name=%s)", name);
         f()
     }
 
-    fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T {
-        debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
-        self._check_label(f_name);
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
+        debug!("read_field(name=%s, idx=%u)", name, idx);
+        self._check_label(name);
         f()
     }
 
-    fn read_tup<T>(sz: uint, f: fn() -> T) -> T {
-        debug!("read_tup(sz=%u)", sz);
+    fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
+        debug!("read_tup(len=%u)", len);
         f()
     }
 
-    fn read_tup_elt<T>(idx: uint, f: fn() -> T) -> T {
+    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
         debug!("read_tup_elt(idx=%u)", idx);
         f()
     }
 }
 
-
 // ___________________________________________________________________________
 // Testing
 
-#[test]
-fn test_option_int() {
-    fn serialize_1<S: serialization::Serializer>(s: &S, v: int) {
-        s.emit_i64(v as i64);
-    }
-
-    fn serialize_0<S: serialization::Serializer>(s: &S, v: Option<int>) {
-        do s.emit_enum(~"core::option::t") {
-            match v {
-              None => s.emit_enum_variant(
-                  ~"core::option::None", 0u, 0u, || { } ),
-              Some(v0) => {
-                do s.emit_enum_variant(~"core::option::some", 1u, 1u) {
-                    s.emit_enum_variant_arg(0u, || serialize_1(s, v0));
-                }
-              }
-            }
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn test_option_int() {
+        fn test_v(v: Option<int>) {
+            debug!("v == %?", v);
+            let bytes = do io::with_bytes_writer |wr| {
+                let ebml_w = Serializer(wr);
+                v.serialize(&ebml_w)
+            };
+            let ebml_doc = Doc(@bytes);
+            let deser = Deserializer(ebml_doc);
+            let v1 = serialization::deserialize(&deser);
+            debug!("v1 == %?", v1);
+            assert v == v1;
         }
-    }
 
-    fn deserialize_1<S: serialization::Deserializer>(s: &S) -> int {
-        s.read_i64() as int
-    }
-
-    fn deserialize_0<S: serialization::Deserializer>(s: &S) -> Option<int> {
-        do s.read_enum(~"core::option::t") {
-            do s.read_enum_variant |i| {
-                match i {
-                  0 => None,
-                  1 => {
-                    let v0 = do s.read_enum_variant_arg(0u) {
-                        deserialize_1(s)
-                    };
-                    Some(v0)
-                  }
-                  _ => {
-                    fail #fmt("deserialize_0: unexpected variant %u", i);
-                  }
-                }
-            }
-        }
+        test_v(Some(22));
+        test_v(None);
+        test_v(Some(3));
     }
-
-    fn test_v(v: Option<int>) {
-        debug!("v == %?", v);
-        let bytes = do io::with_bytes_writer |wr| {
-            let ebml_w = ebml::Writer(wr);
-            serialize_0(&ebml_w, v);
-        };
-        let ebml_doc = ebml::Doc(@bytes);
-        let deser = ebml_deserializer(ebml_doc);
-        let v1 = deserialize_0(&deser);
-        debug!("v1 == %?", v1);
-        assert v == v1;
-    }
-
-    test_v(Some(22));
-    test_v(None);
-    test_v(Some(3));
 }
diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs
deleted file mode 100644
index f88aad1ac63..00000000000
--- a/src/libstd/ebml2.rs
+++ /dev/null
@@ -1,644 +0,0 @@
-#[forbid(deprecated_mode)];
-use serialization2;
-
-// Simple Extensible Binary Markup Language (ebml) reader and writer on a
-// cursor model. See the specification here:
-//     http://www.matroska.org/technical/specs/rfc/index.html
-
-struct EbmlTag {
-    id: uint,
-    size: uint,
-}
-
-struct EbmlState {
-    ebml_tag: EbmlTag,
-    tag_pos: uint,
-    data_pos: uint,
-}
-
-// FIXME (#2739): When we have module renaming, make "reader" and "writer"
-// separate modules within this file.
-
-// ebml reading
-struct Doc {
-    data: @~[u8],
-    start: uint,
-    end: uint,
-}
-
-struct TaggedDoc {
-    tag: uint,
-    doc: Doc,
-}
-
-impl Doc: ops::Index<uint,Doc> {
-    pure fn index(tag: uint) -> Doc {
-        unsafe {
-            get_doc(self, tag)
-        }
-    }
-}
-
-fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
-    let a = data[start];
-    if a & 0x80u8 != 0u8 {
-        return {val: (a & 0x7fu8) as uint, next: start + 1u};
-    }
-    if a & 0x40u8 != 0u8 {
-        return {val: ((a & 0x3fu8) as uint) << 8u |
-                 (data[start + 1u] as uint),
-             next: start + 2u};
-    } else if a & 0x20u8 != 0u8 {
-        return {val: ((a & 0x1fu8) as uint) << 16u |
-                 (data[start + 1u] as uint) << 8u |
-                 (data[start + 2u] as uint),
-             next: start + 3u};
-    } else if a & 0x10u8 != 0u8 {
-        return {val: ((a & 0x0fu8) as uint) << 24u |
-                 (data[start + 1u] as uint) << 16u |
-                 (data[start + 2u] as uint) << 8u |
-                 (data[start + 3u] as uint),
-             next: start + 4u};
-    } else { error!("vint too big"); fail; }
-}
-
-pub fn Doc(data: @~[u8]) -> Doc {
-    Doc { data: data, start: 0u, end: vec::len::<u8>(*data) }
-}
-
-pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
-    let elt_tag = vuint_at(*data, start);
-    let elt_size = vuint_at(*data, elt_tag.next);
-    let end = elt_size.next + elt_size.val;
-    TaggedDoc {
-        tag: elt_tag.val,
-        doc: Doc { data: data, start: elt_size.next, end: end }
-    }
-}
-
-pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = vuint_at(*d.data, pos);
-        let elt_size = vuint_at(*d.data, elt_tag.next);
-        pos = elt_size.next + elt_size.val;
-        if elt_tag.val == tg {
-            return Some(Doc { data: d.data, start: elt_size.next, end: pos });
-        }
-    }
-    None
-}
-
-pub fn get_doc(d: Doc, tg: uint) -> Doc {
-    match maybe_get_doc(d, tg) {
-      Some(d) => d,
-      None => {
-        error!("failed to find block with tag %u", tg);
-        fail;
-      }
-    }
-}
-
-pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = vuint_at(*d.data, pos);
-        let elt_size = vuint_at(*d.data, elt_tag.next);
-        pos = elt_size.next + elt_size.val;
-        let doc = Doc { data: d.data, start: elt_size.next, end: pos };
-        if !it(elt_tag.val, doc) {
-            break;
-        }
-    }
-}
-
-pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = vuint_at(*d.data, pos);
-        let elt_size = vuint_at(*d.data, elt_tag.next);
-        pos = elt_size.next + elt_size.val;
-        if elt_tag.val == tg {
-            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
-            if !it(doc) {
-                break;
-            }
-        }
-    }
-}
-
-pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
-
-pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
-    f(vec::view(*d.data, d.start, d.end))
-}
-
-pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) }
-
-pub fn doc_as_u8(d: Doc) -> u8 {
-    assert d.end == d.start + 1u;
-    (*d.data)[d.start]
-}
-
-pub fn doc_as_u16(d: Doc) -> u16 {
-    assert d.end == d.start + 2u;
-    io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
-}
-
-pub fn doc_as_u32(d: Doc) -> u32 {
-    assert d.end == d.start + 4u;
-    io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
-}
-
-pub fn doc_as_u64(d: Doc) -> u64 {
-    assert d.end == d.start + 8u;
-    io::u64_from_be_bytes(*d.data, d.start, 8u)
-}
-
-pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
-pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
-pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
-pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
-
-// ebml writing
-struct Serializer {
-    writer: io::Writer,
-    priv mut size_positions: ~[uint],
-}
-
-fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
-    match size {
-      1u => w.write(&[0x80u8 | (n as u8)]),
-      2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
-      3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
-                      n as u8]),
-      4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
-                      (n >> 8_u) as u8, n as u8]),
-      _ => fail fmt!("vint to write too big: %?", n)
-    };
-}
-
-fn write_vuint(w: io::Writer, n: uint) {
-    if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
-    if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
-    if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
-    if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
-    fail fmt!("vint to write too big: %?", n);
-}
-
-pub fn Serializer(w: io::Writer) -> Serializer {
-    let size_positions: ~[uint] = ~[];
-    Serializer { writer: w, mut size_positions: size_positions }
-}
-
-// FIXME (#2741): Provide a function to write the standard ebml header.
-impl Serializer {
-    fn start_tag(tag_id: uint) {
-        debug!("Start tag %u", tag_id);
-
-        // Write the enum ID:
-        write_vuint(self.writer, tag_id);
-
-        // Write a placeholder four-byte size.
-        self.size_positions.push(self.writer.tell());
-        let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
-        self.writer.write(zeroes);
-    }
-
-    fn end_tag() {
-        let last_size_pos = self.size_positions.pop();
-        let cur_pos = self.writer.tell();
-        self.writer.seek(last_size_pos as int, io::SeekSet);
-        let size = (cur_pos - last_size_pos - 4u);
-        write_sized_vuint(self.writer, size, 4u);
-        self.writer.seek(cur_pos as int, io::SeekSet);
-
-        debug!("End tag (size = %u)", size);
-    }
-
-    fn wr_tag(tag_id: uint, blk: fn()) {
-        self.start_tag(tag_id);
-        blk();
-        self.end_tag();
-    }
-
-    fn wr_tagged_bytes(tag_id: uint, b: &[u8]) {
-        write_vuint(self.writer, tag_id);
-        write_vuint(self.writer, vec::len(b));
-        self.writer.write(b);
-    }
-
-    fn wr_tagged_u64(tag_id: uint, v: u64) {
-        do io::u64_to_be_bytes(v, 8u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_u32(tag_id: uint, v: u32) {
-        do io::u64_to_be_bytes(v as u64, 4u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_u16(tag_id: uint, v: u16) {
-        do io::u64_to_be_bytes(v as u64, 2u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_u8(tag_id: uint, v: u8) {
-        self.wr_tagged_bytes(tag_id, &[v]);
-    }
-
-    fn wr_tagged_i64(tag_id: uint, v: i64) {
-        do io::u64_to_be_bytes(v as u64, 8u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_i32(tag_id: uint, v: i32) {
-        do io::u64_to_be_bytes(v as u64, 4u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_i16(tag_id: uint, v: i16) {
-        do io::u64_to_be_bytes(v as u64, 2u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_i8(tag_id: uint, v: i8) {
-        self.wr_tagged_bytes(tag_id, &[v as u8]);
-    }
-
-    fn wr_tagged_str(tag_id: uint, v: &str) {
-        str::byte_slice(v, |b| self.wr_tagged_bytes(tag_id, b));
-    }
-
-    fn wr_bytes(b: &[u8]) {
-        debug!("Write %u bytes", vec::len(b));
-        self.writer.write(b);
-    }
-
-    fn wr_str(s: &str) {
-        debug!("Write str: %?", s);
-        self.writer.write(str::to_bytes(s));
-    }
-}
-
-// FIXME (#2743): optionally perform "relaxations" on end_tag to more
-// efficiently encode sizes; this is a fixed point iteration
-
-// Set to true to generate more debugging in EBML serialization.
-// Totally lame approach.
-const debug: bool = false;
-
-enum EbmlSerializerTag {
-    EsUint, EsU64, EsU32, EsU16, EsU8,
-    EsInt, EsI64, EsI32, EsI16, EsI8,
-    EsBool,
-    EsStr,
-    EsF64, EsF32, EsFloat,
-    EsEnum, EsEnumVid, EsEnumBody,
-    EsVec, EsVecLen, EsVecElt,
-
-    EsOpaque,
-
-    EsLabel // Used only when debugging
-}
-
-priv impl Serializer {
-    // used internally to emit things like the vector length and so on
-    fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) {
-        assert v <= 0xFFFF_FFFF_u;
-        self.wr_tagged_u32(t as uint, v as u32);
-    }
-
-    fn _emit_label(label: &str) {
-        // There are various strings that we have access to, such as
-        // the name of a record field, which do not actually appear in
-        // the serialized EBML (normally).  This is just for
-        // efficiency.  When debugging, though, we can emit such
-        // labels and then they will be checked by deserializer to
-        // try and check failures more quickly.
-        if debug { self.wr_tagged_str(EsLabel as uint, label) }
-    }
-}
-
-impl Serializer {
-    fn emit_opaque(&self, f: fn()) {
-        do self.wr_tag(EsOpaque as uint) {
-            f()
-        }
-    }
-}
-
-impl Serializer: serialization2::Serializer {
-    fn emit_nil(&self) {}
-
-    fn emit_uint(&self, v: uint) {
-        self.wr_tagged_u64(EsUint as uint, v as u64);
-    }
-    fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
-    fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
-    fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
-    fn emit_u8(&self, v: u8)   { self.wr_tagged_u8 (EsU8  as uint, v); }
-
-    fn emit_int(&self, v: int) {
-        self.wr_tagged_i64(EsInt as uint, v as i64);
-    }
-    fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
-    fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
-    fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
-    fn emit_i8(&self, v: i8)   { self.wr_tagged_i8 (EsI8  as uint, v); }
-
-    fn emit_bool(&self, v: bool) {
-        self.wr_tagged_u8(EsBool as uint, v as u8)
-    }
-
-    // FIXME (#2742): implement these
-    fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; }
-    fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; }
-    fn emit_float(&self, _v: float) {
-        fail ~"Unimplemented: serializing a float";
-    }
-
-    fn emit_char(&self, _v: char) {
-        fail ~"Unimplemented: serializing a char";
-    }
-
-    fn emit_borrowed_str(&self, v: &str) {
-        self.wr_tagged_str(EsStr as uint, v)
-    }
-
-    fn emit_owned_str(&self, v: &str) {
-        self.emit_borrowed_str(v)
-    }
-
-    fn emit_managed_str(&self, v: &str) {
-        self.emit_borrowed_str(v)
-    }
-
-    fn emit_borrowed(&self, f: fn()) { f() }
-    fn emit_owned(&self, f: fn()) { f() }
-    fn emit_managed(&self, f: fn()) { f() }
-
-    fn emit_enum(&self, name: &str, f: fn()) {
-        self._emit_label(name);
-        self.wr_tag(EsEnum as uint, f)
-    }
-    fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint,
-                         f: fn()) {
-        self._emit_tagged_uint(EsEnumVid, v_id);
-        self.wr_tag(EsEnumBody as uint, f)
-    }
-    fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
-
-    fn emit_borrowed_vec(&self, len: uint, f: fn()) {
-        do self.wr_tag(EsVec as uint) {
-            self._emit_tagged_uint(EsVecLen, len);
-            f()
-        }
-    }
-
-    fn emit_owned_vec(&self, len: uint, f: fn()) {
-        self.emit_borrowed_vec(len, f)
-    }
-
-    fn emit_managed_vec(&self, len: uint, f: fn()) {
-        self.emit_borrowed_vec(len, f)
-    }
-
-    fn emit_vec_elt(&self, _idx: uint, f: fn()) {
-        self.wr_tag(EsVecElt as uint, f)
-    }
-
-    fn emit_rec(&self, f: fn()) { f() }
-    fn emit_struct(&self, _name: &str, f: fn()) { f() }
-    fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
-        self._emit_label(name);
-        f()
-    }
-
-    fn emit_tup(&self, _len: uint, f: fn()) { f() }
-    fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
-}
-
-struct Deserializer {
-    priv mut parent: Doc,
-    priv mut pos: uint,
-}
-
-pub fn Deserializer(d: Doc) -> Deserializer {
-    Deserializer { mut parent: d, mut pos: d.start }
-}
-
-priv impl Deserializer {
-    fn _check_label(lbl: &str) {
-        if self.pos < self.parent.end {
-            let TaggedDoc { tag: r_tag, doc: r_doc } =
-                doc_at(self.parent.data, self.pos);
-
-            if r_tag == (EsLabel as uint) {
-                self.pos = r_doc.end;
-                let str = doc_as_str(r_doc);
-                if lbl != str {
-                    fail fmt!("Expected label %s but found %s", lbl, str);
-                }
-            }
-        }
-    }
-
-    fn next_doc(exp_tag: EbmlSerializerTag) -> Doc {
-        debug!(". next_doc(exp_tag=%?)", exp_tag);
-        if self.pos >= self.parent.end {
-            fail ~"no more documents in current node!";
-        }
-        let TaggedDoc { tag: r_tag, doc: r_doc } =
-            doc_at(self.parent.data, self.pos);
-        debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
-               copy self.parent.start, copy self.parent.end,
-               copy self.pos, r_tag, r_doc.start, r_doc.end);
-        if r_tag != (exp_tag as uint) {
-            fail fmt!("expected EMBL doc with tag %? but found tag %?",
-                      exp_tag, r_tag);
-        }
-        if r_doc.end > self.parent.end {
-            fail fmt!("invalid EBML, child extends to 0x%x, parent to 0x%x",
-                      r_doc.end, self.parent.end);
-        }
-        self.pos = r_doc.end;
-        r_doc
-    }
-
-    fn push_doc<T>(d: Doc, f: fn() -> T) -> T{
-        let old_parent = self.parent;
-        let old_pos = self.pos;
-        self.parent = d;
-        self.pos = d.start;
-        let r = f();
-        self.parent = old_parent;
-        self.pos = old_pos;
-        move r
-    }
-
-    fn _next_uint(exp_tag: EbmlSerializerTag) -> uint {
-        let r = doc_as_u32(self.next_doc(exp_tag));
-        debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
-        r as uint
-    }
-}
-
-impl Deserializer {
-    fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R {
-        do self.push_doc(self.next_doc(EsOpaque)) {
-            op(copy self.parent)
-        }
-    }
-}
-
-impl Deserializer: serialization2::Deserializer {
-    fn read_nil(&self) -> () { () }
-
-    fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
-    fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
-    fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
-    fn read_u8 (&self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
-    fn read_uint(&self) -> uint {
-        let v = doc_as_u64(self.next_doc(EsUint));
-        if v > (core::uint::max_value as u64) {
-            fail fmt!("uint %? too large for this architecture", v);
-        }
-        v as uint
-    }
-
-    fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 }
-    fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 }
-    fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 }
-    fn read_i8 (&self) -> i8  { doc_as_u8 (self.next_doc(EsI8 )) as i8  }
-    fn read_int(&self) -> int {
-        let v = doc_as_u64(self.next_doc(EsInt)) as i64;
-        if v > (int::max_value as i64) || v < (int::min_value as i64) {
-            fail fmt!("int %? out of range for this architecture", v);
-        }
-        v as int
-    }
-
-    fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool }
-
-    fn read_f64(&self) -> f64 { fail ~"read_f64()"; }
-    fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
-    fn read_float(&self) -> float { fail ~"read_float()"; }
-
-    fn read_char(&self) -> char { fail ~"read_char()"; }
-
-    fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
-    fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
-
-    // Compound types:
-    fn read_owned<T>(&self, f: fn() -> T) -> T {
-        debug!("read_owned()");
-        f()
-    }
-
-    fn read_managed<T>(&self, f: fn() -> T) -> T {
-        debug!("read_managed()");
-        f()
-    }
-
-    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
-        debug!("read_enum(%s)", name);
-        self._check_label(name);
-        self.push_doc(self.next_doc(EsEnum), f)
-    }
-
-    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_enum_variant()");
-        let idx = self._next_uint(EsEnumVid);
-        debug!("  idx=%u", idx);
-        do self.push_doc(self.next_doc(EsEnumBody)) {
-            f(idx)
-        }
-    }
-
-    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
-        debug!("read_enum_variant_arg(idx=%u)", idx);
-        f()
-    }
-
-    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_owned_vec()");
-        do self.push_doc(self.next_doc(EsVec)) {
-            let len = self._next_uint(EsVecLen);
-            debug!("  len=%u", len);
-            f(len)
-        }
-    }
-
-    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_managed_vec()");
-        do self.push_doc(self.next_doc(EsVec)) {
-            let len = self._next_uint(EsVecLen);
-            debug!("  len=%u", len);
-            f(len)
-        }
-    }
-
-    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
-        debug!("read_vec_elt(idx=%u)", idx);
-        self.push_doc(self.next_doc(EsVecElt), f)
-    }
-
-    fn read_rec<T>(&self, f: fn() -> T) -> T {
-        debug!("read_rec()");
-        f()
-    }
-
-    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
-        debug!("read_struct(name=%s)", name);
-        f()
-    }
-
-    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
-        debug!("read_field(name=%s, idx=%u)", name, idx);
-        self._check_label(name);
-        f()
-    }
-
-    fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
-        debug!("read_tup(len=%u)", len);
-        f()
-    }
-
-    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
-        debug!("read_tup_elt(idx=%u)", idx);
-        f()
-    }
-}
-
-// ___________________________________________________________________________
-// Testing
-
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn test_option_int() {
-        fn test_v(v: Option<int>) {
-            debug!("v == %?", v);
-            let bytes = do io::with_bytes_writer |wr| {
-                let ebml_w = Serializer(wr);
-                v.serialize(&ebml_w)
-            };
-            let ebml_doc = Doc(@bytes);
-            let deser = Deserializer(ebml_doc);
-            let v1 = serialization2::deserialize(&deser);
-            debug!("v1 == %?", v1);
-            assert v == v1;
-        }
-
-        test_v(Some(22));
-        test_v(None);
-        test_v(Some(3));
-    }
-}
diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs
index 6da51571e34..8d77b88aba2 100644
--- a/src/libstd/getopts.rs
+++ b/src/libstd/getopts.rs
@@ -82,7 +82,7 @@ pub type Opt = {name: Name, hasarg: HasArg, occur: Occur};
 
 fn mkname(nm: &str) -> Name {
     let unm = str::from_slice(nm);
-    return if str::len(nm) == 1u {
+    return if nm.len() == 1u {
             Short(str::char_at(unm, 0u))
         } else { Long(unm) };
 }
@@ -114,6 +114,22 @@ impl Occur : Eq {
     pure fn ne(other: &Occur) -> bool { !self.eq(other) }
 }
 
+impl HasArg : Eq {
+    pure fn eq(other: &HasArg) -> bool {
+        (self as uint) == ((*other) as uint)
+    }
+    pure fn ne(other: &HasArg) -> bool { !self.eq(other) }
+}
+
+impl Opt : Eq {
+    pure fn eq(other: &Opt) -> bool {
+        self.name   == (*other).name   &&
+        self.hasarg == (*other).hasarg &&
+        self.occur  == (*other).occur
+    }
+    pure fn ne(other: &Opt) -> bool { !self.eq(other) }
+}
+
 /// Create an option that is required and takes an argument
 pub fn reqopt(name: &str) -> Opt {
     return {name: mkname(name), hasarg: Yes, occur: Req};
@@ -150,8 +166,29 @@ enum Optval { Val(~str), Given, }
  */
 pub type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]};
 
+impl Optval : Eq {
+    pure fn eq(other: &Optval) -> bool {
+        match self {
+            Val(ref s) => match *other { Val (ref os) => s == os,
+                                          Given => false },
+            Given       => match *other { Val(_) => false,
+                                          Given => true }
+        }
+    }
+    pure fn ne(other: &Optval) -> bool { !self.eq(other) }
+}
+
+impl Matches : Eq {
+    pure fn eq(other: &Matches) -> bool {
+        self.opts == (*other).opts &&
+        self.vals == (*other).vals &&
+        self.free == (*other).free
+    }
+    pure fn ne(other: &Matches) -> bool { !self.eq(other) }
+}
+
 fn is_arg(arg: &str) -> bool {
-    return str::len(arg) > 1u && arg[0] == '-' as u8;
+    return arg.len() > 1u && arg[0] == '-' as u8;
 }
 
 fn name_str(nm: &Name) -> ~str {
@@ -177,6 +214,35 @@ pub enum Fail_ {
     UnexpectedArgument(~str),
 }
 
+impl Fail_ : Eq {
+    // this whole thing should be easy to infer...
+    pure fn eq(other: &Fail_) -> bool {
+        match self {
+            ArgumentMissing(ref s) => {
+                match *other { ArgumentMissing(ref so)    => s == so,
+                               _                          => false }
+            }
+            UnrecognizedOption(ref s) => {
+                match *other { UnrecognizedOption(ref so) => s == so,
+                               _                          => false }
+            }
+            OptionMissing(ref s) => {
+                match *other { OptionMissing(ref so)      => s == so,
+                               _                          => false }
+            }
+            OptionDuplicated(ref s) => {
+                match *other { OptionDuplicated(ref so)   => s == so,
+                               _                          => false }
+            }
+            UnexpectedArgument(ref s) => {
+                match *other { UnexpectedArgument(ref so) => s == so,
+                               _                          => false }
+            }
+        }
+    }
+    pure fn ne(other: &Fail_) -> bool { !self.eq(other) }
+}
+
 /// Convert a `fail_` enum into an error string
 pub fn fail_str(f: Fail_) -> ~str {
     return match f {
@@ -220,7 +286,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe {
     let mut i = 0u;
     while i < l {
         let cur = args[i];
-        let curlen = str::len(cur);
+        let curlen = cur.len();
         if !is_arg(cur) {
             free.push(cur);
         } else if cur == ~"--" {
@@ -444,6 +510,194 @@ impl FailType : Eq {
     pure fn ne(other: &FailType) -> bool { !self.eq(other) }
 }
 
+/** A module which provides a way to specify descriptions and
+ *  groups of short and long option names, together.
+ */
+pub mod groups {
+
+    /** one group of options, e.g., both -h and --help, along with
+     * their shared description and properties
+     */
+    pub type OptGroup = {
+        short_name: ~str,
+        long_name: ~str,
+        hint: ~str,
+        desc: ~str,
+        hasarg: HasArg,
+        occur: Occur
+    };
+
+    impl OptGroup : Eq {
+        pure fn eq(other: &OptGroup) -> bool {
+            self.short_name == (*other).short_name &&
+            self.long_name  == (*other).long_name  &&
+            self.hint       == (*other).hint       &&
+            self.desc       == (*other).desc       &&
+            self.hasarg     == (*other).hasarg     &&
+            self.occur      == (*other).occur
+        }
+        pure fn ne(other: &OptGroup) -> bool { !self.eq(other) }
+    }
+
+    /// Create a long option that is required and takes an argument
+    pub fn reqopt(short_name: &str, long_name: &str,
+                  desc: &str, hint: &str) -> OptGroup {
+        let len = short_name.len();
+        assert len == 1 || len == 0;
+        return {short_name: str::from_slice(short_name),
+                long_name: str::from_slice(long_name),
+                hint: str::from_slice(hint),
+                desc: str::from_slice(desc),
+                hasarg: Yes,
+                occur: Req};
+    }
+
+    /// Create a long option that is optional and takes an argument
+    pub fn optopt(short_name: &str, long_name: &str,
+                  desc: &str, hint: &str) -> OptGroup {
+        let len = short_name.len();
+        assert len == 1 || len == 0;
+        return {short_name: str::from_slice(short_name),
+                long_name: str::from_slice(long_name),
+                hint: str::from_slice(hint),
+                desc: str::from_slice(desc),
+                hasarg: Yes,
+                occur: Optional};
+    }
+
+    /// Create a long option that is optional and does not take an argument
+    pub fn optflag(short_name: &str, long_name: &str,
+                   desc: &str) -> OptGroup {
+        let len = short_name.len();
+        assert len == 1 || len == 0;
+        return {short_name: str::from_slice(short_name),
+                long_name: str::from_slice(long_name),
+                hint: ~"",
+                desc: str::from_slice(desc),
+                hasarg: No,
+                occur: Optional};
+    }
+
+    /// Create a long option that is optional and takes an optional argument
+    pub fn optflagopt(short_name: &str, long_name: &str,
+                      desc: &str, hint: &str) -> OptGroup {
+        let len = short_name.len();
+        assert len == 1 || len == 0;
+        return {short_name: str::from_slice(short_name),
+                long_name: str::from_slice(long_name),
+                hint: str::from_slice(hint),
+                desc: str::from_slice(desc),
+                hasarg: Maybe,
+                occur: Optional};
+    }
+
+    /**
+     * Create a long option that is optional, takes an argument, and may occur
+     * multiple times
+     */
+    pub fn optmulti(short_name: &str, long_name: &str,
+                    desc: &str, hint: &str) -> OptGroup {
+        let len = short_name.len();
+        assert len == 1 || len == 0;
+        return {short_name: str::from_slice(short_name),
+                long_name: str::from_slice(long_name),
+                hint: str::from_slice(hint),
+                desc: str::from_slice(desc),
+                hasarg: Yes,
+                occur: Multi};
+    }
+
+    // translate OptGroup into Opt
+    // (both short and long names correspond to different Opts)
+    pub fn long_to_short(lopt: &OptGroup) -> ~[Opt] {
+        match ((*lopt).short_name.len(),
+               (*lopt).long_name.len()) {
+
+           (0,0) => fail ~"this long-format option was given no name",
+
+           (0,_) => ~[{name:   Long(((*lopt).long_name)),
+                       hasarg: (*lopt).hasarg,
+                       occur:  (*lopt).occur}],
+
+           (1,0) => ~[{name:  Short(str::char_at((*lopt).short_name, 0)),
+                       hasarg: (*lopt).hasarg,
+                       occur:  (*lopt).occur}],
+
+           (1,_) => ~[{name:   Short(str::char_at((*lopt).short_name, 0)),
+                       hasarg: (*lopt).hasarg,
+                       occur:  (*lopt).occur},
+                      {name:   Long(((*lopt).long_name)),
+                       hasarg: (*lopt).hasarg,
+                       occur:  (*lopt).occur}],
+
+           (_,_) => fail ~"something is wrong with the long-form opt"
+        }
+    }
+
+    /*
+     * Parse command line args with the provided long format options
+     */
+    pub fn getopts(args: &[~str], opts: &[OptGroup]) -> Result {
+        ::getopts::getopts(args, vec::flat_map(opts, long_to_short))
+    }
+
+    /**
+     * Derive a usage message from a set of long options
+     */
+    pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
+
+        let desc_sep = ~"\n" + str::repeat(~" ", 24);
+
+        let rows = vec::map(opts, |optref| {
+            let short_name = (*optref).short_name;
+            let long_name = (*optref).long_name;
+            let hint = (*optref).hint;
+            let desc = (*optref).desc;
+            let hasarg = (*optref).hasarg;
+
+            let mut row = str::repeat(~" ", 4);
+
+            // short option
+            row += match short_name.len() {
+                0 => ~"",
+                1 => ~"-" + short_name + " ",
+                _ => fail ~"the short name should only be 1 char long",
+            };
+
+            // long option
+            row += match long_name.len() {
+                0 => ~"",
+                _ => ~"--" + long_name + " ",
+            };
+
+            // arg
+            row += match hasarg {
+                No    => ~"",
+                Yes   => hint,
+                Maybe => ~"[" + hint + ~"]",
+            };
+
+            // here we just need to indent the start of the description
+            let rowlen = row.len();
+            row += if rowlen < 24 {
+                str::repeat(~" ", 24 - rowlen)
+            } else {
+                desc_sep
+            };
+
+            // wrapped description
+            row += str::connect(str::split_within(desc, 54), desc_sep);
+
+            row
+        });
+
+        return str::from_slice(brief)    +
+               ~"\n\nOptions:\n"         +
+               str::connect(rows, ~"\n") +
+               ~"\n\n";
+    }
+} // end groups module
+
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
@@ -943,6 +1197,158 @@ mod tests {
         assert opts_present(matches, ~[~"L"]);
         assert opts_str(matches, ~[~"L"]) == ~"foo";
     }
+
+    #[test]
+    fn test_groups_reqopt() {
+        let opt = groups::reqopt(~"b", ~"banana", ~"some bananas", ~"VAL");
+        assert opt == { short_name: ~"b",
+                        long_name: ~"banana",
+                        hint: ~"VAL",
+                        desc: ~"some bananas",
+                        hasarg: Yes,
+                        occur: Req }
+    }
+
+    #[test]
+    fn test_groups_optopt() {
+        let opt = groups::optopt(~"a", ~"apple", ~"some apples", ~"VAL");
+        assert opt == { short_name: ~"a",
+                        long_name: ~"apple",
+                        hint: ~"VAL",
+                        desc: ~"some apples",
+                        hasarg: Yes,
+                        occur: Optional }
+    }
+
+    #[test]
+    fn test_groups_optflag() {
+        let opt = groups::optflag(~"k", ~"kiwi", ~"some kiwis");
+        assert opt == { short_name: ~"k",
+                        long_name: ~"kiwi",
+                        hint: ~"",
+                        desc: ~"some kiwis",
+                        hasarg: No,
+                        occur: Optional }
+    }
+
+    #[test]
+    fn test_groups_optflagopt() {
+        let opt = groups::optflagopt(~"p", ~"pineapple",
+                                       ~"some pineapples", ~"VAL");
+        assert opt == { short_name: ~"p",
+                        long_name: ~"pineapple",
+                        hint: ~"VAL",
+                        desc: ~"some pineapples",
+                        hasarg: Maybe,
+                        occur: Optional }
+    }
+
+    #[test]
+    fn test_groups_optmulti() {
+        let opt = groups::optmulti(~"l", ~"lime",
+                                     ~"some limes", ~"VAL");
+        assert opt == { short_name: ~"l",
+                        long_name: ~"lime",
+                        hint: ~"VAL",
+                        desc: ~"some limes",
+                        hasarg: Yes,
+                        occur: Multi }
+    }
+
+    #[test]
+    fn test_groups_long_to_short() {
+        let short = ~[reqopt(~"b"), reqopt(~"banana")];
+        let verbose = groups::reqopt(~"b", ~"banana",
+                                       ~"some bananas", ~"VAL");
+
+        assert groups::long_to_short(&verbose) == short;
+    }
+
+    #[test]
+    fn test_groups_getopts() {
+        let short = ~[
+            reqopt(~"b"), reqopt(~"banana"),
+            optopt(~"a"), optopt(~"apple"),
+            optflag(~"k"), optflagopt(~"kiwi"),
+            optflagopt(~"p"),
+            optmulti(~"l")
+        ];
+
+        let verbose = ~[
+            groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"),
+            groups::optopt(~"a", ~"apple", ~"Desc", ~"VAL"),
+            groups::optflag(~"k", ~"kiwi", ~"Desc"),
+            groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"),
+            groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"),
+        ];
+
+        let sample_args = ~[~"-k", ~"15", ~"--apple", ~"1", ~"k",
+                            ~"-p", ~"16", ~"l", ~"35"];
+
+        // NOTE: we should sort before comparing
+        assert getopts(sample_args, short)
+            == groups::getopts(sample_args, verbose);
+    }
+
+    #[test]
+    fn test_groups_usage() {
+        let optgroups = ~[
+            groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"),
+            groups::optopt(~"a", ~"012345678901234567890123456789",
+                             ~"Desc", ~"VAL"),
+            groups::optflag(~"k", ~"kiwi", ~"Desc"),
+            groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"),
+            groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"),
+        ];
+
+        let expected =
+~"Usage: fruits
+
+Options:
+    -b --banana VAL     Desc
+    -a --012345678901234567890123456789 VAL
+                        Desc
+    -k --kiwi           Desc
+    -p [VAL]            Desc
+    -l VAL              Desc
+
+";
+
+        let generated_usage = groups::usage(~"Usage: fruits", optgroups);
+
+        debug!("expected: <<%s>>", expected);
+        debug!("generated: <<%s>>", generated_usage);
+        assert generated_usage == expected;
+    }
+
+    #[test]
+    fn test_groups_usage_description_wrapping() {
+        // indentation should be 24 spaces
+        // lines wrap after 78: or rather descriptions wrap after 54
+
+        let optgroups = ~[
+           groups::optflag(~"k", ~"kiwi",
+           ~"This is a long description which won't be wrapped..+.."), // 54
+           groups::optflag(~"a", ~"apple",
+           ~"This is a long description which _will_ be wrapped..+.."), // 55
+        ];
+
+        let expected =
+~"Usage: fruits
+
+Options:
+    -k --kiwi           This is a long description which won't be wrapped..+..
+    -a --apple          This is a long description which _will_ be
+                        wrapped..+..
+
+";
+
+        let usage = groups::usage(~"Usage: fruits", optgroups);
+
+        debug!("expected: <<%s>>", expected);
+        debug!("generated: <<%s>>", usage);
+        assert usage == expected
+    }
 }
 
 // Local Variables:
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 09d00216209..5f64389e583 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -51,7 +51,7 @@ fn escape_str(s: &str) -> ~str {
 
 fn spaces(n: uint) -> ~str {
     let mut ss = ~"";
-    for n.times { str::push_str(&ss, " "); }
+    for n.times { str::push_str(&mut ss, " "); }
     return ss;
 }
 
@@ -63,7 +63,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer {
     Serializer { wr: wr }
 }
 
-pub impl Serializer: serialization2::Serializer {
+pub impl Serializer: serialization::Serializer {
     fn emit_nil(&self) { self.wr.write_str("null") }
 
     fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
@@ -167,7 +167,7 @@ pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer {
     PrettySerializer { wr: wr, indent: 0 }
 }
 
-pub impl PrettySerializer: serialization2::Serializer {
+pub impl PrettySerializer: serialization::Serializer {
     fn emit_nil(&self) { self.wr.write_str("null") }
 
     fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
@@ -273,8 +273,36 @@ pub impl PrettySerializer: serialization2::Serializer {
     }
 }
 
-pub impl Json: serialization2::Serializable {
-    fn serialize<S: serialization2::Serializer>(&self, s: &S) {
+#[cfg(stage0)]
+pub impl Json: serialization::Serializable {
+    fn serialize<S: serialization::Serializer>(&self, s: &S) {
+        match *self {
+            Number(v) => v.serialize(s),
+            String(ref v) => v.serialize(s),
+            Boolean(v) => v.serialize(s),
+            List(v) => v.serialize(s),
+            Object(ref v) => {
+                do s.emit_rec || {
+                    let mut idx = 0;
+                    for v.each |key, value| {
+                        do s.emit_field(*key, idx) {
+                            value.serialize(s);
+                        }
+                        idx += 1;
+                    }
+                }
+            },
+            Null => s.emit_nil(),
+        }
+    }
+}
+
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub impl<
+    S: serialization::Serializer
+> Json: serialization::Serializable<S> {
+    fn serialize(&self, s: &S) {
         match *self {
             Number(v) => v.serialize(s),
             String(ref v) => v.serialize(s),
@@ -302,7 +330,8 @@ pub fn to_writer(wr: io::Writer, json: &Json) {
 }
 
 /// Serializes a json value into a string
-pub fn to_str(json: &Json) -> ~str {
+pub pure fn to_str(json: &Json) -> ~str unsafe {
+    // ugh, should be safe
     io::with_str_writer(|wr| to_writer(wr, json))
 }
 
@@ -328,8 +357,8 @@ pub fn Parser(rdr: io::Reader) -> Parser {
     Parser {
         rdr: rdr,
         ch: rdr.read_char(),
-        line: 1u,
-        col: 1u,
+        line: 1,
+        col: 1,
     }
 }
 
@@ -341,7 +370,7 @@ pub impl Parser {
             self.parse_whitespace();
             // Make sure there is no trailing characters.
             if self.eof() {
-                Ok(value)
+                Ok(move value)
             } else {
                 self.error(~"trailing characters")
             }
@@ -546,14 +575,14 @@ priv impl Parser {
 
             if (escape) {
                 match self.ch {
-                  '"' => str::push_char(&res, '"'),
-                  '\\' => str::push_char(&res, '\\'),
-                  '/' => str::push_char(&res, '/'),
-                  'b' => str::push_char(&res, '\x08'),
-                  'f' => str::push_char(&res, '\x0c'),
-                  'n' => str::push_char(&res, '\n'),
-                  'r' => str::push_char(&res, '\r'),
-                  't' => str::push_char(&res, '\t'),
+                  '"' => str::push_char(&mut res, '"'),
+                  '\\' => str::push_char(&mut res, '\\'),
+                  '/' => str::push_char(&mut res, '/'),
+                  'b' => str::push_char(&mut res, '\x08'),
+                  'f' => str::push_char(&mut res, '\x0c'),
+                  'n' => str::push_char(&mut res, '\n'),
+                  'r' => str::push_char(&mut res, '\r'),
+                  't' => str::push_char(&mut res, '\t'),
                   'u' => {
                       // Parse \u1234.
                       let mut i = 0u;
@@ -582,7 +611,7 @@ priv impl Parser {
                             ~"invalid \\u escape (not four digits)");
                       }
 
-                      str::push_char(&res, n as char);
+                      str::push_char(&mut res, n as char);
                   }
                   _ => return self.error(~"invalid escape")
                 }
@@ -594,7 +623,7 @@ priv impl Parser {
                     self.bump();
                     return Ok(res);
                 }
-                str::push_char(&res, self.ch);
+                str::push_char(&mut res, self.ch);
             }
         }
 
@@ -609,12 +638,12 @@ priv impl Parser {
 
         if self.ch == ']' {
             self.bump();
-            return Ok(List(values));
+            return Ok(List(move values));
         }
 
         loop {
             match move self.parse_value() {
-              Ok(move v) => values.push(v),
+              Ok(move v) => values.push(move v),
               Err(move e) => return Err(e)
             }
 
@@ -625,7 +654,7 @@ priv impl Parser {
 
             match self.ch {
               ',' => self.bump(),
-              ']' => { self.bump(); return Ok(List(values)); }
+              ']' => { self.bump(); return Ok(List(move values)); }
               _ => return self.error(~"expected `,` or `]`")
             }
         };
@@ -639,7 +668,7 @@ priv impl Parser {
 
         if self.ch == '}' {
           self.bump();
-          return Ok(Object(values));
+          return Ok(Object(move values));
         }
 
         while !self.eof() {
@@ -663,14 +692,14 @@ priv impl Parser {
             self.bump();
 
             match move self.parse_value() {
-              Ok(move value) => { values.insert(key, value); }
+              Ok(move value) => { values.insert(key, move value); }
               Err(move e) => return Err(e)
             }
             self.parse_whitespace();
 
             match self.ch {
               ',' => self.bump(),
-              '}' => { self.bump(); return Ok(Object(values)); }
+              '}' => { self.bump(); return Ok(Object(move values)); }
               _ => {
                   if self.eof() { break; }
                   return self.error(~"expected `,` or `}`");
@@ -702,7 +731,7 @@ pub struct Deserializer {
 pub fn Deserializer(rdr: io::Reader) -> Result<Deserializer, Error> {
     match move from_reader(rdr) {
         Ok(move json) => {
-            let des = Deserializer { json: json, stack: ~[] };
+            let des = Deserializer { json: move json, stack: ~[] };
             Ok(move des)
         }
         Err(move e) => Err(e)
@@ -721,7 +750,7 @@ priv impl Deserializer {
     }
 }
 
-pub impl Deserializer: serialization2::Deserializer {
+pub impl Deserializer: serialization::Deserializer {
     fn read_nil(&self) -> () {
         debug!("read_nil");
         match *self.pop() {
@@ -818,7 +847,7 @@ pub impl Deserializer: serialization2::Deserializer {
         };
         let res = f(len);
         self.pop();
-        res
+        move res
     }
 
     fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
@@ -829,7 +858,7 @@ pub impl Deserializer: serialization2::Deserializer {
         };
         let res = f(len);
         self.pop();
-        res
+        move res
     }
 
     fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
@@ -850,14 +879,14 @@ pub impl Deserializer: serialization2::Deserializer {
         debug!("read_rec()");
         let value = f();
         self.pop();
-        value
+        move value
     }
 
     fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T {
         debug!("read_struct()");
         let value = f();
         self.pop();
-        value
+        move value
     }
 
     fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
@@ -868,7 +897,7 @@ pub impl Deserializer: serialization2::Deserializer {
                 // FIXME(#3148) This hint should not be necessary.
                 let obj: &self/~Object = obj;
 
-                match obj.find_ref(&name.to_unique()) {
+                match obj.find_ref(&name.to_owned()) {
                     None => fail fmt!("no such field: %s", name),
                     Some(json) => {
                         self.stack.push(json);
@@ -890,7 +919,7 @@ pub impl Deserializer: serialization2::Deserializer {
         debug!("read_tup(len=%u)", len);
         let value = f();
         self.pop();
-        value
+        move value
     }
 
     fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
@@ -1166,11 +1195,11 @@ impl <A: ToJson> Option<A>: ToJson {
 }
 
 impl Json: to_str::ToStr {
-    fn to_str() -> ~str { to_str(&self) }
+    pure fn to_str() -> ~str { to_str(&self) }
 }
 
 impl Error: to_str::ToStr {
-    fn to_str() -> ~str {
+    pure fn to_str() -> ~str {
         fmt!("%u:%u: %s", self.line, self.col, *self.msg)
     }
 }
@@ -1182,11 +1211,11 @@ mod tests {
 
         for items.each |item| {
             match *item {
-                (copy key, copy value) => { d.insert(key, value); },
+                (copy key, copy value) => { d.insert(key, move value); },
             }
         };
 
-        Object(d)
+        Object(move d)
     }
 
     #[test]
diff --git a/src/libstd/map.rs b/src/libstd/map.rs
index 765d40339d3..e49f1abd02b 100644
--- a/src/libstd/map.rs
+++ b/src/libstd/map.rs
@@ -341,7 +341,8 @@ pub mod chained {
             wr.write_str(~" }");
         }
 
-        fn to_str() -> ~str {
+        pure fn to_str() -> ~str unsafe {
+            // Meh -- this should be safe
             do io::with_str_writer |wr| { self.to_writer(wr) }
         }
     }
@@ -722,7 +723,7 @@ mod tests {
         let map = map::HashMap::<~str, ~str>();
         assert (option::is_none(&map.find(key)));
         map.insert(key, ~"val");
-        assert (option::get(&map.find(key)) == ~"val");
+        assert (option::get(map.find(key)) == ~"val");
     }
 
     #[test]
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index 2d9dd5bdf4e..5d78fb19bab 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -10,8 +10,10 @@ use addrinfo = uv::ll::addrinfo;
 use uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t;
 use uv_ip4_addr = uv::ll::ip4_addr;
 use uv_ip4_name = uv::ll::ip4_name;
+use uv_ip4_port = uv::ll::ip4_port;
 use uv_ip6_addr = uv::ll::ip6_addr;
 use uv_ip6_name = uv::ll::ip6_name;
+use uv_ip6_port = uv::ll::ip6_port;
 use uv_getaddrinfo = uv::ll::getaddrinfo;
 use uv_freeaddrinfo = uv::ll::freeaddrinfo;
 use create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t;
@@ -33,11 +35,11 @@ type ParseAddrErr = {
 };
 
 /**
- * Convert a `ip_addr` to a str
+ * Convert a `IpAddr` to a str
  *
  * # Arguments
  *
- * * ip - a `std::net::ip::ip_addr`
+ * * ip - a `std::net::ip::IpAddr`
  */
 pub fn format_addr(ip: &IpAddr) -> ~str {
     match *ip {
@@ -58,6 +60,23 @@ pub fn format_addr(ip: &IpAddr) -> ~str {
     }
 }
 
+/**
+ * Get the associated port
+ *
+ * # Arguments
+ * * ip - a `std::net::ip::IpAddr`
+ */
+pub fn get_port(ip: &IpAddr) -> uint {
+    match *ip {
+        Ipv4(ref addr) => unsafe {
+            uv_ip4_port(addr)
+        },
+        Ipv6(ref addr) => unsafe {
+            uv_ip6_port(addr)
+        }
+    }
+}
+
 /// Represents errors returned from `net::ip::get_addr()`
 enum IpGetAddrErr {
     GetAddrUnknownError
@@ -128,7 +147,7 @@ pub mod v4 {
      */
     pub fn parse_addr(ip: &str) -> IpAddr {
         match try_parse_addr(ip) {
-          result::Ok(copy addr) => addr,
+          result::Ok(move addr) => move addr,
           result::Err(ref err_data) => fail err_data.err_msg
         }
     }
@@ -214,7 +233,7 @@ pub mod v6 {
      */
     pub fn parse_addr(ip: &str) -> IpAddr {
         match try_parse_addr(ip) {
-          result::Ok(copy addr) => addr,
+          result::Ok(move addr) => move addr,
           result::Err(copy err_data) => fail err_data.err_msg
         }
     }
@@ -353,7 +372,7 @@ mod test {
         }
         // note really sure how to realiably test/assert
         // this.. mostly just wanting to see it work, atm.
-        let results = result::unwrap(ga_result);
+        let results = result::unwrap(move ga_result);
         log(debug, fmt!("test_get_addr: Number of results for %s: %?",
                         localhost_name, vec::len(results)));
         for vec::each(results) |r| {
@@ -366,7 +385,7 @@ mod test {
         }
         // at least one result.. this is going to vary from system
         // to system, based on stuff like the contents of /etc/hosts
-        assert vec::len(results) > 0;
+        assert !results.is_empty();
     }
     #[test]
     #[ignore(reason = "valgrind says it's leaky")]
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index 249551fbb7d..942d52a3ad6 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -6,9 +6,7 @@ use ip = net_ip;
 use uv::iotask;
 use uv::iotask::IoTask;
 use future_spawn = future::spawn;
-// FIXME #1935
-// should be able to, but can't atm, replace w/ result::{result, extensions};
-use result::*;
+use result::{Result};
 use libc::size_t;
 use io::{Reader, ReaderUtil, Writer};
 use comm = core::comm;
@@ -136,6 +134,10 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
         stream_handle_ptr: stream_handle_ptr,
         connect_req: uv::ll::connect_t(),
         write_req: uv::ll::write_t(),
+        ipv6: match input_ip {
+            ip::Ipv4(_) => { false }
+            ip::Ipv6(_) => { true }
+        },
         iotask: iotask
     };
     let socket_data_ptr = ptr::addr_of(&(*socket_data));
@@ -477,6 +479,7 @@ pub fn accept(new_conn: TcpNewConnection)
             stream_handle_ptr : stream_handle_ptr,
             connect_req : uv::ll::connect_t(),
             write_req : uv::ll::write_t(),
+            ipv6: (*server_data_ptr).ipv6,
             iotask : iotask
         };
         let client_socket_data_ptr = ptr::addr_of(&(*client_socket_data));
@@ -564,7 +567,8 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint,
           new_connect_cb: fn~(TcpNewConnection,
                                comm::Chan<Option<TcpErrData>>))
     -> result::Result<(), TcpListenErrData> unsafe {
-    do listen_common(move host_ip, port, backlog, iotask, on_establish_cb)
+    do listen_common(move host_ip, port, backlog, iotask,
+                     move on_establish_cb)
         // on_connect_cb
         |move new_connect_cb, handle| unsafe {
             let server_data_ptr = uv::ll::get_data_for_uv_handle(handle)
@@ -591,6 +595,10 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint,
         kill_ch: kill_ch,
         on_connect_cb: move on_connect_cb,
         iotask: iotask,
+        ipv6: match host_ip {
+            ip::Ipv4(_) => { false }
+            ip::Ipv6(_) => { true }
+        },
         mut active: true
     };
     let server_data_ptr = ptr::addr_of(&server_data);
@@ -747,6 +755,21 @@ impl TcpSocket {
         -> future::Future<result::Result<(), TcpErrData>> {
         write_future(&self, raw_write_data)
     }
+    pub fn get_peer_addr() -> ip::IpAddr {
+        unsafe {
+            if self.socket_data.ipv6 {
+                let addr = uv::ll::ip6_addr("", 0);
+                uv::ll::tcp_getpeername6(self.socket_data.stream_handle_ptr,
+                                         ptr::addr_of(&addr));
+                ip::Ipv6(move addr)
+            } else {
+                let addr = uv::ll::ip4_addr("", 0);
+                uv::ll::tcp_getpeername(self.socket_data.stream_handle_ptr,
+                                        ptr::addr_of(&addr));
+                ip::Ipv4(move addr)
+            }
+        }
+    }
 }
 
 /// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
@@ -1004,6 +1027,7 @@ type TcpListenFcData = {
     kill_ch: comm::Chan<Option<TcpErrData>>,
     on_connect_cb: fn~(*uv::ll::uv_tcp_t),
     iotask: IoTask,
+    ipv6: bool,
     mut active: bool
 };
 
@@ -1093,7 +1117,7 @@ extern fn on_tcp_read_cb(stream: *uv::ll::uv_stream_t,
         log(debug, fmt!("tcp on_read_cb nread: %d", nread as int));
         let reader_ch = (*socket_data_ptr).reader_ch;
         let buf_base = uv::ll::get_base_from_buf(buf);
-        let new_bytes = vec::raw::from_buf(buf_base, nread as uint);
+        let new_bytes = vec::from_buf(buf_base, nread as uint);
         core::comm::send(reader_ch, result::Ok(new_bytes));
       }
     }
@@ -1202,6 +1226,7 @@ type TcpSocketData = {
     stream_handle_ptr: *uv::ll::uv_tcp_t,
     connect_req: uv::ll::uv_connect_t,
     write_req: uv::ll::uv_write_t,
+    ipv6: bool,
     iotask: IoTask
 };
 
@@ -1224,6 +1249,10 @@ mod test {
                 impl_gl_tcp_ipv4_server_and_client();
             }
             #[test]
+            fn test_gl_tcp_get_peer_addr() unsafe {
+                impl_gl_tcp_ipv4_get_peer_addr();
+            }
+            #[test]
             fn test_gl_tcp_ipv4_client_error_connection_refused() unsafe {
                 impl_gl_tcp_ipv4_client_error_connection_refused();
             }
@@ -1250,6 +1279,11 @@ mod test {
             }
             #[test]
             #[ignore(cfg(target_os = "linux"))]
+            fn test_gl_tcp_get_peer_addr() unsafe {
+                impl_gl_tcp_ipv4_get_peer_addr();
+            }
+            #[test]
+            #[ignore(cfg(target_os = "linux"))]
             fn test_gl_tcp_ipv4_client_error_connection_refused() unsafe {
                 impl_gl_tcp_ipv4_client_error_connection_refused();
             }
@@ -1317,6 +1351,53 @@ mod test {
         assert str::contains(actual_req, expected_req);
         assert str::contains(actual_resp, expected_resp);
     }
+    fn impl_gl_tcp_ipv4_get_peer_addr() {
+        let hl_loop = uv::global_loop::get();
+        let server_ip = ~"127.0.0.1";
+        let server_port = 8887u;
+        let expected_resp = ~"pong";
+
+        let server_result_po = core::comm::Port::<~str>();
+        let server_result_ch = core::comm::Chan(&server_result_po);
+
+        let cont_po = core::comm::Port::<()>();
+        let cont_ch = core::comm::Chan(&cont_po);
+        // server
+        do task::spawn_sched(task::ManualThreads(1u)) {
+            let actual_req = do comm::listen |server_ch| {
+                run_tcp_test_server(
+                    server_ip,
+                    server_port,
+                    expected_resp,
+                    server_ch,
+                    cont_ch,
+                    hl_loop)
+            };
+            server_result_ch.send(actual_req);
+        };
+        core::comm::recv(cont_po);
+        // client
+        log(debug, ~"server started, firing up client..");
+        do core::comm::listen |client_ch| {
+            let server_ip_addr = ip::v4::parse_addr(server_ip);
+            let iotask = uv::global_loop::get();
+            let connect_result = connect(move server_ip_addr, server_port,
+                                         iotask);
+
+            let sock = result::unwrap(move connect_result);
+
+            // This is what we are actually testing!
+            assert net::ip::format_addr(&sock.get_peer_addr()) ==
+                ~"127.0.0.1";
+            assert net::ip::get_port(&sock.get_peer_addr()) == 8887;
+
+            // Fulfill the protocol the test server expects
+            let resp_bytes = str::to_bytes(~"ping");
+            tcp_write_single(&sock, resp_bytes);
+            let read_result = sock.read(0u);
+            client_ch.send(str::from_bytes(read_result.get()));
+        };
+    }
     fn impl_gl_tcp_ipv4_client_error_connection_refused() {
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
@@ -1512,8 +1593,11 @@ mod test {
                             ~"SERVER/WORKER: send on cont ch");
                         cont_ch.send(());
                         let sock = result::unwrap(move accept_result);
+                        let peer_addr = sock.get_peer_addr();
                         log(debug, ~"SERVER: successfully accepted"+
-                            ~"connection!");
+                            fmt!(" connection from %s:%u",
+                                 ip::format_addr(&peer_addr),
+                                 ip::get_port(&peer_addr)));
                         let received_req_bytes = read(&sock, 0u);
                         match move received_req_bytes {
                           result::Ok(move data) => {
diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs
index 0ab4d89f363..8ea9513d155 100644
--- a/src/libstd/net_url.rs
+++ b/src/libstd/net_url.rs
@@ -65,10 +65,10 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
                         str::push_char(&mut out, ch);
                       }
 
-                      _ => out += #fmt("%%%X", ch as uint)
+                      _ => out += fmt!("%%%X", ch as uint)
                     }
                 } else {
-                    out += #fmt("%%%X", ch as uint);
+                    out += fmt!("%%%X", ch as uint);
                 }
               }
             }
@@ -94,6 +94,7 @@ pub fn encode(s: &str) -> ~str {
  *
  * This function is compliant with RFC 3986.
  */
+
 pub fn encode_component(s: &str) -> ~str {
     encode_inner(s, false)
 }
@@ -163,7 +164,7 @@ fn encode_plus(s: &str) -> ~str {
                 str::push_char(&mut out, ch);
               }
               ' ' => str::push_char(&mut out, '+'),
-              _ => out += #fmt("%%%X", ch as uint)
+              _ => out += fmt!("%%%X", ch as uint)
             }
         }
 
@@ -189,7 +190,7 @@ pub fn encode_form_urlencoded(m: HashMap<~str, @DVec<@~str>>) -> ~str {
                 first = false;
             }
 
-            out += #fmt("%s=%s", key, encode_plus(**value));
+            out += fmt!("%s=%s", key, encode_plus(**value));
         }
     }
 
@@ -297,7 +298,7 @@ fn userinfo_from_str(uinfo: &str) -> UserInfo {
     return UserInfo(user, pass);
 }
 
-fn userinfo_to_str(userinfo: UserInfo) -> ~str {
+pure fn userinfo_to_str(userinfo: UserInfo) -> ~str {
     if option::is_some(&userinfo.pass) {
         return str::concat(~[copy userinfo.user, ~":",
                           option::unwrap(copy userinfo.pass),
@@ -325,11 +326,15 @@ fn query_from_str(rawquery: &str) -> Query {
     return query;
 }
 
-pub fn query_to_str(query: Query) -> ~str {
+pub pure fn query_to_str(query: Query) -> ~str {
     let mut strvec = ~[];
     for query.each |kv| {
         let (k, v) = copy *kv;
-        strvec += ~[#fmt("%s=%s", encode_component(k), encode_component(v))];
+        // This is really safe...
+        unsafe {
+          strvec += ~[fmt!("%s=%s",
+                           encode_component(k), encode_component(v))];
+        }
     };
     return str::connect(strvec, ~"&");
 }
@@ -672,7 +677,7 @@ impl Url : FromStr {
  * result in just "http://somehost.com".
  *
  */
-pub fn to_str(url: Url) -> ~str {
+pub pure fn to_str(url: Url) -> ~str {
     let user = if url.user.is_some() {
       userinfo_to_str(option::unwrap(copy url.user))
     } else {
@@ -688,7 +693,8 @@ pub fn to_str(url: Url) -> ~str {
     } else {
         str::concat(~[~"?", query_to_str(url.query)])
     };
-    let fragment = if url.fragment.is_some() {
+    // ugh, this really is safe
+    let fragment = if url.fragment.is_some() unsafe {
         str::concat(~[~"#", encode_component(
             option::unwrap(copy url.fragment))])
     } else {
@@ -704,7 +710,7 @@ pub fn to_str(url: Url) -> ~str {
 }
 
 impl Url: to_str::ToStr {
-    pub fn to_str() -> ~str {
+    pub pure fn to_str() -> ~str {
         to_str(self)
     }
 }
@@ -844,7 +850,7 @@ mod tests {
     fn test_url_parse_host_slash() {
         let urlstr = ~"http://0.42.42.42/";
         let url = from_str(urlstr).get();
-        #debug("url: %?", url);
+        debug!("url: %?", url);
         assert url.host == ~"0.42.42.42";
         assert url.path == ~"/";
     }
@@ -853,7 +859,7 @@ mod tests {
     fn test_url_with_underscores() {
         let urlstr = ~"http://dotcom.com/file_name.html";
         let url = from_str(urlstr).get();
-        #debug("url: %?", url);
+        debug!("url: %?", url);
         assert url.path == ~"/file_name.html";
     }
 
@@ -861,7 +867,7 @@ mod tests {
     fn test_url_with_dashes() {
         let urlstr = ~"http://dotcom.com/file-name.html";
         let url = from_str(urlstr).get();
-        #debug("url: %?", url);
+        debug!("url: %?", url);
         assert url.path == ~"/file-name.html";
     }
 
diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs
index bc528800666..6119c03cdca 100644
--- a/src/libstd/prettyprint.rs
+++ b/src/libstd/prettyprint.rs
@@ -2,131 +2,175 @@
 
 use io::Writer;
 use io::WriterUtil;
-use serialization::Serializer;
+use serialization;
 
-impl Writer: Serializer {
-    fn emit_nil() {
-        self.write_str(~"()")
+pub struct Serializer {
+    wr: io::Writer,
+}
+
+pub fn Serializer(wr: io::Writer) -> Serializer {
+    Serializer { wr: wr }
+}
+
+pub impl Serializer: serialization::Serializer {
+    fn emit_nil(&self) {
+        self.wr.write_str(~"()")
+    }
+
+    fn emit_uint(&self, v: uint) {
+        self.wr.write_str(fmt!("%?u", v));
+    }
+
+    fn emit_u64(&self, v: u64) {
+        self.wr.write_str(fmt!("%?_u64", v));
+    }
+
+    fn emit_u32(&self, v: u32) {
+        self.wr.write_str(fmt!("%?_u32", v));
+    }
+
+    fn emit_u16(&self, v: u16) {
+        self.wr.write_str(fmt!("%?_u16", v));
+    }
+
+    fn emit_u8(&self, v: u8) {
+        self.wr.write_str(fmt!("%?_u8", v));
     }
 
-    fn emit_uint(v: uint) {
-        self.write_str(fmt!("%?u", v));
+    fn emit_int(&self, v: int) {
+        self.wr.write_str(fmt!("%?", v));
     }
 
-    fn emit_u64(v: u64) {
-        self.write_str(fmt!("%?_u64", v));
+    fn emit_i64(&self, v: i64) {
+        self.wr.write_str(fmt!("%?_i64", v));
     }
 
-    fn emit_u32(v: u32) {
-        self.write_str(fmt!("%?_u32", v));
+    fn emit_i32(&self, v: i32) {
+        self.wr.write_str(fmt!("%?_i32", v));
     }
 
-    fn emit_u16(v: u16) {
-        self.write_str(fmt!("%?_u16", v));
+    fn emit_i16(&self, v: i16) {
+        self.wr.write_str(fmt!("%?_i16", v));
     }
 
-    fn emit_u8(v: u8) {
-        self.write_str(fmt!("%?_u8", v));
+    fn emit_i8(&self, v: i8) {
+        self.wr.write_str(fmt!("%?_i8", v));
     }
 
-    fn emit_int(v: int) {
-        self.write_str(fmt!("%?", v));
+    fn emit_bool(&self, v: bool) {
+        self.wr.write_str(fmt!("%b", v));
     }
 
-    fn emit_i64(v: i64) {
-        self.write_str(fmt!("%?_i64", v));
+    fn emit_float(&self, v: float) {
+        self.wr.write_str(fmt!("%?_f", v));
     }
 
-    fn emit_i32(v: i32) {
-        self.write_str(fmt!("%?_i32", v));
+    fn emit_f64(&self, v: f64) {
+        self.wr.write_str(fmt!("%?_f64", v));
     }
 
-    fn emit_i16(v: i16) {
-        self.write_str(fmt!("%?_i16", v));
+    fn emit_f32(&self, v: f32) {
+        self.wr.write_str(fmt!("%?_f32", v));
     }
 
-    fn emit_i8(v: i8) {
-        self.write_str(fmt!("%?_i8", v));
+    fn emit_char(&self, v: char) {
+        self.wr.write_str(fmt!("%?", v));
     }
 
-    fn emit_bool(v: bool) {
-        self.write_str(fmt!("%b", v));
+    fn emit_borrowed_str(&self, v: &str) {
+        self.wr.write_str(fmt!("&%?", v));
     }
 
-    fn emit_float(v: float) {
-        self.write_str(fmt!("%?_f", v));
+    fn emit_owned_str(&self, v: &str) {
+        self.wr.write_str(fmt!("~%?", v));
     }
 
-    fn emit_f64(v: f64) {
-        self.write_str(fmt!("%?_f64", v));
+    fn emit_managed_str(&self, v: &str) {
+        self.wr.write_str(fmt!("@%?", v));
     }
 
-    fn emit_f32(v: f32) {
-        self.write_str(fmt!("%?_f32", v));
+    fn emit_borrowed(&self, f: fn()) {
+        self.wr.write_str(~"&");
+        f();
     }
 
-    fn emit_str(v: &str) {
-        self.write_str(fmt!("%?", v));
+    fn emit_owned(&self, f: fn()) {
+        self.wr.write_str(~"~");
+        f();
+    }
+
+    fn emit_managed(&self, f: fn()) {
+        self.wr.write_str(~"@");
+        f();
+    }
+
+    fn emit_enum(&self, _name: &str, f: fn()) {
+        f();
     }
 
-    fn emit_enum(_name: &str, f: fn()) {
+    fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint,
+                         f: fn()) {
+        self.wr.write_str(v_name);
+        if sz > 0u { self.wr.write_str(~"("); }
         f();
+        if sz > 0u { self.wr.write_str(~")"); }
     }
 
-    fn emit_enum_variant(v_name: &str, _v_id: uint, sz: uint, f: fn()) {
-        self.write_str(v_name);
-        if sz > 0u { self.write_str(~"("); }
+    fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
-        if sz > 0u { self.write_str(~")"); }
     }
 
-    fn emit_enum_variant_arg(idx: uint, f: fn()) {
-        if idx > 0u { self.write_str(~", "); }
+    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"&[");
         f();
+        self.wr.write_str(~"]");
     }
 
-    fn emit_vec(_len: uint, f: fn()) {
-        self.write_str(~"[");
+    fn emit_owned_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"~[");
         f();
-        self.write_str(~"]");
+        self.wr.write_str(~"]");
     }
 
-    fn emit_vec_elt(idx: uint, f: fn()) {
-        if idx > 0u { self.write_str(~", "); }
+    fn emit_managed_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"@[");
         f();
+        self.wr.write_str(~"]");
     }
 
-    fn emit_box(f: fn()) {
-        self.write_str(~"@");
+    fn emit_vec_elt(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
     }
 
-    fn emit_uniq(f: fn()) {
-        self.write_str(~"~");
+    fn emit_rec(&self, f: fn()) {
+        self.wr.write_str(~"{");
         f();
+        self.wr.write_str(~"}");
     }
 
-    fn emit_rec(f: fn()) {
-        self.write_str(~"{");
+    fn emit_struct(&self, name: &str, f: fn()) {
+        self.wr.write_str(fmt!("%s {", name));
         f();
-        self.write_str(~"}");
+        self.wr.write_str(~"}");
     }
 
-    fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()) {
-        if f_idx > 0u { self.write_str(~", "); }
-        self.write_str(f_name);
-        self.write_str(~": ");
+    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
+        self.wr.write_str(name);
+        self.wr.write_str(~": ");
         f();
     }
 
-    fn emit_tup(_sz: uint, f: fn()) {
-        self.write_str(~"(");
+    fn emit_tup(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"(");
         f();
-        self.write_str(~")");
+        self.wr.write_str(~")");
     }
 
-    fn emit_tup_elt(idx: uint, f: fn()) {
-        if idx > 0u { self.write_str(~", "); }
+    fn emit_tup_elt(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
     }
 }
diff --git a/src/libstd/prettyprint2.rs b/src/libstd/prettyprint2.rs
deleted file mode 100644
index 87af519eb12..00000000000
--- a/src/libstd/prettyprint2.rs
+++ /dev/null
@@ -1,176 +0,0 @@
-#[forbid(deprecated_mode)];
-
-use io::Writer;
-use io::WriterUtil;
-use serialization2;
-
-pub struct Serializer {
-    wr: io::Writer,
-}
-
-pub fn Serializer(wr: io::Writer) -> Serializer {
-    Serializer { wr: wr }
-}
-
-pub impl Serializer: serialization2::Serializer {
-    fn emit_nil(&self) {
-        self.wr.write_str(~"()")
-    }
-
-    fn emit_uint(&self, v: uint) {
-        self.wr.write_str(fmt!("%?u", v));
-    }
-
-    fn emit_u64(&self, v: u64) {
-        self.wr.write_str(fmt!("%?_u64", v));
-    }
-
-    fn emit_u32(&self, v: u32) {
-        self.wr.write_str(fmt!("%?_u32", v));
-    }
-
-    fn emit_u16(&self, v: u16) {
-        self.wr.write_str(fmt!("%?_u16", v));
-    }
-
-    fn emit_u8(&self, v: u8) {
-        self.wr.write_str(fmt!("%?_u8", v));
-    }
-
-    fn emit_int(&self, v: int) {
-        self.wr.write_str(fmt!("%?", v));
-    }
-
-    fn emit_i64(&self, v: i64) {
-        self.wr.write_str(fmt!("%?_i64", v));
-    }
-
-    fn emit_i32(&self, v: i32) {
-        self.wr.write_str(fmt!("%?_i32", v));
-    }
-
-    fn emit_i16(&self, v: i16) {
-        self.wr.write_str(fmt!("%?_i16", v));
-    }
-
-    fn emit_i8(&self, v: i8) {
-        self.wr.write_str(fmt!("%?_i8", v));
-    }
-
-    fn emit_bool(&self, v: bool) {
-        self.wr.write_str(fmt!("%b", v));
-    }
-
-    fn emit_float(&self, v: float) {
-        self.wr.write_str(fmt!("%?_f", v));
-    }
-
-    fn emit_f64(&self, v: f64) {
-        self.wr.write_str(fmt!("%?_f64", v));
-    }
-
-    fn emit_f32(&self, v: f32) {
-        self.wr.write_str(fmt!("%?_f32", v));
-    }
-
-    fn emit_char(&self, v: char) {
-        self.wr.write_str(fmt!("%?", v));
-    }
-
-    fn emit_borrowed_str(&self, v: &str) {
-        self.wr.write_str(fmt!("&%?", v));
-    }
-
-    fn emit_owned_str(&self, v: &str) {
-        self.wr.write_str(fmt!("~%?", v));
-    }
-
-    fn emit_managed_str(&self, v: &str) {
-        self.wr.write_str(fmt!("@%?", v));
-    }
-
-    fn emit_borrowed(&self, f: fn()) {
-        self.wr.write_str(~"&");
-        f();
-    }
-
-    fn emit_owned(&self, f: fn()) {
-        self.wr.write_str(~"~");
-        f();
-    }
-
-    fn emit_managed(&self, f: fn()) {
-        self.wr.write_str(~"@");
-        f();
-    }
-
-    fn emit_enum(&self, _name: &str, f: fn()) {
-        f();
-    }
-
-    fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint,
-                         f: fn()) {
-        self.wr.write_str(v_name);
-        if sz > 0u { self.wr.write_str(~"("); }
-        f();
-        if sz > 0u { self.wr.write_str(~")"); }
-    }
-
-    fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        f();
-    }
-
-    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"&[");
-        f();
-        self.wr.write_str(~"]");
-    }
-
-    fn emit_owned_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"~[");
-        f();
-        self.wr.write_str(~"]");
-    }
-
-    fn emit_managed_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"@[");
-        f();
-        self.wr.write_str(~"]");
-    }
-
-    fn emit_vec_elt(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        f();
-    }
-
-    fn emit_rec(&self, f: fn()) {
-        self.wr.write_str(~"{");
-        f();
-        self.wr.write_str(~"}");
-    }
-
-    fn emit_struct(&self, name: &str, f: fn()) {
-        self.wr.write_str(fmt!("%s {", name));
-        f();
-        self.wr.write_str(~"}");
-    }
-
-    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        self.wr.write_str(name);
-        self.wr.write_str(~": ");
-        f();
-    }
-
-    fn emit_tup(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"(");
-        f();
-        self.wr.write_str(~")");
-    }
-
-    fn emit_tup_elt(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        f();
-    }
-}
diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs
index 8ba00e65dec..9df2a326a84 100644
--- a/src/libstd/serialization.rs
+++ b/src/libstd/serialization.rs
@@ -1,81 +1,532 @@
 //! Support code for serialization.
 
-#[allow(deprecated_mode)];
-
 /*
 Core serialization interfaces.
 */
 
+#[forbid(deprecated_mode)];
+#[forbid(non_camel_case_types)];
+
 pub trait Serializer {
     // Primitive types:
-    fn emit_nil();
-    fn emit_uint(v: uint);
-    fn emit_u64(v: u64);
-    fn emit_u32(v: u32);
-    fn emit_u16(v: u16);
-    fn emit_u8(v: u8);
-    fn emit_int(v: int);
-    fn emit_i64(v: i64);
-    fn emit_i32(v: i32);
-    fn emit_i16(v: i16);
-    fn emit_i8(v: i8);
-    fn emit_bool(v: bool);
-    fn emit_float(v: float);
-    fn emit_f64(v: f64);
-    fn emit_f32(v: f32);
-    fn emit_str(v: &str);
+    fn emit_nil(&self);
+    fn emit_uint(&self, v: uint);
+    fn emit_u64(&self, v: u64);
+    fn emit_u32(&self, v: u32);
+    fn emit_u16(&self, v: u16);
+    fn emit_u8(&self, v: u8);
+    fn emit_int(&self, v: int);
+    fn emit_i64(&self, v: i64);
+    fn emit_i32(&self, v: i32);
+    fn emit_i16(&self, v: i16);
+    fn emit_i8(&self, v: i8);
+    fn emit_bool(&self, v: bool);
+    fn emit_float(&self, v: float);
+    fn emit_f64(&self, v: f64);
+    fn emit_f32(&self, v: f32);
+    fn emit_char(&self, v: char);
+    fn emit_borrowed_str(&self, v: &str);
+    fn emit_owned_str(&self, v: &str);
+    fn emit_managed_str(&self, v: &str);
 
     // Compound types:
-    fn emit_enum(name: &str, f: fn());
-    fn emit_enum_variant(v_name: &str, v_id: uint, sz: uint, f: fn());
-    fn emit_enum_variant_arg(idx: uint, f: fn());
-    fn emit_vec(len: uint, f: fn());
-    fn emit_vec_elt(idx: uint, f: fn());
-    fn emit_box(f: fn());
-    fn emit_uniq(f: fn());
-    fn emit_rec(f: fn());
-    fn emit_rec_field(f_name: &str, f_idx: uint, f: fn());
-    fn emit_tup(sz: uint, f: fn());
-    fn emit_tup_elt(idx: uint, f: fn());
+    fn emit_borrowed(&self, f: fn());
+    fn emit_owned(&self, f: fn());
+    fn emit_managed(&self, f: fn());
+
+    fn emit_enum(&self, name: &str, f: fn());
+    fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
+    fn emit_enum_variant_arg(&self, idx: uint, f: fn());
+
+    fn emit_borrowed_vec(&self, len: uint, f: fn());
+    fn emit_owned_vec(&self, len: uint, f: fn());
+    fn emit_managed_vec(&self, len: uint, f: fn());
+    fn emit_vec_elt(&self, idx: uint, f: fn());
+
+    fn emit_rec(&self, f: fn());
+    fn emit_struct(&self, name: &str, f: fn());
+    fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
+
+    fn emit_tup(&self, len: uint, f: fn());
+    fn emit_tup_elt(&self, idx: uint, f: fn());
 }
 
 pub trait Deserializer {
     // Primitive types:
-    fn read_nil() -> ();
+    fn read_nil(&self) -> ();
+    fn read_uint(&self) -> uint;
+    fn read_u64(&self) -> u64;
+    fn read_u32(&self) -> u32;
+    fn read_u16(&self) -> u16;
+    fn read_u8(&self) -> u8;
+    fn read_int(&self) -> int;
+    fn read_i64(&self) -> i64;
+    fn read_i32(&self) -> i32;
+    fn read_i16(&self) -> i16;
+    fn read_i8(&self) -> i8;
+    fn read_bool(&self) -> bool;
+    fn read_f64(&self) -> f64;
+    fn read_f32(&self) -> f32;
+    fn read_float(&self) -> float;
+    fn read_char(&self) -> char;
+    fn read_owned_str(&self) -> ~str;
+    fn read_managed_str(&self) -> @str;
 
-    fn read_uint() -> uint;
-    fn read_u64() -> u64;
-    fn read_u32() -> u32;
-    fn read_u16() -> u16;
-    fn read_u8() -> u8;
+    // Compound types:
+    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
+    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
 
-    fn read_int() -> int;
-    fn read_i64() -> i64;
-    fn read_i32() -> i32;
-    fn read_i16() -> i16;
-    fn read_i8() -> i8;
+    fn read_owned<T>(&self, f: fn() -> T) -> T;
+    fn read_managed<T>(&self, f: fn() -> T) -> T;
 
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
 
-    fn read_bool() -> bool;
+    fn read_rec<T>(&self, f: fn() -> T) -> T;
+    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
 
-    fn read_str() -> ~str;
+    fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
+    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
+}
 
-    fn read_f64() -> f64;
-    fn read_f32() -> f32;
-    fn read_float() -> float;
+#[cfg(stage0)]
+pub mod traits {
+pub trait Serializable {
+    fn serialize<S: Serializer>(&self, s: &S);
+}
 
-    // Compound types:
-    fn read_enum<T>(name: &str, f: fn() -> T) -> T;
-    fn read_enum_variant<T>(f: fn(uint) -> T) -> T;
-    fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T;
-    fn read_vec<T>(f: fn(uint) -> T) -> T;
-    fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T;
-    fn read_box<T>(f: fn() -> T) -> T;
-    fn read_uniq<T>(f: fn() -> T) -> T;
-    fn read_rec<T>(f: fn() -> T) -> T;
-    fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T;
-    fn read_tup<T>(sz: uint, f: fn() -> T) -> T;
-    fn read_tup_elt<T>(idx: uint, f: fn() -> T) -> T;
+pub trait Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
+}
+
+pub impl uint: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
+}
+
+pub impl uint: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
+        d.read_uint()
+    }
+}
+
+pub impl u8: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
+}
+
+pub impl u8: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
+        d.read_u8()
+    }
+}
+
+pub impl u16: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
+}
+
+pub impl u16: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
+        d.read_u16()
+    }
+}
+
+pub impl u32: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
+}
+
+pub impl u32: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
+        d.read_u32()
+    }
+}
+
+pub impl u64: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
+}
+
+pub impl u64: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
+        d.read_u64()
+    }
+}
+
+pub impl int: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
+}
+
+pub impl int: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
+        d.read_int()
+    }
+}
+
+pub impl i8: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
+}
+
+pub impl i8: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
+        d.read_i8()
+    }
+}
+
+pub impl i16: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
+}
+
+pub impl i16: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
+        d.read_i16()
+    }
+}
+
+pub impl i32: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
+}
+
+pub impl i32: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
+        d.read_i32()
+    }
+}
+
+pub impl i64: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
+}
+
+pub impl i64: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
+        d.read_i64()
+    }
+}
+
+pub impl &str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
+}
+
+pub impl ~str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
+}
+
+pub impl ~str: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
+        d.read_owned_str()
+    }
+}
+
+pub impl @str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
+}
+
+pub impl @str: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
+        d.read_managed_str()
+    }
+}
+
+pub impl float: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
+}
+
+pub impl float: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
+        d.read_float()
+    }
+}
+
+pub impl f32: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
+}
+
+pub impl f32: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
+        d.read_f32() }
+}
+
+pub impl f64: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
+}
+
+pub impl f64: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
+        d.read_f64()
+    }
+}
+
+pub impl bool: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
+}
+
+pub impl bool: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
+        d.read_bool()
+    }
+}
+
+pub impl (): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
+}
+
+pub impl (): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
+        d.read_nil()
+    }
+}
+
+pub impl<T: Serializable> &T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_borrowed(|| (**self).serialize(s))
+    }
+}
+
+pub impl<T: Serializable> ~T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_owned(|| (**self).serialize(s))
+    }
+}
+
+pub impl<T: Deserializable> ~T: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
+        d.read_owned(|| ~deserialize(d))
+    }
+}
+
+pub impl<T: Serializable> @T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_managed(|| (**self).serialize(s))
+    }
+}
+
+pub impl<T: Deserializable> @T: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
+        d.read_managed(|| @deserialize(d))
+    }
+}
+
+pub impl<T: Serializable> &[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_borrowed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<T: Serializable> ~[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_owned_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<T: Deserializable> ~[T]: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
+        do d.read_owned_vec |len| {
+            do vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
+}
+
+pub impl<T: Serializable> @[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_managed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<T: Deserializable> @[T]: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
+        do d.read_managed_vec |len| {
+            do at_vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
+}
+
+pub impl<T: Serializable> Option<T>: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_enum(~"option") {
+            match *self {
+              None => do s.emit_enum_variant(~"none", 0u, 0u) {
+              },
+
+              Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
+                s.emit_enum_variant_arg(0u, || v.serialize(s))
+              }
+            }
+        }
+    }
+}
+
+pub impl<T: Deserializable> Option<T>: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
+        do d.read_enum(~"option") {
+            do d.read_enum_variant |i| {
+                match i {
+                  0 => None,
+                  1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))),
+                  _ => fail(fmt!("Bad variant for option: %u", i))
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable
+> (T0, T1): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1) => {
+                do s.emit_tup(2) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable
+> (T0, T1): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
+        do d.read_tup(2) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d))
+            )
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable,
+    T2: Serializable
+> (T0, T1, T2): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2) => {
+                do s.emit_tup(3) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable
+> (T0, T1, T2): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
+        do d.read_tup(3) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d))
+            )
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable,
+    T2: Serializable,
+    T3: Serializable
+> (T0, T1, T2, T3): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3) => {
+                do s.emit_tup(4) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                    s.emit_tup_elt(3, || t3.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable,
+    T3: Deserializable
+> (T0, T1, T2, T3): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
+        do d.read_tup(4) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d)),
+                d.read_tup_elt(3, || deserialize(d))
+            )
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable,
+    T2: Serializable,
+    T3: Serializable,
+    T4: Serializable
+> (T0, T1, T2, T3, T4): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3, ref t4) => {
+                do s.emit_tup(5) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                    s.emit_tup_elt(3, || t3.serialize(s));
+                    s.emit_tup_elt(4, || t4.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable,
+    T3: Deserializable,
+    T4: Deserializable
+> (T0, T1, T2, T3, T4): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D)
+      -> (T0, T1, T2, T3, T4) {
+        do d.read_tup(5) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d)),
+                d.read_tup_elt(3, || deserialize(d)),
+                d.read_tup_elt(4, || deserialize(d))
+            )
+        }
+    }
 }
 
 // ___________________________________________________________________________
@@ -83,189 +534,517 @@ pub trait Deserializer {
 //
 // In some cases, these should eventually be coded as traits.
 
-pub fn emit_from_vec<S: Serializer, T>(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
-    do s.emit_vec(vec::len(v)) {
-        for vec::eachi(v) |i,e| {
-            do s.emit_vec_elt(i) {
-                f(*e)
+pub trait SerializerHelpers {
+    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
+}
+
+pub impl<S: Serializer> S: SerializerHelpers {
+    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
+        do self.emit_owned_vec(v.len()) {
+            for v.eachi |i, e| {
+                do self.emit_vec_elt(i) {
+                    f(e)
+                }
             }
         }
     }
 }
 
-pub fn read_to_vec<D: Deserializer, T: Copy>(&&d: D, f: fn() -> T) -> ~[T] {
-    do d.read_vec |len| {
-        do vec::from_fn(len) |i| {
-            d.read_vec_elt(i, || f())
+pub trait DeserializerHelpers {
+    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
+}
+
+pub impl<D: Deserializer> D: DeserializerHelpers {
+    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
+        do self.read_owned_vec |len| {
+            do vec::from_fn(len) |i| {
+                self.read_vec_elt(i, || f())
+            }
         }
     }
 }
+}
 
-pub trait SerializerHelpers {
-    fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T));
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub mod traits {
+pub trait Serializable<S: Serializer> {
+    fn serialize(&self, s: &S);
+}
+
+pub trait Deserializable<D: Deserializer> {
+    static fn deserialize(&self, d: &D) -> self;
+}
+
+pub impl<S: Serializer> uint: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_uint(*self) }
 }
 
-impl<S: Serializer> S: SerializerHelpers {
-    fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T)) {
-        emit_from_vec(self, v, f)
+pub impl<D: Deserializer> uint: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> uint {
+        d.read_uint()
     }
 }
 
-pub trait DeserializerHelpers {
-    fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T];
+pub impl<S: Serializer> u8: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_u8(*self) }
+}
+
+pub impl<D: Deserializer> u8: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> u8 {
+        d.read_u8()
+    }
+}
+
+pub impl<S: Serializer> u16: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_u16(*self) }
+}
+
+pub impl<D: Deserializer> u16: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> u16 {
+        d.read_u16()
+    }
+}
+
+pub impl<S: Serializer> u32: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_u32(*self) }
+}
+
+pub impl<D: Deserializer> u32: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> u32 {
+        d.read_u32()
+    }
+}
+
+pub impl<S: Serializer> u64: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_u64(*self) }
+}
+
+pub impl<D: Deserializer> u64: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> u64 {
+        d.read_u64()
+    }
+}
+
+pub impl<S: Serializer> int: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_int(*self) }
+}
+
+pub impl<D: Deserializer> int: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> int {
+        d.read_int()
+    }
+}
+
+pub impl<S: Serializer> i8: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_i8(*self) }
+}
+
+pub impl<D: Deserializer> i8: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> i8 {
+        d.read_i8()
+    }
+}
+
+pub impl<S: Serializer> i16: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_i16(*self) }
+}
+
+pub impl<D: Deserializer> i16: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> i16 {
+        d.read_i16()
+    }
+}
+
+pub impl<S: Serializer> i32: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_i32(*self) }
+}
+
+pub impl<D: Deserializer> i32: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> i32 {
+        d.read_i32()
+    }
+}
+
+pub impl<S: Serializer> i64: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_i64(*self) }
 }
 
-impl<D: Deserializer> D: DeserializerHelpers {
-    fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T] {
-        read_to_vec(self, f)
+pub impl<D: Deserializer> i64: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> i64 {
+        d.read_i64()
     }
 }
 
-pub fn serialize_uint<S: Serializer>(&&s: S, v: uint) {
-    s.emit_uint(v);
+pub impl<S: Serializer> &str: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_borrowed_str(*self) }
+}
+
+pub impl<S: Serializer> ~str: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_owned_str(*self) }
 }
 
-pub fn deserialize_uint<D: Deserializer>(&&d: D) -> uint {
-    d.read_uint()
+pub impl<D: Deserializer> ~str: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> ~str {
+        d.read_owned_str()
+    }
 }
 
-pub fn serialize_u8<S: Serializer>(&&s: S, v: u8) {
-    s.emit_u8(v);
+pub impl<S: Serializer> @str: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_managed_str(*self) }
 }
 
-pub fn deserialize_u8<D: Deserializer>(&&d: D) -> u8 {
-    d.read_u8()
+pub impl<D: Deserializer> @str: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> @str {
+        d.read_managed_str()
+    }
 }
 
-pub fn serialize_u16<S: Serializer>(&&s: S, v: u16) {
-    s.emit_u16(v);
+pub impl<S: Serializer> float: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_float(*self) }
 }
 
-pub fn deserialize_u16<D: Deserializer>(&&d: D) -> u16 {
-    d.read_u16()
+pub impl<D: Deserializer> float: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> float {
+        d.read_float()
+    }
 }
 
-pub fn serialize_u32<S: Serializer>(&&s: S, v: u32) {
-    s.emit_u32(v);
+pub impl<S: Serializer> f32: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_f32(*self) }
 }
 
-pub fn deserialize_u32<D: Deserializer>(&&d: D) -> u32 {
-    d.read_u32()
+pub impl<D: Deserializer> f32: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> f32 {
+        d.read_f32() }
 }
 
-pub fn serialize_u64<S: Serializer>(&&s: S, v: u64) {
-    s.emit_u64(v);
+pub impl<S: Serializer> f64: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_f64(*self) }
 }
 
-pub fn deserialize_u64<D: Deserializer>(&&d: D) -> u64 {
-    d.read_u64()
+pub impl<D: Deserializer> f64: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> f64 {
+        d.read_f64()
+    }
 }
 
-pub fn serialize_int<S: Serializer>(&&s: S, v: int) {
-    s.emit_int(v);
+pub impl<S: Serializer> bool: Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_bool(*self) }
 }
 
-pub fn deserialize_int<D: Deserializer>(&&d: D) -> int {
-    d.read_int()
+pub impl<D: Deserializer> bool: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> bool {
+        d.read_bool()
+    }
 }
 
-pub fn serialize_i8<S: Serializer>(&&s: S, v: i8) {
-    s.emit_i8(v);
+pub impl<S: Serializer> (): Serializable<S> {
+    fn serialize(&self, s: &S) { s.emit_nil() }
 }
 
-pub fn deserialize_i8<D: Deserializer>(&&d: D) -> i8 {
-    d.read_i8()
+pub impl<D: Deserializer> (): Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> () {
+        d.read_nil()
+    }
 }
 
-pub fn serialize_i16<S: Serializer>(&&s: S, v: i16) {
-    s.emit_i16(v);
+pub impl<S: Serializer, T: Serializable<S>> &T: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        s.emit_borrowed(|| (**self).serialize(s))
+    }
 }
 
-pub fn deserialize_i16<D: Deserializer>(&&d: D) -> i16 {
-    d.read_i16()
+pub impl<S: Serializer, T: Serializable<S>> ~T: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        s.emit_owned(|| (**self).serialize(s))
+    }
 }
 
-pub fn serialize_i32<S: Serializer>(&&s: S, v: i32) {
-    s.emit_i32(v);
+pub impl<D: Deserializer, T: Deserializable<D>> ~T: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> ~T {
+        d.read_owned(|| ~deserialize(d))
+    }
 }
 
-pub fn deserialize_i32<D: Deserializer>(&&d: D) -> i32 {
-    d.read_i32()
+pub impl<S: Serializer, T: Serializable<S>> @T: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        s.emit_managed(|| (**self).serialize(s))
+    }
 }
 
-pub fn serialize_i64<S: Serializer>(&&s: S, v: i64) {
-    s.emit_i64(v);
+pub impl<D: Deserializer, T: Deserializable<D>> @T: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> @T {
+        d.read_managed(|| @deserialize(d))
+    }
 }
 
-pub fn deserialize_i64<D: Deserializer>(&&d: D) -> i64 {
-    d.read_i64()
+pub impl<S: Serializer, T: Serializable<S>> &[T]: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        do s.emit_borrowed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<S: Serializer, T: Serializable<S>> ~[T]: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        do s.emit_owned_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<D: Deserializer, T: Deserializable<D>> ~[T]: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> ~[T] {
+        do d.read_owned_vec |len| {
+            do vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
+}
+
+pub impl<S: Serializer, T: Serializable<S>> @[T]: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        do s.emit_managed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<D: Deserializer, T: Deserializable<D>> @[T]: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> @[T] {
+        do d.read_managed_vec |len| {
+            do at_vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
 }
 
-pub fn serialize_str<S: Serializer>(&&s: S, v: &str) {
-    s.emit_str(v);
+pub impl<S: Serializer, T: Serializable<S>> Option<T>: Serializable<S> {
+    fn serialize(&self, s: &S) {
+        do s.emit_enum(~"option") {
+            match *self {
+              None => do s.emit_enum_variant(~"none", 0u, 0u) {
+              },
+
+              Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
+                s.emit_enum_variant_arg(0u, || v.serialize(s))
+              }
+            }
+        }
+    }
 }
 
-pub fn deserialize_str<D: Deserializer>(&&d: D) -> ~str {
-    d.read_str()
+pub impl<D: Deserializer, T: Deserializable<D>> Option<T>: Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> Option<T> {
+        do d.read_enum(~"option") {
+            do d.read_enum_variant |i| {
+                match i {
+                  0 => None,
+                  1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))),
+                  _ => fail(#fmt("Bad variant for option: %u", i))
+                }
+            }
+        }
+    }
 }
 
-pub fn serialize_float<S: Serializer>(&&s: S, v: float) {
-    s.emit_float(v);
+pub impl<
+    S: Serializer,
+    T0: Serializable<S>,
+    T1: Serializable<S>
+> (T0, T1): Serializable<S> {
+    fn serialize(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1) => {
+                do s.emit_tup(2) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                }
+            }
+        }
+    }
 }
 
-pub fn deserialize_float<D: Deserializer>(&&d: D) -> float {
-    d.read_float()
+pub impl<
+    D: Deserializer,
+    T0: Deserializable<D>,
+    T1: Deserializable<D>
+> (T0, T1): Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> (T0, T1) {
+        do d.read_tup(2) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d))
+            )
+        }
+    }
 }
 
-pub fn serialize_f32<S: Serializer>(&&s: S, v: f32) {
-    s.emit_f32(v);
+pub impl<
+    S: Serializer,
+    T0: Serializable<S>,
+    T1: Serializable<S>,
+    T2: Serializable<S>
+> (T0, T1, T2): Serializable<S> {
+    fn serialize(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2) => {
+                do s.emit_tup(3) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                }
+            }
+        }
+    }
 }
 
-pub fn deserialize_f32<D: Deserializer>(&&d: D) -> f32 {
-    d.read_f32()
+pub impl<
+    D: Deserializer,
+    T0: Deserializable<D>,
+    T1: Deserializable<D>,
+    T2: Deserializable<D>
+> (T0, T1, T2): Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> (T0, T1, T2) {
+        do d.read_tup(3) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d))
+            )
+        }
+    }
 }
 
-pub fn serialize_f64<S: Serializer>(&&s: S, v: f64) {
-    s.emit_f64(v);
+pub impl<
+    S: Serializer,
+    T0: Serializable<S>,
+    T1: Serializable<S>,
+    T2: Serializable<S>,
+    T3: Serializable<S>
+> (T0, T1, T2, T3): Serializable<S> {
+    fn serialize(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3) => {
+                do s.emit_tup(4) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                    s.emit_tup_elt(3, || t3.serialize(s));
+                }
+            }
+        }
+    }
 }
 
-pub fn deserialize_f64<D: Deserializer>(&&d: D) -> f64 {
-    d.read_f64()
+pub impl<
+    D: Deserializer,
+    T0: Deserializable<D>,
+    T1: Deserializable<D>,
+    T2: Deserializable<D>,
+    T3: Deserializable<D>
+> (T0, T1, T2, T3): Deserializable<D> {
+    static fn deserialize(&self, d: &D) -> (T0, T1, T2, T3) {
+        do d.read_tup(4) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d)),
+                d.read_tup_elt(3, || deserialize(d))
+            )
+        }
+    }
 }
 
-pub fn serialize_bool<S: Serializer>(&&s: S, v: bool) {
-    s.emit_bool(v);
+pub impl<
+    S: Serializer,
+    T0: Serializable<S>,
+    T1: Serializable<S>,
+    T2: Serializable<S>,
+    T3: Serializable<S>,
+    T4: Serializable<S>
+> (T0, T1, T2, T3, T4): Serializable<S> {
+    fn serialize(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3, ref t4) => {
+                do s.emit_tup(5) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                    s.emit_tup_elt(3, || t3.serialize(s));
+                    s.emit_tup_elt(4, || t4.serialize(s));
+                }
+            }
+        }
+    }
 }
 
-pub fn deserialize_bool<D: Deserializer>(&&d: D) -> bool {
-    d.read_bool()
+pub impl<
+    D: Deserializer,
+    T0: Deserializable<D>,
+    T1: Deserializable<D>,
+    T2: Deserializable<D>,
+    T3: Deserializable<D>,
+    T4: Deserializable<D>
+> (T0, T1, T2, T3, T4): Deserializable<D> {
+    static fn deserialize(&self, d: &D)
+      -> (T0, T1, T2, T3, T4) {
+        do d.read_tup(5) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d)),
+                d.read_tup_elt(3, || deserialize(d)),
+                d.read_tup_elt(4, || deserialize(d))
+            )
+        }
+    }
 }
 
-pub fn serialize_Option<S: Serializer,T>(&&s: S, &&v: Option<T>,
-                                         st: fn(&&x: T)) {
-    do s.emit_enum(~"option") {
-        match v {
-          None => do s.emit_enum_variant(~"none", 0u, 0u) {
-          },
+// ___________________________________________________________________________
+// Helper routines
+//
+// In some cases, these should eventually be coded as traits.
 
-          Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
-            do s.emit_enum_variant_arg(0u) {
-                st(*v)
+pub trait SerializerHelpers {
+    fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T));
+}
+
+pub impl<S: Serializer> S: SerializerHelpers {
+    fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T)) {
+        do self.emit_owned_vec(v.len()) {
+            for v.eachi |i, e| {
+                do self.emit_vec_elt(i) {
+                    f(e)
+                }
             }
-          }
         }
     }
 }
 
-pub fn deserialize_Option<D: Deserializer,T: Copy>(&&d: D, st: fn() -> T)
-    -> Option<T> {
-    do d.read_enum(~"option") {
-        do d.read_enum_variant |i| {
-            match i {
-              0 => None,
-              1 => Some(d.read_enum_variant_arg(0u, || st() )),
-              _ => fail(#fmt("Bad variant for option: %u", i))
+pub trait DeserializerHelpers {
+    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
+}
+
+pub impl<D: Deserializer> D: DeserializerHelpers {
+    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
+        do self.read_owned_vec |len| {
+            do vec::from_fn(len) |i| {
+                self.read_vec_elt(i, || f())
             }
         }
     }
 }
+}
+
+pub use traits::*;
diff --git a/src/libstd/serialization2.rs b/src/libstd/serialization2.rs
deleted file mode 100644
index 5173ef163a2..00000000000
--- a/src/libstd/serialization2.rs
+++ /dev/null
@@ -1,563 +0,0 @@
-//! Support code for serialization.
-
-/*
-Core serialization interfaces.
-*/
-
-#[forbid(deprecated_mode)];
-#[forbid(non_camel_case_types)];
-
-pub trait Serializer {
-    // Primitive types:
-    fn emit_nil(&self);
-    fn emit_uint(&self, v: uint);
-    fn emit_u64(&self, v: u64);
-    fn emit_u32(&self, v: u32);
-    fn emit_u16(&self, v: u16);
-    fn emit_u8(&self, v: u8);
-    fn emit_int(&self, v: int);
-    fn emit_i64(&self, v: i64);
-    fn emit_i32(&self, v: i32);
-    fn emit_i16(&self, v: i16);
-    fn emit_i8(&self, v: i8);
-    fn emit_bool(&self, v: bool);
-    fn emit_float(&self, v: float);
-    fn emit_f64(&self, v: f64);
-    fn emit_f32(&self, v: f32);
-    fn emit_char(&self, v: char);
-    fn emit_borrowed_str(&self, v: &str);
-    fn emit_owned_str(&self, v: &str);
-    fn emit_managed_str(&self, v: &str);
-
-    // Compound types:
-    fn emit_borrowed(&self, f: fn());
-    fn emit_owned(&self, f: fn());
-    fn emit_managed(&self, f: fn());
-
-    fn emit_enum(&self, name: &str, f: fn());
-    fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
-    fn emit_enum_variant_arg(&self, idx: uint, f: fn());
-
-    fn emit_borrowed_vec(&self, len: uint, f: fn());
-    fn emit_owned_vec(&self, len: uint, f: fn());
-    fn emit_managed_vec(&self, len: uint, f: fn());
-    fn emit_vec_elt(&self, idx: uint, f: fn());
-
-    fn emit_rec(&self, f: fn());
-    fn emit_struct(&self, name: &str, f: fn());
-    fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
-
-    fn emit_tup(&self, len: uint, f: fn());
-    fn emit_tup_elt(&self, idx: uint, f: fn());
-}
-
-pub trait Deserializer {
-    // Primitive types:
-    fn read_nil(&self) -> ();
-    fn read_uint(&self) -> uint;
-    fn read_u64(&self) -> u64;
-    fn read_u32(&self) -> u32;
-    fn read_u16(&self) -> u16;
-    fn read_u8(&self) -> u8;
-    fn read_int(&self) -> int;
-    fn read_i64(&self) -> i64;
-    fn read_i32(&self) -> i32;
-    fn read_i16(&self) -> i16;
-    fn read_i8(&self) -> i8;
-    fn read_bool(&self) -> bool;
-    fn read_f64(&self) -> f64;
-    fn read_f32(&self) -> f32;
-    fn read_float(&self) -> float;
-    fn read_char(&self) -> char;
-    fn read_owned_str(&self) -> ~str;
-    fn read_managed_str(&self) -> @str;
-
-    // Compound types:
-    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
-    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
-    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
-
-    fn read_owned<T>(&self, f: fn() -> T) -> T;
-    fn read_managed<T>(&self, f: fn() -> T) -> T;
-
-    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
-    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
-    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
-
-    fn read_rec<T>(&self, f: fn() -> T) -> T;
-    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
-    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
-
-    fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
-    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
-}
-
-pub trait Serializable {
-    fn serialize<S: Serializer>(&self, s: &S);
-}
-
-pub trait Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
-}
-
-pub impl uint: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
-}
-
-pub impl uint: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
-        d.read_uint()
-    }
-}
-
-pub impl u8: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
-}
-
-pub impl u8: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
-        d.read_u8()
-    }
-}
-
-pub impl u16: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
-}
-
-pub impl u16: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
-        d.read_u16()
-    }
-}
-
-pub impl u32: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
-}
-
-pub impl u32: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
-        d.read_u32()
-    }
-}
-
-pub impl u64: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
-}
-
-pub impl u64: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
-        d.read_u64()
-    }
-}
-
-pub impl int: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
-}
-
-pub impl int: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
-        d.read_int()
-    }
-}
-
-pub impl i8: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
-}
-
-pub impl i8: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
-        d.read_i8()
-    }
-}
-
-pub impl i16: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
-}
-
-pub impl i16: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
-        d.read_i16()
-    }
-}
-
-pub impl i32: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
-}
-
-pub impl i32: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
-        d.read_i32()
-    }
-}
-
-pub impl i64: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
-}
-
-pub impl i64: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
-        d.read_i64()
-    }
-}
-
-pub impl &str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
-}
-
-pub impl ~str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
-}
-
-pub impl ~str: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
-        d.read_owned_str()
-    }
-}
-
-pub impl @str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
-}
-
-pub impl @str: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
-        d.read_managed_str()
-    }
-}
-
-pub impl float: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
-}
-
-pub impl float: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
-        d.read_float()
-    }
-}
-
-pub impl f32: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
-}
-
-pub impl f32: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
-        d.read_f32() }
-}
-
-pub impl f64: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
-}
-
-pub impl f64: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
-        d.read_f64()
-    }
-}
-
-pub impl bool: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
-}
-
-pub impl bool: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
-        d.read_bool()
-    }
-}
-
-pub impl (): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
-}
-
-pub impl (): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
-        d.read_nil()
-    }
-}
-
-pub impl<T: Serializable> &T: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_borrowed(|| (**self).serialize(s))
-    }
-}
-
-pub impl<T: Serializable> ~T: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_owned(|| (**self).serialize(s))
-    }
-}
-
-pub impl<T: Deserializable> ~T: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
-        d.read_owned(|| ~deserialize(d))
-    }
-}
-
-pub impl<T: Serializable> @T: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_managed(|| (**self).serialize(s))
-    }
-}
-
-pub impl<T: Deserializable> @T: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
-        d.read_managed(|| @deserialize(d))
-    }
-}
-
-pub impl<T: Serializable> &[T]: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_borrowed_vec(self.len()) {
-            for self.eachi |i, e| {
-                s.emit_vec_elt(i, || e.serialize(s))
-            }
-        }
-    }
-}
-
-pub impl<T: Serializable> ~[T]: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_owned_vec(self.len()) {
-            for self.eachi |i, e| {
-                s.emit_vec_elt(i, || e.serialize(s))
-            }
-        }
-    }
-}
-
-pub impl<T: Deserializable> ~[T]: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
-        do d.read_owned_vec |len| {
-            do vec::from_fn(len) |i| {
-                d.read_vec_elt(i, || deserialize(d))
-            }
-        }
-    }
-}
-
-pub impl<T: Serializable> @[T]: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_managed_vec(self.len()) {
-            for self.eachi |i, e| {
-                s.emit_vec_elt(i, || e.serialize(s))
-            }
-        }
-    }
-}
-
-pub impl<T: Deserializable> @[T]: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
-        do d.read_managed_vec |len| {
-            do at_vec::from_fn(len) |i| {
-                d.read_vec_elt(i, || deserialize(d))
-            }
-        }
-    }
-}
-
-pub impl<T: Serializable> Option<T>: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_enum(~"option") {
-            match *self {
-              None => do s.emit_enum_variant(~"none", 0u, 0u) {
-              },
-
-              Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
-                s.emit_enum_variant_arg(0u, || v.serialize(s))
-              }
-            }
-        }
-    }
-}
-
-pub impl<T: Deserializable> Option<T>: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
-        do d.read_enum(~"option") {
-            do d.read_enum_variant |i| {
-                match i {
-                  0 => None,
-                  1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))),
-                  _ => fail(#fmt("Bad variant for option: %u", i))
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable
-> (T0, T1): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1) => {
-                do s.emit_tup(2) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable
-> (T0, T1): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
-        do d.read_tup(2) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d))
-            )
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable,
-    T2: Serializable
-> (T0, T1, T2): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1, ref t2) => {
-                do s.emit_tup(3) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                    s.emit_tup_elt(2, || t2.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable,
-    T2: Deserializable
-> (T0, T1, T2): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
-        do d.read_tup(3) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d)),
-                d.read_tup_elt(2, || deserialize(d))
-            )
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable,
-    T2: Serializable,
-    T3: Serializable
-> (T0, T1, T2, T3): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1, ref t2, ref t3) => {
-                do s.emit_tup(4) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                    s.emit_tup_elt(2, || t2.serialize(s));
-                    s.emit_tup_elt(3, || t3.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable,
-    T2: Deserializable,
-    T3: Deserializable
-> (T0, T1, T2, T3): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
-        do d.read_tup(4) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d)),
-                d.read_tup_elt(2, || deserialize(d)),
-                d.read_tup_elt(3, || deserialize(d))
-            )
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable,
-    T2: Serializable,
-    T3: Serializable,
-    T4: Serializable
-> (T0, T1, T2, T3, T4): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1, ref t2, ref t3, ref t4) => {
-                do s.emit_tup(5) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                    s.emit_tup_elt(2, || t2.serialize(s));
-                    s.emit_tup_elt(3, || t3.serialize(s));
-                    s.emit_tup_elt(4, || t4.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable,
-    T2: Deserializable,
-    T3: Deserializable,
-    T4: Deserializable
-> (T0, T1, T2, T3, T4): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D)
-      -> (T0, T1, T2, T3, T4) {
-        do d.read_tup(5) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d)),
-                d.read_tup_elt(2, || deserialize(d)),
-                d.read_tup_elt(3, || deserialize(d)),
-                d.read_tup_elt(4, || deserialize(d))
-            )
-        }
-    }
-}
-
-// ___________________________________________________________________________
-// Helper routines
-//
-// In some cases, these should eventually be coded as traits.
-
-pub trait SerializerHelpers {
-    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
-}
-
-pub impl<S: Serializer> S: SerializerHelpers {
-    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
-        do self.emit_owned_vec(v.len()) {
-            for v.eachi |i, e| {
-                do self.emit_vec_elt(i) {
-                    f(e)
-                }
-            }
-        }
-    }
-}
-
-pub trait DeserializerHelpers {
-    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
-}
-
-pub impl<D: Deserializer> D: DeserializerHelpers {
-    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
-        do self.read_owned_vec |len| {
-            do vec::from_fn(len) |i| {
-                self.read_vec_elt(i, || f())
-            }
-        }
-    }
-}
diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs
index 98f98fe7fce..946a3e1155d 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -899,7 +899,7 @@ mod test_qsort {
 
         do sort::quick_sort(names) |x, y| { int::le(*x, *y) };
 
-        let immut_names = vec::from_mut(names);
+        let immut_names = vec::from_mut(move names);
 
         let pairs = vec::zip(expected, immut_names);
         for vec::each(pairs) |p| {
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 7fc3004bbcf..bbffde40948 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -8,7 +8,7 @@ not required in or otherwise suitable for the core library.
 */
 
 #[link(name = "std",
-       vers = "0.4",
+       vers = "0.5",
        uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
        url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
 
@@ -25,7 +25,7 @@ not required in or otherwise suitable for the core library.
 #[allow(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
-extern mod core(vers = "0.4");
+extern mod core(vers = "0.5");
 use core::*;
 
 // General io and system-services modules
@@ -69,7 +69,6 @@ pub mod treemap;
 // And ... other stuff
 
 pub mod ebml;
-pub mod ebml2;
 pub mod dbg;
 pub mod getopts;
 pub mod json;
@@ -79,7 +78,6 @@ pub mod tempfile;
 pub mod term;
 pub mod time;
 pub mod prettyprint;
-pub mod prettyprint2;
 pub mod arena;
 pub mod par;
 pub mod cmp;
@@ -93,7 +91,6 @@ mod unicode;
 
 pub mod test;
 pub mod serialization;
-pub mod serialization2;
 
 // Local Variables:
 // mode: rust;
diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs
index 908f3936f4e..73fc78a091a 100644
--- a/src/libstd/sync.rs
+++ b/src/libstd/sync.rs
@@ -25,7 +25,7 @@ struct Waitqueue { head: pipes::Port<SignalEnd>,
 
 fn new_waitqueue() -> Waitqueue {
     let (block_tail, block_head) = pipes::stream();
-    Waitqueue { head: block_head, tail: block_tail }
+    Waitqueue { head: move block_head, tail: move block_tail }
 }
 
 // Signals one live task from the queue.
@@ -71,7 +71,7 @@ enum Sem<Q: Send> = Exclusive<SemInner<Q>>;
 #[doc(hidden)]
 fn new_sem<Q: Send>(count: int, q: Q) -> Sem<Q> {
     Sem(exclusive(SemInner {
-        mut count: count, waiters: new_waitqueue(), blocked: q }))
+        mut count: count, waiters: new_waitqueue(), blocked: move q }))
 }
 #[doc(hidden)]
 fn new_sem_and_signal(count: int, num_condvars: uint)
@@ -146,7 +146,7 @@ impl &Sem<~[mut Waitqueue]> {
     }
 }
 
-// FIXME(#3136) should go inside of access()
+// FIXME(#3588) should go inside of access()
 #[doc(hidden)]
 struct SemRelease {
     sem: &Sem<()>,
@@ -577,7 +577,7 @@ impl &RWlock {
     }
 }
 
-// FIXME(#3136) should go inside of read()
+// FIXME(#3588) should go inside of read()
 #[doc(hidden)]
 struct RWlockReleaseRead {
     lock: &RWlock,
@@ -606,7 +606,7 @@ fn RWlockReleaseRead(lock: &r/RWlock) -> RWlockReleaseRead/&r {
     }
 }
 
-// FIXME(#3136) should go inside of downgrade()
+// FIXME(#3588) should go inside of downgrade()
 #[doc(hidden)]
 struct RWlockReleaseDowngrade {
     lock: &RWlock,
@@ -686,7 +686,7 @@ mod tests {
     fn test_sem_as_mutex() {
         let s = ~semaphore(1);
         let s2 = ~s.clone();
-        do task::spawn {
+        do task::spawn |move s2| {
             do s2.access {
                 for 5.times { task::yield(); }
             }
@@ -701,7 +701,7 @@ mod tests {
         let (c,p) = pipes::stream();
         let s = ~semaphore(0);
         let s2 = ~s.clone();
-        do task::spawn {
+        do task::spawn |move s2, move c| {
             s2.acquire();
             c.send(());
         }
@@ -713,7 +713,7 @@ mod tests {
         let (c,p) = pipes::stream();
         let s = ~semaphore(0);
         let s2 = ~s.clone();
-        do task::spawn {
+        do task::spawn |move s2, move p| {
             for 5.times { task::yield(); }
             s2.release();
             let _ = p.recv();
@@ -729,7 +729,7 @@ mod tests {
         let s2 = ~s.clone();
         let (c1,p1) = pipes::stream();
         let (c2,p2) = pipes::stream();
-        do task::spawn {
+        do task::spawn |move s2, move c1, move p2| {
             do s2.access {
                 let _ = p2.recv();
                 c1.send(());
@@ -748,10 +748,10 @@ mod tests {
             let s = ~semaphore(1);
             let s2 = ~s.clone();
             let (c,p) = pipes::stream();
-            let child_data = ~mut Some((s2,c));
+            let child_data = ~mut Some((move s2, move c));
             do s.access {
                 let (s2,c) = option::swap_unwrap(child_data);
-                do task::spawn {
+                do task::spawn |move c, move s2| {
                     c.send(());
                     do s2.access { }
                     c.send(());
@@ -774,7 +774,7 @@ mod tests {
         let m2 = ~m.clone();
         let mut sharedstate = ~0;
         let ptr = ptr::addr_of(&(*sharedstate));
-        do task::spawn {
+        do task::spawn |move m2, move c| {
             let sharedstate: &mut int =
                 unsafe { cast::reinterpret_cast(&ptr) };
             access_shared(sharedstate, m2, 10);
@@ -803,7 +803,7 @@ mod tests {
         // Child wakes up parent
         do m.lock_cond |cond| {
             let m2 = ~m.clone();
-            do task::spawn {
+            do task::spawn |move m2| {
                 do m2.lock_cond |cond| {
                     let woken = cond.signal();
                     assert woken;
@@ -814,7 +814,7 @@ mod tests {
         // Parent wakes up child
         let (chan,port) = pipes::stream();
         let m3 = ~m.clone();
-        do task::spawn {
+        do task::spawn |move chan, move m3| {
             do m3.lock_cond |cond| {
                 chan.send(());
                 cond.wait();
@@ -836,8 +836,8 @@ mod tests {
         for num_waiters.times {
             let mi = ~m.clone();
             let (chan, port) = pipes::stream();
-            ports.push(port);
-            do task::spawn {
+            ports.push(move port);
+            do task::spawn |move chan, move mi| {
                 do mi.lock_cond |cond| {
                     chan.send(());
                     cond.wait();
@@ -867,7 +867,7 @@ mod tests {
     fn test_mutex_cond_no_waiter() {
         let m = ~Mutex();
         let m2 = ~m.clone();
-        do task::try {
+        do task::try |move m| {
             do m.lock_cond |_x| { }
         };
         do m2.lock_cond |cond| {
@@ -880,7 +880,7 @@ mod tests {
         let m = ~Mutex();
         let m2 = ~m.clone();
 
-        let result: result::Result<(),()> = do task::try {
+        let result: result::Result<(),()> = do task::try |move m2| {
             do m2.lock {
                 fail;
             }
@@ -896,9 +896,9 @@ mod tests {
         let m = ~Mutex();
         let m2 = ~m.clone();
 
-        let result: result::Result<(),()> = do task::try {
+        let result: result::Result<(),()> = do task::try |move m2| {
             let (c,p) = pipes::stream();
-            do task::spawn { // linked
+            do task::spawn |move p| { // linked
                 let _ = p.recv(); // wait for sibling to get in the mutex
                 task::yield();
                 fail;
@@ -921,19 +921,19 @@ mod tests {
         let m2 = ~m.clone();
         let (c,p) = pipes::stream();
 
-        let result: result::Result<(),()> = do task::try {
+        let result: result::Result<(),()> = do task::try |move c, move m2| {
             let mut sibling_convos = ~[];
             for 2.times {
                 let (c,p) = pipes::stream();
-                let c = ~mut Some(c);
-                sibling_convos.push(p);
+                let c = ~mut Some(move c);
+                sibling_convos.push(move p);
                 let mi = ~m2.clone();
                 // spawn sibling task
-                do task::spawn { // linked
+                do task::spawn |move mi, move c| { // linked
                     do mi.lock_cond |cond| {
                         let c = option::swap_unwrap(c);
                         c.send(()); // tell sibling to go ahead
-                        let _z = SendOnFailure(c);
+                        let _z = SendOnFailure(move c);
                         cond.wait(); // block forever
                     }
                 }
@@ -942,7 +942,7 @@ mod tests {
                 let _ = p.recv(); // wait for sibling to get in the mutex
             }
             do m2.lock { }
-            c.send(sibling_convos); // let parent wait on all children
+            c.send(move sibling_convos); // let parent wait on all children
             fail;
         };
         assert result.is_err();
@@ -959,7 +959,7 @@ mod tests {
 
         fn SendOnFailure(c: pipes::Chan<()>) -> SendOnFailure {
             SendOnFailure {
-                c: c
+                c: move c
             }
         }
     }
@@ -969,7 +969,7 @@ mod tests {
         let m = ~Mutex();
         do m.lock_cond |cond| {
             let m2 = ~m.clone();
-            do task::spawn {
+            do task::spawn |move m2| {
                 do m2.lock_cond |cond| {
                     cond.signal_on(0);
                 }
@@ -983,7 +983,7 @@ mod tests {
             let m = ~mutex_with_condvars(2);
             let m2 = ~m.clone();
             let (c,p) = pipes::stream();
-            do task::spawn {
+            do task::spawn |move m2, move c| {
                 do m2.lock_cond |cond| {
                     c.send(());
                     cond.wait_on(1);
@@ -1032,7 +1032,7 @@ mod tests {
                 },
             DowngradeRead =>
                 do x.write_downgrade |mode| {
-                    let mode = x.downgrade(mode);
+                    let mode = x.downgrade(move mode);
                     (&mode).read(blk);
                 },
         }
@@ -1046,7 +1046,7 @@ mod tests {
         let x2 = ~x.clone();
         let mut sharedstate = ~0;
         let ptr = ptr::addr_of(&(*sharedstate));
-        do task::spawn {
+        do task::spawn |move c, move x2| {
             let sharedstate: &mut int =
                 unsafe { cast::reinterpret_cast(&ptr) };
             access_shared(sharedstate, x2, mode1, 10);
@@ -1089,7 +1089,7 @@ mod tests {
         let x2 = ~x.clone();
         let (c1,p1) = pipes::stream();
         let (c2,p2) = pipes::stream();
-        do task::spawn {
+        do task::spawn |move c1, move x2, move p2| {
             if !make_mode2_go_first {
                 let _ = p2.recv(); // parent sends to us once it locks, or ...
             }
@@ -1126,10 +1126,10 @@ mod tests {
         // Tests that downgrade can unlock the lock in both modes
         let x = ~RWlock();
         do lock_rwlock_in_mode(x, Downgrade) { }
-        test_rwlock_handshake(x, Read, Read, false);
+        test_rwlock_handshake(move x, Read, Read, false);
         let y = ~RWlock();
         do lock_rwlock_in_mode(y, DowngradeRead) { }
-        test_rwlock_exclusion(y, Write, Write);
+        test_rwlock_exclusion(move y, Write, Write);
     }
     #[test]
     fn test_rwlock_read_recursive() {
@@ -1144,7 +1144,7 @@ mod tests {
         // Child wakes up parent
         do x.write_cond |cond| {
             let x2 = ~x.clone();
-            do task::spawn {
+            do task::spawn |move x2| {
                 do x2.write_cond |cond| {
                     let woken = cond.signal();
                     assert woken;
@@ -1155,7 +1155,7 @@ mod tests {
         // Parent wakes up child
         let (chan,port) = pipes::stream();
         let x3 = ~x.clone();
-        do task::spawn {
+        do task::spawn |move x3, move chan| {
             do x3.write_cond |cond| {
                 chan.send(());
                 cond.wait();
@@ -1190,8 +1190,8 @@ mod tests {
         for num_waiters.times {
             let xi = ~x.clone();
             let (chan, port) = pipes::stream();
-            ports.push(port);
-            do task::spawn {
+            ports.push(move port);
+            do task::spawn |move chan, move xi| {
                 do lock_cond(xi, dg1) |cond| {
                     chan.send(());
                     cond.wait();
@@ -1226,7 +1226,7 @@ mod tests {
         let x = ~RWlock();
         let x2 = ~x.clone();
 
-        let result: result::Result<(),()> = do task::try {
+        let result: result::Result<(),()> = do task::try |move x2| {
             do lock_rwlock_in_mode(x2, mode1) {
                 fail;
             }
@@ -1264,7 +1264,7 @@ mod tests {
         let x = ~RWlock();
         let y = ~RWlock();
         do x.write_downgrade |xwrite| {
-            let mut xopt = Some(xwrite);
+            let mut xopt = Some(move xwrite);
             do y.write_downgrade |_ywrite| {
                 y.downgrade(option::swap_unwrap(&mut xopt));
                 error!("oops, y.downgrade(x) should have failed!");
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index 9790622332a..a10997d7c35 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -130,7 +130,7 @@ pub fn run_tests_console(opts: &TestOpts,
                 st.failed += 1u;
                 write_failed(st.out, st.use_color);
                 st.out.write_line(~"");
-                st.failures.push(test);
+                st.failures.push(move test);
               }
               TrIgnored => {
                 st.ignored += 1u;
@@ -249,7 +249,7 @@ fn should_sort_failures_before_printing_them() {
               mut passed: 0u,
               mut failed: 0u,
               mut ignored: 0u,
-              mut failures: ~[test_b, test_a]};
+              mut failures: ~[move test_b, move test_a]};
 
         print_failures(st);
     };
@@ -534,9 +534,9 @@ mod tests {
             for vec::each(names) |name| {
                 let test = {name: *name, testfn: copy testfn, ignore: false,
                             should_fail: false};
-                tests.push(test);
+                tests.push(move test);
             }
-            tests
+            move tests
         };
         let filtered = filter_tests(&opts, tests);
 
@@ -549,7 +549,7 @@ mod tests {
               ~"test::parse_ignored_flag",
               ~"test::sort_tests"];
 
-        let pairs = vec::zip(expected, filtered);
+        let pairs = vec::zip(expected, move filtered);
 
         for vec::each(pairs) |p| {
             match *p {
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 65872a013ab..75909273392 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -595,8 +595,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
 fn strftime(format: &str, tm: Tm) -> ~str {
     fn parse_type(ch: char, tm: &Tm) -> ~str {
         //FIXME (#2350): Implement missing types.
-      let die = || #fmt("strftime: can't understand this format %c ",
-                             ch);
+      let die = || fmt!("strftime: can't understand this format %c ", ch);
         match ch {
           'A' => match tm.tm_wday as int {
             0 => ~"Sunday",
diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs
index c9c28c4e1f0..199fba45914 100644
--- a/src/libstd/timer.rs
+++ b/src/libstd/timer.rs
@@ -23,7 +23,7 @@ use comm = core::comm;
  * * ch - a channel of type T to send a `val` on
  * * val - a value of type T to send over the provided `ch`
  */
-pub fn delayed_send<T: Copy Send>(iotask: IoTask,
+pub fn delayed_send<T: Send>(iotask: IoTask,
                                   msecs: uint, ch: comm::Chan<T>, val: T) {
         unsafe {
             let timer_done_po = core::comm::Port::<()>();
@@ -55,7 +55,7 @@ pub fn delayed_send<T: Copy Send>(iotask: IoTask,
             // delayed_send_cb has been processed by libuv
             core::comm::recv(timer_done_po);
             // notify the caller immediately
-            core::comm::send(ch, copy(val));
+            core::comm::send(ch, move(val));
             // uv_close for this timer has been processed
             core::comm::recv(timer_done_po);
     };
diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs
index 8ab0dc7f2e7..e4b6c9b5b9a 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -11,28 +11,28 @@ use core::cmp::{Eq, Ord};
 use core::option::{Some, None};
 use Option = core::Option;
 
-pub type TreeMap<K, V> = @mut TreeEdge<K, V>;
+pub type TreeMap<K: Copy Eq Ord, V: Copy> = @mut TreeEdge<K, V>;
 
-type TreeEdge<K, V> = Option<@TreeNode<K, V>>;
+type TreeEdge<K: Copy Eq Ord, V: Copy> = Option<@TreeNode<K, V>>;
 
-enum TreeNode<K, V> = {
+struct TreeNode<K: Copy Eq Ord, V: Copy> {
     key: K,
     mut value: V,
     mut left: TreeEdge<K, V>,
     mut right: TreeEdge<K, V>
-};
+}
 
 /// Create a treemap
-pub fn TreeMap<K, V>() -> TreeMap<K, V> { @mut None }
+pub fn TreeMap<K: Copy Eq Ord, V: Copy>() -> TreeMap<K, V> { @mut None }
 
 /// Insert a value into the map
 pub fn insert<K: Copy Eq Ord, V: Copy>(m: &mut TreeEdge<K, V>, k: K, v: V) {
     match copy *m {
       None => {
-        *m = Some(@TreeNode({key: k,
-                              mut value: v,
-                              mut left: None,
-                              mut right: None}));
+        *m = Some(@TreeNode {key: k,
+                             mut value: v,
+                             mut left: None,
+                             mut right: None});
         return;
       }
       Some(node) => {
@@ -67,7 +67,8 @@ pub fn find<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>, k: K)
 }
 
 /// Visit all pairs in the map in order.
-pub fn traverse<K, V: Copy>(m: &const TreeEdge<K, V>, f: fn((&K), (&V))) {
+pub fn traverse<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>,
+                                         f: fn((&K), (&V))) {
     match copy *m {
       None => (),
       Some(node) => {
@@ -79,6 +80,19 @@ pub fn traverse<K, V: Copy>(m: &const TreeEdge<K, V>, f: fn((&K), (&V))) {
     }
 }
 
+/// Compare two treemaps and return true iff
+/// they contain same keys and values
+pub fn equals<K: Copy Eq Ord, V: Copy Eq>(t1: &const TreeEdge<K, V>,
+                                          t2: &const TreeEdge<K, V>)
+                                        -> bool {
+    let mut v1 = ~[];
+    let mut v2 = ~[];
+    traverse(t1, |k,v| { v1.push((copy *k, copy *v)) });
+    traverse(t2, |k,v| { v2.push((copy *k, copy *v)) });
+    return v1 == v2;
+}
+
+
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
@@ -128,6 +142,28 @@ mod tests {
     }
 
     #[test]
+    fn equality() {
+        let m1 = TreeMap();
+        insert(m1, 3, ());
+        insert(m1, 0, ());
+        insert(m1, 4, ());
+        insert(m1, 2, ());
+        insert(m1, 1, ());
+        let m2 = TreeMap();
+        insert(m2, 2, ());
+        insert(m2, 1, ());
+        insert(m2, 3, ());
+        insert(m2, 0, ());
+        insert(m2, 4, ());
+
+        assert equals(m1, m2);
+
+        let m3 = TreeMap();
+        assert !equals(m1,m3);
+
+    }
+
+    #[test]
     fn u8_map() {
         let m = TreeMap();
 
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index f8c3882d15e..8bf4e9ed3af 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -590,6 +590,8 @@ extern mod rustrt {
         -> libc::c_int;
     fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t)
         -> libc::c_int;
+    fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
+    fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
     // FIXME ref #2064
     fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
                            tcp_handle_ptr: *uv_tcp_t,
@@ -606,6 +608,10 @@ extern mod rustrt {
     // FIXME ref #2064
     fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
                         ++addr: *sockaddr_in6) -> libc::c_int;
+    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+                               ++name: *sockaddr_in) -> libc::c_int;
+    fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+                                ++name: *sockaddr_in6) ->libc::c_int;
     fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
                       cb: *u8) -> libc::c_int;
     fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
@@ -736,6 +742,16 @@ pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
                                  addr_ptr);
 }
 
+pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+                              name: *sockaddr_in) -> libc::c_int {
+    return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name);
+}
+
+pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+                               name: *sockaddr_in6) ->libc::c_int {
+    return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
+}
+
 pub unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
                  cb: *u8) -> libc::c_int {
     return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb);
@@ -857,6 +873,12 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
         }
     }
 }
+pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
+    rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
+}
+pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
+    rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
+}
 
 pub unsafe fn timer_init(loop_ptr: *libc::c_void,
                      timer_ptr: *uv_timer_t) -> libc::c_int {
@@ -1048,7 +1070,7 @@ pub mod test {
                   as *request_wrapper;
             let buf_base = get_base_from_buf(buf);
             let buf_len = get_len_from_buf(buf);
-            let bytes = vec::raw::from_buf(buf_base, buf_len as uint);
+            let bytes = vec::from_buf(buf_base, buf_len as uint);
             let read_chan = *((*client_data).read_chan);
             let msg_from_server = str::from_bytes(bytes);
             core::comm::send(read_chan, msg_from_server);
@@ -1223,7 +1245,7 @@ pub mod test {
                             buf_base as uint,
                             buf_len as uint,
                             nread));
-            let bytes = vec::raw::from_buf(buf_base, buf_len);
+            let bytes = vec::from_buf(buf_base, buf_len);
             let request_str = str::from_bytes(bytes);
 
             let client_data = get_data_for_uv_handle(
@@ -1462,7 +1484,7 @@ pub mod test {
     fn impl_uv_tcp_server_and_request() unsafe {
         let bind_ip = ~"0.0.0.0";
         let request_ip = ~"127.0.0.1";
-        let port = 8887;
+        let port = 8886;
         let kill_server_msg = ~"does a dog have buddha nature?";
         let server_resp_msg = ~"mu!";
         let client_port = core::comm::Port::<~str>();