about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorEric Reed <ereed@mozilla.com>2013-06-17 12:45:40 -0700
committerEric Reed <ereed@mozilla.com>2013-06-17 12:45:40 -0700
commit35f3fa6383b5ed278879bfe5c74a913b885a2d4f (patch)
treebe8ca61c0beccd0b4c5d1e486c5322c1181c49f5 /src/libstd
parent33ae193a3c1a156e73bf6880366c9785dd4b7393 (diff)
parent319cf6e465f203c794d71800808c2bd60a1e7613 (diff)
downloadrust-35f3fa6383b5ed278879bfe5c74a913b885a2d4f.tar.gz
rust-35f3fa6383b5ed278879bfe5c74a913b885a2d4f.zip
Merge remote-tracking branch 'upstream/io' into io
Conflicts:
	src/libstd/rt/uvio.rs
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs12
-rw-r--r--src/libstd/bool.rs83
-rw-r--r--src/libstd/borrow.rs60
-rw-r--r--src/libstd/cast.rs2
-rw-r--r--src/libstd/cell.rs46
-rw-r--r--src/libstd/char.rs5
-rw-r--r--src/libstd/clone.rs6
-rw-r--r--src/libstd/cmp.rs32
-rw-r--r--src/libstd/comm.rs58
-rw-r--r--src/libstd/condition.rs17
-rw-r--r--src/libstd/container.rs10
-rw-r--r--src/libstd/core.rc38
-rw-r--r--src/libstd/either.rs18
-rw-r--r--src/libstd/from_str.rs4
-rw-r--r--src/libstd/hash.rs4
-rw-r--r--src/libstd/hashmap.rs188
-rw-r--r--src/libstd/io.rs97
-rw-r--r--src/libstd/iter.rs39
-rw-r--r--src/libstd/iterator.rs465
-rw-r--r--src/libstd/kinds.rs7
-rw-r--r--src/libstd/libc.rs18
-rw-r--r--src/libstd/local_data.rs5
-rw-r--r--src/libstd/logging.rs1
-rw-r--r--src/libstd/macros.rs19
-rw-r--r--src/libstd/managed.rs6
-rw-r--r--src/libstd/num/cmath.rs2
-rw-r--r--src/libstd/num/f32.rs16
-rw-r--r--src/libstd/num/f64.rs17
-rw-r--r--src/libstd/num/float.rs30
-rw-r--r--src/libstd/num/int_macros.rs62
-rw-r--r--src/libstd/num/num.rs11
-rw-r--r--src/libstd/num/strconv.rs15
-rw-r--r--src/libstd/num/uint_macros.rs57
-rw-r--r--src/libstd/old_iter.rs17
-rw-r--r--src/libstd/ops.rs2
-rw-r--r--src/libstd/option.rs148
-rw-r--r--src/libstd/os.rs88
-rw-r--r--src/libstd/path.rs130
-rw-r--r--src/libstd/pipes.rs49
-rw-r--r--src/libstd/prelude.rs86
-rw-r--r--src/libstd/ptr.rs242
-rw-r--r--src/libstd/rand.rs56
-rw-r--r--src/libstd/rand/distributions.rs4
-rw-r--r--src/libstd/reflect.rs20
-rw-r--r--src/libstd/repr.rs37
-rw-r--r--src/libstd/result.rs68
-rw-r--r--src/libstd/rt/comm.rs37
-rw-r--r--src/libstd/rt/context.rs8
-rw-r--r--src/libstd/rt/io/extensions.rs18
-rw-r--r--src/libstd/rt/io/file.rs2
-rw-r--r--src/libstd/rt/io/flate.rs4
-rw-r--r--src/libstd/rt/io/mem.rs3
-rw-r--r--src/libstd/rt/io/net/tcp.rs4
-rw-r--r--src/libstd/rt/io/stdio.rs1
-rw-r--r--src/libstd/rt/join_latch.rs645
-rw-r--r--src/libstd/rt/local.rs35
-rw-r--r--src/libstd/rt/local_ptr.rs2
-rw-r--r--src/libstd/rt/message_queue.rs18
-rw-r--r--src/libstd/rt/metrics.rs16
-rw-r--r--src/libstd/rt/mod.rs14
-rw-r--r--src/libstd/rt/rc.rs2
-rw-r--r--src/libstd/rt/sched.rs750
-rw-r--r--src/libstd/rt/sleeper_list.rs18
-rw-r--r--src/libstd/rt/stack.rs12
-rw-r--r--src/libstd/rt/task.rs73
-rw-r--r--src/libstd/rt/test.rs260
-rw-r--r--src/libstd/rt/thread.rs4
-rw-r--r--src/libstd/rt/tube.rs12
-rw-r--r--src/libstd/rt/uv/async.rs2
-rw-r--r--src/libstd/rt/uv/idle.rs15
-rw-r--r--src/libstd/rt/uv/mod.rs37
-rw-r--r--src/libstd/rt/uv/net.rs40
-rw-r--r--src/libstd/rt/uv/uvio.rs52
-rw-r--r--src/libstd/rt/uv/uvll.rs4
-rw-r--r--src/libstd/rt/work_queue.rs46
-rw-r--r--src/libstd/run.rs91
-rw-r--r--src/libstd/stackwalk.rs2
-rw-r--r--src/libstd/str.rs3945
-rw-r--r--src/libstd/str/ascii.rs25
-rw-r--r--src/libstd/sys.rs23
-rw-r--r--src/libstd/task/local_data_priv.rs2
-rw-r--r--src/libstd/task/mod.rs68
-rw-r--r--src/libstd/task/spawn.rs37
-rw-r--r--src/libstd/to_bytes.rs22
-rw-r--r--src/libstd/to_str.rs46
-rw-r--r--src/libstd/trie.rs30
-rw-r--r--src/libstd/tuple.rs12
-rw-r--r--src/libstd/unicode.rs2
-rw-r--r--src/libstd/unstable/atomics.rs7
-rw-r--r--src/libstd/unstable/dynamic_lib.rs199
-rw-r--r--src/libstd/unstable/extfmt.rs26
-rw-r--r--src/libstd/unstable/finally.rs38
-rw-r--r--src/libstd/unstable/lang.rs13
-rw-r--r--src/libstd/unstable/mod.rs13
-rw-r--r--src/libstd/unstable/sync.rs72
-rw-r--r--src/libstd/unstable/weak_task.rs8
-rw-r--r--src/libstd/util.rs53
-rw-r--r--src/libstd/vec.rs990
98 files changed, 5705 insertions, 4550 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 7a41c278fa3..a118e445fe2 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -101,6 +101,9 @@ pub fn build_sized_opt<A>(size: Option<uint>,
 }
 
 // Appending
+
+/// Iterates over the `rhs` vector, copying each element and appending it to the
+/// `lhs`. Afterwards, the `lhs` is then returned for use again.
 #[inline(always)]
 pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] {
     do build_sized(lhs.len() + rhs.len()) |push| {
@@ -211,6 +214,9 @@ pub mod raw {
         (**repr).unboxed.fill = new_len * sys::size_of::<T>();
     }
 
+    /**
+     * Pushes a new value onto this vector.
+     */
     #[inline(always)]
     pub unsafe fn push<T>(v: &mut @[T], initval: T) {
         let repr: **VecRepr = transmute_copy(&v);
@@ -223,7 +229,7 @@ pub mod raw {
     }
 
     #[inline(always)] // really pretty please
-    pub unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
+    unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
         let repr: **mut VecRepr = ::cast::transmute(v);
         let fill = (**repr).unboxed.fill;
         (**repr).unboxed.fill += sys::size_of::<T>();
@@ -232,7 +238,7 @@ pub mod raw {
         move_val_init(&mut(*p), initval);
     }
 
-    pub unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
+    unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
         reserve_at_least(&mut *v, v.len() + 1u);
         push_fast(v, initval);
     }
@@ -280,7 +286,7 @@ pub mod raw {
 #[cfg(test)]
 mod test {
     use super::*;
-    use prelude::*;
+    use uint;
 
     #[test]
     fn test() {
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
index d91c09c99a2..66a5bfa944f 100644
--- a/src/libstd/bool.rs
+++ b/src/libstd/bool.rs
@@ -38,6 +38,7 @@ Finally, some inquries into the nature of truth: `is_true` and `is_false`.
 use cmp::{Eq, Ord, TotalOrd, Ordering};
 use option::{None, Option, Some};
 use from_str::FromStr;
+use to_str::ToStr;
 
 /**
 * Negation of a boolean value.
@@ -130,44 +131,6 @@ pub fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) }
 pub fn implies(a: bool, b: bool) -> bool { !a || b }
 
 /**
-* Equality between two boolean values.
-*
-* Two booleans are equal if they have the same value.
-*
-* # Examples
-*
-* ~~~ {.rust}
-* rusti> std::bool::eq(false, true)
-* false
-* ~~~
-*
-* ~~~ {.rust}
-* rusti> std::bool::eq(false, false)
-* true
-* ~~~
-*/
-pub fn eq(a: bool, b: bool) -> bool { a == b }
-
-/**
-* Non-equality between two boolean values.
-*
-* Two booleans are not equal if they have different values.
-*
-* # Examples
-*
-* ~~~ {.rust}
-* rusti> std::bool::ne(false, true)
-* true
-* ~~~
-*
-* ~~~ {.rust}
-* rusti> std::bool::ne(false, false)
-* false
-* ~~~
-*/
-pub fn ne(a: bool, b: bool) -> bool { a != b }
-
-/**
 * Is a given boolean value true?
 *
 * # Examples
@@ -239,16 +202,21 @@ impl FromStr for bool {
 * # Examples
 *
 * ~~~ {.rust}
-* rusti> std::bool::to_str(true)
+* rusti> true.to_str()
 * "true"
 * ~~~
 *
 * ~~~ {.rust}
-* rusti> std::bool::to_str(false)
+* rusti> false.to_str()
 * "false"
 * ~~~
 */
-pub fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } }
+impl ToStr for bool {
+    #[inline(always)]
+    fn to_str(&self) -> ~str {
+        if *self { ~"true" } else { ~"false" }
+    }
+}
 
 /**
 * Iterates over all truth values, passing them to the given block.
@@ -258,7 +226,7 @@ pub fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } }
 * # Examples
 * ~~~
 * do std::bool::all_values |x: bool| {
-*     println(std::bool::to_str(x));
+*     println(x.to_str())
 * }
 * ~~~
 */
@@ -303,6 +271,31 @@ impl TotalOrd for bool {
     fn cmp(&self, other: &bool) -> Ordering { to_bit(*self).cmp(&to_bit(*other)) }
 }
 
+/**
+* Equality between two boolean values.
+*
+* Two booleans are equal if they have the same value.
+*
+* ~~~ {.rust}
+* rusti> false.eq(&true)
+* false
+* ~~~
+*
+* ~~~ {.rust}
+* rusti> false == false
+* true
+* ~~~
+*
+* ~~~ {.rust}
+* rusti> false != true
+* true
+* ~~~
+*
+* ~~~ {.rust}
+* rusti> false.ne(&false)
+* false
+* ~~~
+*/
 #[cfg(not(test))]
 impl Eq for bool {
     #[inline(always)]
@@ -319,14 +312,14 @@ mod tests {
     #[test]
     fn test_bool_from_str() {
         do all_values |v| {
-            assert!(Some(v) == FromStr::from_str(to_str(v)))
+            assert!(Some(v) == FromStr::from_str(v.to_str()))
         }
     }
 
     #[test]
     fn test_bool_to_str() {
-        assert_eq!(to_str(false), ~"false");
-        assert_eq!(to_str(true), ~"true");
+        assert_eq!(false.to_str(), ~"false");
+        assert_eq!(true.to_str(), ~"true");
     }
 
     #[test]
diff --git a/src/libstd/borrow.rs b/src/libstd/borrow.rs
new file mode 100644
index 00000000000..703011aea7f
--- /dev/null
+++ b/src/libstd/borrow.rs
@@ -0,0 +1,60 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Borrowed pointer utilities
+
+#[cfg(not(test))]
+use prelude::*;
+
+/// Cast a region pointer - &T - to a uint.
+#[inline(always)]
+pub fn to_uint<T>(thing: &T) -> uint {
+    thing as *T as uint
+}
+
+/// Determine if two borrowed pointers point to the same thing.
+#[inline(always)]
+pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool {
+    to_uint(thing) == to_uint(other)
+}
+
+// Equality for region pointers
+#[cfg(not(test))]
+impl<'self, T: Eq> Eq for &'self T {
+    #[inline(always)]
+    fn eq(&self, other: & &'self T) -> bool {
+        *(*self) == *(*other)
+    }
+    #[inline(always)]
+    fn ne(&self, other: & &'self T) -> bool {
+        *(*self) != *(*other)
+    }
+}
+
+// Comparison for region pointers
+#[cfg(not(test))]
+impl<'self, T: Ord> Ord for &'self T {
+    #[inline(always)]
+    fn lt(&self, other: & &'self T) -> bool {
+        *(*self) < *(*other)
+    }
+    #[inline(always)]
+    fn le(&self, other: & &'self T) -> bool {
+        *(*self) <= *(*other)
+    }
+    #[inline(always)]
+    fn ge(&self, other: & &'self T) -> bool {
+        *(*self) >= *(*other)
+    }
+    #[inline(always)]
+    fn gt(&self, other: & &'self T) -> bool {
+        *(*self) > *(*other)
+    }
+}
diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs
index 30ad41f0ca2..2109568a0a4 100644
--- a/src/libstd/cast.rs
+++ b/src/libstd/cast.rs
@@ -27,6 +27,7 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     dest
 }
 
+/// Casts the value at `src` to U. The two types must have the same length.
 #[cfg(target_word_size = "32", not(stage0))]
 #[inline(always)]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
@@ -37,6 +38,7 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     dest
 }
 
+/// Casts the value at `src` to U. The two types must have the same length.
 #[cfg(target_word_size = "64", not(stage0))]
 #[inline(always)]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs
index d1fa9e697bf..e1d2b246dd3 100644
--- a/src/libstd/cell.rs
+++ b/src/libstd/cell.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -10,6 +10,8 @@
 
 //! A mutable, nullable memory location
 
+#[missing_doc];
+
 use cast::transmute_mut;
 use prelude::*;
 use util::replace;
@@ -22,22 +24,24 @@ Similar to a mutable option type, but friendlier.
 
 #[mutable]
 #[deriving(Clone, DeepClone, Eq)]
+#[allow(missing_doc)]
 pub struct Cell<T> {
     priv value: Option<T>
 }
 
-/// Creates a new full cell with the given value.
-pub fn Cell<T>(value: T) -> Cell<T> {
-    Cell { value: Some(value) }
-}
+impl<T> Cell<T> {
+    /// Creates a new full cell with the given value.
+    pub fn new(value: T) -> Cell<T> {
+        Cell { value: Some(value) }
+    }
 
-pub fn empty_cell<T>() -> Cell<T> {
-    Cell { value: None }
-}
+    /// Creates a new empty cell with no value inside.
+    pub fn new_empty() -> Cell<T> {
+        Cell { value: None }
+    }
 
-pub impl<T> Cell<T> {
     /// Yields the value, failing if the cell is empty.
-    fn take(&self) -> T {
+    pub fn take(&self) -> T {
         let this = unsafe { transmute_mut(self) };
         if this.is_empty() {
             fail!("attempt to take an empty cell");
@@ -47,7 +51,7 @@ pub impl<T> Cell<T> {
     }
 
     /// Returns the value, failing if the cell is full.
-    fn put_back(&self, value: T) {
+    pub fn put_back(&self, value: T) {
         let this = unsafe { transmute_mut(self) };
         if !this.is_empty() {
             fail!("attempt to put a value back into a full cell");
@@ -56,20 +60,20 @@ pub impl<T> Cell<T> {
     }
 
     /// Returns true if the cell is empty and false if the cell is full.
-    fn is_empty(&self) -> bool {
+    pub fn is_empty(&self) -> bool {
         self.value.is_none()
     }
 
-    // Calls a closure with a reference to the value.
-    fn with_ref<R>(&self, op: &fn(v: &T) -> R) -> R {
+    /// Calls a closure with a reference to the value.
+    pub fn with_ref<R>(&self, op: &fn(v: &T) -> R) -> R {
         let v = self.take();
         let r = op(&v);
         self.put_back(v);
         r
     }
 
-    // Calls a closure with a mutable reference to the value.
-    fn with_mut_ref<R>(&self, op: &fn(v: &mut T) -> R) -> R {
+    /// Calls a closure with a mutable reference to the value.
+    pub fn with_mut_ref<R>(&self, op: &fn(v: &mut T) -> R) -> R {
         let mut v = self.take();
         let r = op(&mut v);
         self.put_back(v);
@@ -79,7 +83,7 @@ pub impl<T> Cell<T> {
 
 #[test]
 fn test_basic() {
-    let value_cell = Cell(~10);
+    let value_cell = Cell::new(~10);
     assert!(!value_cell.is_empty());
     let value = value_cell.take();
     assert!(value == ~10);
@@ -92,7 +96,7 @@ fn test_basic() {
 #[should_fail]
 #[ignore(cfg(windows))]
 fn test_take_empty() {
-    let value_cell = empty_cell::<~int>();
+    let value_cell = Cell::new_empty::<~int>();
     value_cell.take();
 }
 
@@ -100,14 +104,14 @@ fn test_take_empty() {
 #[should_fail]
 #[ignore(cfg(windows))]
 fn test_put_back_non_empty() {
-    let value_cell = Cell(~10);
+    let value_cell = Cell::new(~10);
     value_cell.put_back(~20);
 }
 
 #[test]
 fn test_with_ref() {
     let good = 6;
-    let c = Cell(~[1, 2, 3, 4, 5, 6]);
+    let c = Cell::new(~[1, 2, 3, 4, 5, 6]);
     let l = do c.with_ref() |v| { v.len() };
     assert_eq!(l, good);
 }
@@ -116,7 +120,7 @@ fn test_with_ref() {
 fn test_with_mut_ref() {
     let good = ~[1, 2, 3];
     let v = ~[1, 2];
-    let c = Cell(v);
+    let c = Cell::new(v);
     do c.with_mut_ref() |v| { v.push(3); }
     let v = c.take();
     assert_eq!(v, good);
diff --git a/src/libstd/char.rs b/src/libstd/char.rs
index bd70f59212d..073ced8988a 100644
--- a/src/libstd/char.rs
+++ b/src/libstd/char.rs
@@ -53,8 +53,12 @@ use cmp::{Eq, Ord};
     Cn  Unassigned              a reserved unassigned code point or a noncharacter
 */
 
+/// Returns whether the specified character is considered a unicode alphabetic
+/// character
 pub fn is_alphabetic(c: char) -> bool   { derived_property::Alphabetic(c) }
+#[allow(missing_doc)]
 pub fn is_XID_start(c: char) -> bool    { derived_property::XID_Start(c) }
+#[allow(missing_doc)]
 pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
 
 ///
@@ -256,6 +260,7 @@ pub fn len_utf8_bytes(c: char) -> uint {
     )
 }
 
+#[allow(missing_doc)]
 pub trait Char {
     fn is_alphabetic(&self) -> bool;
     fn is_XID_start(&self) -> bool;
diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs
index 2965b31a8c3..266dd1a35e3 100644
--- a/src/libstd/clone.rs
+++ b/src/libstd/clone.rs
@@ -24,6 +24,7 @@ by convention implementing the `Clone` trait and calling the
 
 use core::kinds::Const;
 
+/// A common trait for cloning an object.
 pub trait Clone {
     /// Returns a copy of the value. The contents of owned pointers
     /// are copied to maintain uniqueness, while the contents of
@@ -85,10 +86,11 @@ clone_impl!(())
 clone_impl!(bool)
 clone_impl!(char)
 
+/// A trait distinct from `Clone` which represents "deep copies" of things like
+/// managed boxes which would otherwise not be copied.
 pub trait DeepClone {
     /// Return a deep copy of the value. Unlike `Clone`, the contents of shared pointer types
-    /// *are* copied. Note that this is currently unimplemented for managed boxes, as
-    /// it would need to handle cycles, but it is implemented for other smart-pointer types.
+    /// *are* copied.
     fn deep_clone(&self) -> Self;
 }
 
diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs
index ca9c49b2c06..ce6a04c3688 100644
--- a/src/libstd/cmp.rs
+++ b/src/libstd/cmp.rs
@@ -20,6 +20,8 @@ and `Eq` to overload the `==` and `!=` operators.
 
 */
 
+#[allow(missing_doc)];
+
 /**
 * Trait for values that can be compared for equality and inequality.
 *
@@ -170,36 +172,6 @@ pub trait Ord {
     fn gt(&self, other: &Self) -> bool;
 }
 
-#[inline(always)]
-pub fn lt<T:Ord>(v1: &T, v2: &T) -> bool {
-    (*v1).lt(v2)
-}
-
-#[inline(always)]
-pub fn le<T:Ord>(v1: &T, v2: &T) -> bool {
-    (*v1).le(v2)
-}
-
-#[inline(always)]
-pub fn eq<T:Eq>(v1: &T, v2: &T) -> bool {
-    (*v1).eq(v2)
-}
-
-#[inline(always)]
-pub fn ne<T:Eq>(v1: &T, v2: &T) -> bool {
-    (*v1).ne(v2)
-}
-
-#[inline(always)]
-pub fn ge<T:Ord>(v1: &T, v2: &T) -> bool {
-    (*v1).ge(v2)
-}
-
-#[inline(always)]
-pub fn gt<T:Ord>(v1: &T, v2: &T) -> bool {
-    (*v1).gt(v2)
-}
-
 /// The equivalence relation. Two values may be equivalent even if they are
 /// of different types. The most common use case for this relation is
 /// container types; e.g. it is often desirable to be able to use `&str`
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index 59eb915c239..f0c353c8d62 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -12,6 +12,8 @@
 Message passing
 */
 
+#[allow(missing_doc)];
+
 use cast::{transmute, transmute_mut};
 use container::Container;
 use either::{Either, Left, Right};
@@ -148,14 +150,14 @@ pub struct PortSet<T> {
     ports: ~[pipesy::Port<T>],
 }
 
-pub impl<T: Owned> PortSet<T> {
-    fn new() -> PortSet<T> {
+impl<T: Owned> PortSet<T> {
+    pub fn new() -> PortSet<T> {
         PortSet {
             ports: ~[]
         }
     }
 
-    fn add(&self, port: Port<T>) {
+    pub fn add(&self, port: Port<T>) {
         let Port { inner } = port;
         let port = match inner {
             Left(p) => p,
@@ -167,7 +169,7 @@ pub impl<T: Owned> PortSet<T> {
         }
     }
 
-    fn chan(&self) -> Chan<T> {
+    pub fn chan(&self) -> Chan<T> {
         let (po, ch) = stream();
         self.add(po);
         ch
@@ -236,20 +238,24 @@ impl<T: Owned> SharedChan<T> {
 
 impl<T: Owned> GenericChan<T> for SharedChan<T> {
     fn send(&self, x: T) {
-        let mut xx = Some(x);
-        do self.ch.with_imm |chan| {
-            let x = replace(&mut xx, None);
-            chan.send(x.unwrap())
+        unsafe {
+            let mut xx = Some(x);
+            do self.ch.with_imm |chan| {
+                let x = replace(&mut xx, None);
+                chan.send(x.unwrap())
+            }
         }
     }
 }
 
 impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
     fn try_send(&self, x: T) -> bool {
-        let mut xx = Some(x);
-        do self.ch.with_imm |chan| {
-            let x = replace(&mut xx, None);
-            chan.try_send(x.unwrap())
+        unsafe {
+            let mut xx = Some(x);
+            do self.ch.with_imm |chan| {
+                let x = replace(&mut xx, None);
+                chan.try_send(x.unwrap())
+            }
         }
     }
 }
@@ -370,7 +376,7 @@ mod pipesy {
         priv use core::kinds::Owned;
         use ptr::to_mut_unsafe_ptr;
 
-        pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) {
+        pub fn init<T: Owned>() -> (server::Oneshot<T>, client::Oneshot<T>) {
             pub use core::pipes::HasBuffer;
 
             let buffer = ~::core::pipes::Buffer {
@@ -460,24 +466,24 @@ mod pipesy {
 
     /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
     pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
-        let (chan, port) = oneshot::init();
+        let (port, chan) = oneshot::init();
         (PortOne::new(port), ChanOne::new(chan))
     }
 
-    pub impl<T: Owned> PortOne<T> {
-        fn recv(self) -> T { recv_one(self) }
-        fn try_recv(self) -> Option<T> { try_recv_one(self) }
-        fn unwrap(self) -> oneshot::server::Oneshot<T> {
+    impl<T: Owned> PortOne<T> {
+        pub fn recv(self) -> T { recv_one(self) }
+        pub fn try_recv(self) -> Option<T> { try_recv_one(self) }
+        pub fn unwrap(self) -> oneshot::server::Oneshot<T> {
             match self {
                 PortOne { contents: s } => s
             }
         }
     }
 
-    pub impl<T: Owned> ChanOne<T> {
-        fn send(self, data: T) { send_one(self, data) }
-        fn try_send(self, data: T) -> bool { try_send_one(self, data) }
-        fn unwrap(self) -> oneshot::client::Oneshot<T> {
+    impl<T: Owned> ChanOne<T> {
+        pub fn send(self, data: T) { send_one(self, data) }
+        pub fn try_send(self, data: T) -> bool { try_send_one(self, data) }
+        pub fn unwrap(self) -> oneshot::client::Oneshot<T> {
             match self {
                 ChanOne { contents: s } => s
             }
@@ -544,7 +550,7 @@ mod pipesy {
     pub mod streamp {
         priv use core::kinds::Owned;
 
-        pub fn init<T: Owned>() -> (client::Open<T>, server::Open<T>) {
+        pub fn init<T: Owned>() -> (server::Open<T>, client::Open<T>) {
             pub use core::pipes::HasBuffer;
             ::core::pipes::entangle()
         }
@@ -561,7 +567,7 @@ mod pipesy {
                 ::core::option::Option<Open<T>> {
                 {
                     use super::data;
-                    let (c, s) = ::core::pipes::entangle();
+                    let (s, c) = ::core::pipes::entangle();
                     let message = data(x_0, s);
                     if ::core::pipes::send(pipe, message) {
                         ::core::pipes::rt::make_some(c)
@@ -573,7 +579,7 @@ mod pipesy {
             pub fn data<T: Owned>(pipe: Open<T>, x_0: T) -> Open<T> {
                 {
                     use super::data;
-                    let (c, s) = ::core::pipes::entangle();
+                    let (s, c) = ::core::pipes::entangle();
                     let message = data(x_0, s);
                     ::core::pipes::send(pipe, message);
                     c
@@ -609,7 +615,7 @@ mod pipesy {
 
     */
     pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
-        let (c, s) = streamp::init();
+        let (s, c) = streamp::init();
 
         (Port {
             endp: Some(s)
diff --git a/src/libstd/condition.rs b/src/libstd/condition.rs
index baa6722b193..2f150a0d1b2 100644
--- a/src/libstd/condition.rs
+++ b/src/libstd/condition.rs
@@ -10,8 +10,11 @@
 
 /*! Condition handling */
 
-use prelude::*;
+#[allow(missing_doc)];
+
 use local_data::{local_data_pop, local_data_set};
+use local_data;
+use prelude::*;
 
 // helper for transmutation, shown below.
 type RustClosure = (int, int);
@@ -26,8 +29,8 @@ pub struct Condition<'self, T, U> {
     key: local_data::LocalDataKey<'self, Handler<T, U>>
 }
 
-pub impl<'self, T, U> Condition<'self, T, U> {
-    fn trap(&'self self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
+impl<'self, T, U> Condition<'self, T, U> {
+    pub fn trap(&'self self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
         unsafe {
             let p : *RustClosure = ::cast::transmute(&h);
             let prev = local_data::local_data_get(self.key);
@@ -36,12 +39,12 @@ pub impl<'self, T, U> Condition<'self, T, U> {
         }
     }
 
-    fn raise(&self, t: T) -> U {
+    pub fn raise(&self, t: T) -> U {
         let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
         self.raise_default(t, || fail!(copy msg))
     }
 
-    fn raise_default(&self, t: T, default: &fn() -> U) -> U {
+    pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
         unsafe {
             match local_data_pop(self.key) {
                 None => {
@@ -70,8 +73,8 @@ struct Trap<'self, T, U> {
     handler: @Handler<T, U>
 }
 
-pub impl<'self, T, U> Trap<'self, T, U> {
-    fn in<V>(&self, inner: &'self fn() -> V) -> V {
+impl<'self, T, U> Trap<'self, T, U> {
+    pub fn in<V>(&self, inner: &'self fn() -> V) -> V {
         unsafe {
             let _g = Guard { cond: self.cond };
             debug!("Trap: pushing handler to TLS");
diff --git a/src/libstd/container.rs b/src/libstd/container.rs
index 505aa5881c5..065582e2e0d 100644
--- a/src/libstd/container.rs
+++ b/src/libstd/container.rs
@@ -12,6 +12,8 @@
 
 use option::Option;
 
+/// A trait to represent the abstract idea of a container. The only concrete
+/// knowledge known is the number of elements contained within.
 pub trait Container {
     /// Return the number of elements in the container
     fn len(&const self) -> uint;
@@ -20,16 +22,19 @@ pub trait Container {
     fn is_empty(&const self) -> bool;
 }
 
+/// A trait to represent mutable containers
 pub trait Mutable: Container {
     /// Clear the container, removing all values.
     fn clear(&mut self);
 }
 
+/// A map is a key-value store where values may be looked up by their keys. This
+/// trait provides basic operations to operate on these stores.
 pub trait Map<K, V>: Mutable {
     /// Return true if the map contains a value for the specified key
     fn contains_key(&self, key: &K) -> bool;
 
-    // Visits all keys and values
+    /// Visits all keys and values
     fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) -> bool;
 
     /// Visit all keys
@@ -65,6 +70,9 @@ pub trait Map<K, V>: Mutable {
     fn pop(&mut self, k: &K) -> Option<V>;
 }
 
+/// A set is a group of objects which are each distinct from one another. This
+/// trait represents actions which can be performed on sets to manipulate and
+/// iterate over them.
 pub trait Set<T>: Mutable {
     /// Return true if the set contains a value
     fn contains(&self, value: &T) -> bool;
diff --git a/src/libstd/core.rc b/src/libstd/core.rc
index 3d5f0fb8493..8e09a9b17fd 100644
--- a/src/libstd/core.rc
+++ b/src/libstd/core.rc
@@ -10,39 +10,39 @@
 
 /*!
 
-# The Rust core library
+# The Rust standard library
 
-The Rust core library provides runtime features required by the language,
+The Rust standard library provides runtime features required by the language,
 including the task scheduler and memory allocators, as well as library
 support for Rust built-in types, platform abstractions, and other commonly
 used features.
 
-`core` includes modules corresponding to each of the integer types, each of
+`std` includes modules corresponding to each of the integer types, each of
 the floating point types, the `bool` type, tuples, characters, strings
 (`str`), vectors (`vec`), managed boxes (`managed`), owned boxes (`owned`),
-and unsafe and borrowed pointers (`ptr`).  Additionally, `core` provides
+and unsafe and borrowed pointers (`ptr`).  Additionally, `std` provides
 pervasive types (`option` and `result`), task creation and communication
 primitives (`task`, `comm`), platform abstractions (`os` and `path`), basic
 I/O abstractions (`io`), common traits (`kinds`, `ops`, `cmp`, `num`,
 `to_str`), and complete bindings to the C standard library (`libc`).
 
-# Core injection and the Rust prelude
+# Standard library injection and the Rust prelude
 
-`core` is imported at the topmost level of every crate by default, as
+`std` is imported at the topmost level of every crate by default, as
 if the first line of each crate was
 
-    extern mod core;
+    extern mod std;
 
-This means that the contents of core can be accessed from from any context
-with the `core::` path prefix, as in `use core::vec`, `use core::task::spawn`,
+This means that the contents of std can be accessed from any context
+with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
 etc.
 
-Additionally, `core` contains a `prelude` module that reexports many of the
-most common core modules, types and traits. The contents of the prelude are
+Additionally, `std` contains a `prelude` module that reexports many of the
+most common std modules, types and traits. The contents of the prelude are
 imported into every *module* by default.  Implicitly, all modules behave as if
 they contained the following prologue:
 
-    use core::prelude::*;
+    use std::prelude::*;
 
 */
 
@@ -50,18 +50,21 @@ they contained the following prologue:
 #[link(name = "std",
        vers = "0.7-pre",
        uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
-       url = "https://github.com/mozilla/rust/tree/master/src/libcore")];
+       url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
 
-#[comment = "The Rust core library"];
+#[comment = "The Rust standard library"];
 #[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
+// NOTE: remove these two attributes after the next snapshot
+#[no_core]; // for stage0
+#[allow(unrecognized_lint)]; // otherwise stage0 is seriously ugly
 
 // Don't link to std. We are std.
-#[no_core]; // for stage0
 #[no_std];
 
 #[deny(non_camel_case_types)];
+#[deny(missing_doc)];
 
 // Make core testable by not duplicating lang items. See #2912
 #[cfg(test)] extern mod realstd(name = "std");
@@ -122,6 +125,7 @@ pub mod ascii;
 pub mod ptr;
 pub mod owned;
 pub mod managed;
+pub mod borrow;
 
 
 /* Core language traits */
@@ -224,5 +228,7 @@ mod std {
     pub use kinds;
     pub use sys;
     pub use pipes;
+    pub use unstable;
+    pub use str;
+    pub use os;
 }
-
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index f89bb3b2f90..fac0866f17e 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -10,6 +10,8 @@
 
 //! A type that represents one of two alternatives
 
+#[allow(missing_doc)];
+
 use container::Container;
 use cmp::Eq;
 use kinds::Copy;
@@ -137,29 +139,29 @@ pub fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
     }
 }
 
-pub impl<T, U> Either<T, U> {
+impl<T, U> Either<T, U> {
     #[inline(always)]
-    fn either<V>(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V {
+    pub fn either<V>(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V {
         either(f_left, f_right, self)
     }
 
     #[inline(always)]
-    fn flip(self) -> Either<U, T> { flip(self) }
+    pub fn flip(self) -> Either<U, T> { flip(self) }
 
     #[inline(always)]
-    fn to_result(self) -> Result<U, T> { to_result(self) }
+    pub fn to_result(self) -> Result<U, T> { to_result(self) }
 
     #[inline(always)]
-    fn is_left(&self) -> bool { is_left(self) }
+    pub fn is_left(&self) -> bool { is_left(self) }
 
     #[inline(always)]
-    fn is_right(&self) -> bool { is_right(self) }
+    pub fn is_right(&self) -> bool { is_right(self) }
 
     #[inline(always)]
-    fn unwrap_left(self) -> T { unwrap_left(self) }
+    pub fn unwrap_left(self) -> T { unwrap_left(self) }
 
     #[inline(always)]
-    fn unwrap_right(self) -> U { unwrap_right(self) }
+    pub fn unwrap_right(self) -> U { unwrap_right(self) }
 }
 
 #[test]
diff --git a/src/libstd/from_str.rs b/src/libstd/from_str.rs
index ebf6d212466..d2f1a895e1e 100644
--- a/src/libstd/from_str.rs
+++ b/src/libstd/from_str.rs
@@ -12,6 +12,10 @@
 
 use option::Option;
 
+/// A trait to abstract the idea of creating a new instance of a type from a
+/// string.
 pub trait FromStr {
+    /// Parses a string `s` to return an optional value of this type. If the
+    /// string is ill-formatted, the None is returned.
     fn from_str(s: &str) -> Option<Self>;
 }
diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs
index 7eb2054a35d..e9022445786 100644
--- a/src/libstd/hash.rs
+++ b/src/libstd/hash.rs
@@ -19,6 +19,8 @@
  * CPRNG like rand::rng.
  */
 
+#[allow(missing_doc)];
+
 use container::Container;
 use old_iter::BaseIter;
 use rt::io::Writer;
@@ -387,6 +389,8 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use uint;
+
     #[test]
     fn test_siphash() {
         let vecs : [[u8, ..8], ..64] = [
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index e6ccb7a1d6b..85156d6996d 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -13,11 +13,14 @@
 //! The tables use a keyed hash with new random keys generated for each container, so the ordering
 //! of a set of keys in a hash table is randomized.
 
+#[mutable_doc];
+
 use container::{Container, Mutable, Map, Set};
 use cmp::{Eq, Equiv};
 use hash::Hash;
 use old_iter::BaseIter;
 use old_iter;
+use iterator::{IteratorUtil};
 use option::{None, Option, Some};
 use rand::RngUtil;
 use rand;
@@ -34,6 +37,14 @@ struct Bucket<K,V> {
     value: V,
 }
 
+/// A hash map implementation which uses linear probing along with the SipHash
+/// hash function for internal state. This means that the order of all hash maps
+/// is randomized by keying each hash map randomly on creation.
+///
+/// It is required that the keys implement the `Eq` and `Hash` traits, although
+/// this can frequently be achieved by just implementing the `Eq` and
+/// `IterBytes` traits as `Hash` is automatically implemented for types that
+/// implement `IterBytes`.
 pub struct HashMap<K,V> {
     priv k0: u64,
     priv k1: u64,
@@ -53,6 +64,7 @@ fn resize_at(capacity: uint) -> uint {
     ((capacity as float) * 3. / 4.) as uint
 }
 
+/// Creates a new hash map with the specified capacity.
 pub fn linear_map_with_capacity<K:Eq + Hash,V>(
     initial_capacity: uint) -> HashMap<K, V> {
     let mut r = rand::task_rng();
@@ -63,15 +75,16 @@ pub fn linear_map_with_capacity<K:Eq + Hash,V>(
 fn linear_map_with_capacity_and_keys<K:Eq + Hash,V>(
     k0: u64, k1: u64,
     initial_capacity: uint) -> HashMap<K, V> {
+    let cap = uint::max(INITIAL_CAPACITY, initial_capacity);
     HashMap {
         k0: k0, k1: k1,
-        resize_at: resize_at(initial_capacity),
+        resize_at: resize_at(cap),
         size: 0,
-        buckets: vec::from_fn(initial_capacity, |_| None)
+        buckets: vec::from_fn(cap, |_| None)
     }
 }
 
-priv impl<K:Hash + Eq,V> HashMap<K, V> {
+impl<K:Hash + Eq,V> HashMap<K, V> {
     #[inline(always)]
     fn to_bucket(&self, h: uint) -> uint {
         // A good hash function with entropy spread over all of the
@@ -81,9 +94,7 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> {
 
     #[inline(always)]
     fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint {
-        let n = (idx + 1) % len_buckets;
-        debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
-        n
+        (idx + 1) % len_buckets
     }
 
     #[inline(always)]
@@ -202,16 +213,12 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> {
         match self.bucket_for_key_with_hash(hash, &k) {
             TableFull => { fail!("Internal logic error"); }
             FoundHole(idx) => {
-                debug!("insert fresh (%?->%?) at idx %?, hash %?",
-                       k, v, idx, hash);
                 self.buckets[idx] = Some(Bucket{hash: hash, key: k,
                                                 value: v});
                 self.size += 1;
                 None
             }
             FoundEntry(idx) => {
-                debug!("insert overwrite (%?->%?) at idx %?, hash %?",
-                       k, v, idx, hash);
                 match self.buckets[idx] {
                     None => { fail!("insert_internal: Internal logic error") }
                     Some(ref mut b) => {
@@ -304,7 +311,7 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
     /// Visit all key-value pairs
     fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool {
         for self.buckets.each |bucket| {
-            for bucket.each |pair| {
+            for bucket.iter().advance |pair| {
                 if !blk(&pair.key, &pair.value) {
                     return false;
                 }
@@ -393,29 +400,30 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
     }
 }
 
-pub impl<K: Hash + Eq, V> HashMap<K, V> {
+impl<K: Hash + Eq, V> HashMap<K, V> {
     /// Create an empty HashMap
-    fn new() -> HashMap<K, V> {
+    pub fn new() -> HashMap<K, V> {
         HashMap::with_capacity(INITIAL_CAPACITY)
     }
 
     /// Create an empty HashMap with space for at least `n` elements in
     /// the hash table.
-    fn with_capacity(capacity: uint) -> HashMap<K, V> {
+    pub fn with_capacity(capacity: uint) -> HashMap<K, V> {
         linear_map_with_capacity(capacity)
     }
 
     /// Reserve space for at least `n` elements in the hash table.
-    fn reserve_at_least(&mut self, n: uint) {
+    pub fn reserve_at_least(&mut self, n: uint) {
         if n > self.buckets.len() {
             let buckets = n * 4 / 3 + 1;
             self.resize(uint::next_power_of_two(buckets));
         }
     }
 
-    /// Return the value corresponding to the key in the map, or insert
-    /// and return the value if it doesn't exist.
-    fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
+    /// Modify and return the value corresponding to the key in the map, or
+    /// insert and return a new value if it doesn't exist.
+    pub fn mangle<'a,A>(&'a mut self, k: K, a: A, not_found: &fn(&K, A) -> V,
+                        found: &fn(&K, &mut V, A)) -> &'a mut V {
         if self.size >= self.resize_at {
             // n.b.: We could also do this after searching, so
             // that we do not resize if this call to insert is
@@ -429,49 +437,44 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
         let hash = k.hash_keyed(self.k0, self.k1) as uint;
         let idx = match self.bucket_for_key_with_hash(hash, &k) {
             TableFull => fail!("Internal logic error"),
-            FoundEntry(idx) => idx,
+            FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
             FoundHole(idx) => {
-                self.buckets[idx] = Some(Bucket{hash: hash, key: k,
-                                     value: v});
+                let v = not_found(&k, a);
+                self.buckets[idx] = Some(Bucket{hash: hash, key: k, value: v});
                 self.size += 1;
                 idx
-            },
+            }
         };
 
-        self.value_for_bucket(idx)
+        self.mut_value_for_bucket(idx)
+    }
+
+    /// Return the value corresponding to the key in the map, or insert
+    /// and return the value if it doesn't exist.
+    pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
+        self.mangle(k, v, |_k, a| a, |_k,_v,_a| ())
     }
 
     /// Return the value corresponding to the key in the map, or create,
     /// insert, and return a new value if it doesn't exist.
-    fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
-        if self.size >= self.resize_at {
-            // n.b.: We could also do this after searching, so
-            // that we do not resize if this call to insert is
-            // simply going to update a key in place.  My sense
-            // though is that it's worse to have to search through
-            // buckets to find the right spot twice than to just
-            // resize in this corner case.
-            self.expand();
-        }
-
-        let hash = k.hash_keyed(self.k0, self.k1) as uint;
-        let idx = match self.bucket_for_key_with_hash(hash, &k) {
-            TableFull => fail!("Internal logic error"),
-            FoundEntry(idx) => idx,
-            FoundHole(idx) => {
-                let v = f(&k);
-                self.buckets[idx] = Some(Bucket{hash: hash, key: k,
-                                     value: v});
-                self.size += 1;
-                idx
-            },
-        };
+    pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V)
+                               -> &'a mut V {
+        self.mangle(k, (), |k,_a| f(k), |_k,_v,_a| ())
+    }
 
-        self.value_for_bucket(idx)
+    /// Insert a key-value pair into the map if the key is not already present.
+    /// Otherwise, modify the existing value for the key.
+    /// Returns the new or modified value for the key.
+    pub fn insert_or_update_with<'a>(&'a mut self, k: K, v: V,
+                                     f: &fn(&K, &mut V)) -> &'a mut V {
+        self.mangle(k, v, |_k,a| a, |k,v,_a| f(k,v))
     }
 
-    fn consume(&mut self, f: &fn(K, V)) {
-        let buckets = replace(&mut self.buckets, ~[]);
+    /// Calls a function on each element of a hash map, destroying the hash
+    /// map in the process.
+    pub fn consume(&mut self, f: &fn(K, V)) {
+        let buckets = replace(&mut self.buckets,
+                              vec::from_fn(INITIAL_CAPACITY, |_| None));
         self.size = 0;
 
         do vec::consume(buckets) |_, bucket| {
@@ -484,16 +487,27 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
         }
     }
 
-    fn get<'a>(&'a self, k: &K) -> &'a V {
+    /// Retrieves a value for the given key, failing if the key is not
+    /// present.
+    pub fn get<'a>(&'a self, k: &K) -> &'a V {
         match self.find(k) {
             Some(v) => v,
             None => fail!("No entry found for key: %?", k),
         }
     }
 
+    /// Retrieves a (mutable) value for the given key, failing if the key
+    /// is not present.
+    pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
+        match self.find_mut(k) {
+            Some(v) => v,
+            None => fail!("No entry found for key: %?", k),
+        }
+    }
+
     /// Return true if the map contains a value for the specified key,
     /// using equivalence
-    fn contains_key_equiv<Q:Hash + Equiv<K>>(&self, key: &Q) -> bool {
+    pub fn contains_key_equiv<Q:Hash + Equiv<K>>(&self, key: &Q) -> bool {
         match self.bucket_for_key_equiv(key) {
             FoundEntry(_) => {true}
             TableFull | FoundHole(_) => {false}
@@ -502,7 +516,8 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
 
     /// Return the value corresponding to the key in the map, using
     /// equivalence
-    fn find_equiv<'a, Q:Hash + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
+    pub fn find_equiv<'a, Q:Hash + Equiv<K>>(&'a self, k: &Q)
+                                             -> Option<&'a V> {
         match self.bucket_for_key_equiv(k) {
             FoundEntry(idx) => Some(self.value_for_bucket(idx)),
             TableFull | FoundHole(_) => None,
@@ -510,14 +525,14 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
     }
 }
 
-pub impl<K: Hash + Eq, V: Copy> HashMap<K, V> {
+impl<K: Hash + Eq, V: Copy> HashMap<K, V> {
     /// Like `find`, but returns a copy of the value.
-    fn find_copy(&self, k: &K) -> Option<V> {
+    pub fn find_copy(&self, k: &K) -> Option<V> {
         self.find(k).map_consume(|v| copy *v)
     }
 
     /// Like `get`, but returns a copy of the value.
-    fn get_copy(&self, k: &K) -> V {
+    pub fn get_copy(&self, k: &K) -> V {
         copy *self.get(k)
     }
 }
@@ -539,6 +554,9 @@ impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
     fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
 }
 
+/// An implementation of a hash set using the underlying representation of a
+/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
+/// requires that the elements implement the `Eq` and `Hash` traits.
 pub struct HashSet<T> {
     priv map: HashMap<T, ()>
 }
@@ -618,29 +636,31 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
     }
 }
 
-pub impl <T:Hash + Eq> HashSet<T> {
+impl<T:Hash + Eq> HashSet<T> {
     /// Create an empty HashSet
-    fn new() -> HashSet<T> {
+    pub fn new() -> HashSet<T> {
         HashSet::with_capacity(INITIAL_CAPACITY)
     }
 
     /// Create an empty HashSet with space for at least `n` elements in
     /// the hash table.
-    fn with_capacity(capacity: uint) -> HashSet<T> {
+    pub fn with_capacity(capacity: uint) -> HashSet<T> {
         HashSet { map: HashMap::with_capacity(capacity) }
     }
 
     /// Reserve space for at least `n` elements in the hash table.
-    fn reserve_at_least(&mut self, n: uint) {
+    pub fn reserve_at_least(&mut self, n: uint) {
         self.map.reserve_at_least(n)
     }
 
     /// Consumes all of the elements in the set, emptying it out
-    fn consume(&mut self, f: &fn(T)) {
+    pub fn consume(&mut self, f: &fn(T)) {
         self.map.consume(|k, _| f(k))
     }
 
-    fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
+    /// Returns true if the hash set contains a value equivalent to the
+    /// given query value.
+    pub fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
       self.map.contains_key_equiv(value)
     }
 }
@@ -653,6 +673,12 @@ mod test_map {
     use uint;
 
     #[test]
+    fn test_create_capacity_zero() {
+        let mut m = HashMap::with_capacity(0);
+        assert!(m.insert(1, 1));
+    }
+
+    #[test]
     fn test_insert() {
         let mut m = HashMap::new();
         assert!(m.insert(1, 2));
@@ -733,15 +759,22 @@ mod test_map {
     #[test]
     fn test_find_or_insert() {
         let mut m = HashMap::new::<int, int>();
-        assert_eq!(m.find_or_insert(1, 2), &2);
-        assert_eq!(m.find_or_insert(1, 3), &2);
+        assert_eq!(*m.find_or_insert(1, 2), 2);
+        assert_eq!(*m.find_or_insert(1, 3), 2);
     }
 
     #[test]
     fn test_find_or_insert_with() {
         let mut m = HashMap::new::<int, int>();
-        assert_eq!(m.find_or_insert_with(1, |_| 2), &2);
-        assert_eq!(m.find_or_insert_with(1, |_| 3), &2);
+        assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
+        assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
+    }
+
+    #[test]
+    fn test_insert_or_update_with() {
+        let mut m = HashMap::new::<int, int>();
+        assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
+        assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
     }
 
     #[test]
@@ -760,6 +793,14 @@ mod test_map {
     }
 
     #[test]
+    fn test_consume_still_usable() {
+        let mut m = HashMap::new();
+        assert!(m.insert(1, 2));
+        do m.consume |_, _| {}
+        assert!(m.insert(1, 2));
+    }
+
+    #[test]
     fn test_iterate() {
         let mut m = linear_map_with_capacity(4);
         for uint::range(0, 32) |i| {
@@ -819,6 +860,23 @@ mod test_map {
         assert_eq!(m.len(), i);
         assert!(!m.is_empty());
     }
+
+    #[test]
+    fn test_find_equiv() {
+        let mut m = HashMap::new();
+
+        let (foo, bar, baz) = (1,2,3);
+        m.insert(~"foo", foo);
+        m.insert(~"bar", bar);
+        m.insert(~"baz", baz);
+
+
+        assert_eq!(m.find_equiv(&("foo")), Some(&foo));
+        assert_eq!(m.find_equiv(&("bar")), Some(&bar));
+        assert_eq!(m.find_equiv(&("baz")), Some(&baz));
+
+        assert_eq!(m.find_equiv(&("qux")), None);
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index b97b0c70afc..6f065d74fa2 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -44,6 +44,8 @@ implement `Reader` and `Writer`, where appropriate.
 
 */
 
+#[allow(missing_doc)];
+
 use result::Result;
 
 use container::Container;
@@ -670,7 +672,7 @@ impl<T:Reader> ReaderUtil for T {
                     val <<= 6;
                     val += (next & 63) as uint;
                 }
-                // See str::char_at
+                // See str::StrSlice::char_at
                 val += ((b0 << ((w + 1) as u8)) as uint)
                     << (w - 1) * 6 - w - 1u;
                 chars.push(val as char);
@@ -746,7 +748,7 @@ impl<T:Reader> ReaderUtil for T {
             if self.eof() && line.is_empty() { break; }
 
             // trim the \n, so that each_line is consistent with read_line
-            let n = str::len(line);
+            let n = line.len();
             if line[n-1] == '\n' as u8 {
                 unsafe { str::raw::set_len(&mut line, n-1); }
             }
@@ -769,7 +771,7 @@ impl<T:Reader> ReaderUtil for T {
     fn read_le_uint_n(&self, nbytes: uint) -> u64 {
         assert!(nbytes > 0 && nbytes <= 8);
 
-        let mut val = 0u64, pos = 0, i = nbytes;
+        let mut (val, pos, i) = (0u64, 0, nbytes);
         while i > 0 {
             val += (self.read_u8() as u64) << pos;
             pos += 8;
@@ -785,7 +787,7 @@ impl<T:Reader> ReaderUtil for T {
     fn read_be_uint_n(&self, nbytes: uint) -> u64 {
         assert!(nbytes > 0 && nbytes <= 8);
 
-        let mut val = 0u64, i = nbytes;
+        let mut (val, i) = (0u64, nbytes);
         while i > 0 {
             i -= 1;
             val += (self.read_u8() as u64) << i * 8;
@@ -980,6 +982,12 @@ pub struct FILERes {
     f: *libc::FILE,
 }
 
+impl FILERes {
+    pub fn new(f: *libc::FILE) -> FILERes {
+        FILERes { f: f }
+    }
+}
+
 impl Drop for FILERes {
     fn finalize(&self) {
         unsafe {
@@ -988,15 +996,9 @@ impl Drop for FILERes {
     }
 }
 
-pub fn FILERes(f: *libc::FILE) -> FILERes {
-    FILERes {
-        f: f
-    }
-}
-
 pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> @Reader {
     if cleanup {
-        @Wrapper { base: f, cleanup: FILERes(f) } as @Reader
+        @Wrapper { base: f, cleanup: FILERes::new(f) } as @Reader
     } else {
         @f as @Reader
     }
@@ -1089,7 +1091,7 @@ pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
 }
 
 pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
-    str::byte_slice(s, |bytes| with_bytes_reader(bytes, f))
+    with_bytes_reader(s.as_bytes(), f)
 }
 
 // Writing
@@ -1181,7 +1183,7 @@ impl Writer for *libc::FILE {
 
 pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
     if cleanup {
-        @Wrapper { base: f, cleanup: FILERes(f) } as @Writer
+        @Wrapper { base: f, cleanup: FILERes::new(f) } as @Writer
     } else {
         @f as @Writer
     }
@@ -1225,6 +1227,12 @@ pub struct FdRes {
     fd: fd_t,
 }
 
+impl FdRes {
+    pub fn new(fd: fd_t) -> FdRes {
+        FdRes { fd: fd }
+    }
+}
+
 impl Drop for FdRes {
     fn finalize(&self) {
         unsafe {
@@ -1233,15 +1241,9 @@ impl Drop for FdRes {
     }
 }
 
-pub fn FdRes(fd: fd_t) -> FdRes {
-    FdRes {
-        fd: fd
-    }
-}
-
 pub fn fd_writer(fd: fd_t, cleanup: bool) -> @Writer {
     if cleanup {
-        @Wrapper { base: fd, cleanup: FdRes(fd) } as @Writer
+        @Wrapper { base: fd, cleanup: FdRes::new(fd) } as @Writer
     } else {
         @fd as @Writer
     }
@@ -1302,7 +1304,9 @@ pub fn u64_to_le_bytes<T>(n: u64, size: uint,
               (n >> 56) as u8]),
       _ => {
 
-        let mut bytes: ~[u8] = ~[], i = size, n = n;
+        let mut bytes: ~[u8] = ~[];
+        let mut i = size;
+        let mut n = n;
         while i > 0u {
             bytes.push((n & 255_u64) as u8);
             n >>= 8_u64;
@@ -1458,7 +1462,7 @@ impl<T:Writer> WriterUtil for T {
             self.write_str(str::from_char(ch));
         }
     }
-    fn write_str(&self, s: &str) { str::byte_slice(s, |v| self.write(v)) }
+    fn write_str(&self, s: &str) { self.write(s.as_bytes()) }
     fn write_line(&self, s: &str) {
         self.write_str(s);
         self.write_str(&"\n");
@@ -1632,6 +1636,15 @@ pub struct BytesWriter {
     pos: @mut uint,
 }
 
+impl BytesWriter {
+    pub fn new() -> BytesWriter {
+        BytesWriter {
+            bytes: @mut ~[],
+            pos: @mut 0
+        }
+    }
+}
+
 impl Writer for BytesWriter {
     fn write(&self, v: &[u8]) {
         let v_len = v.len();
@@ -1671,15 +1684,8 @@ impl Writer for BytesWriter {
     }
 }
 
-pub fn BytesWriter() -> BytesWriter {
-    BytesWriter {
-        bytes: @mut ~[],
-        pos: @mut 0
-    }
-}
-
 pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
-    let wr = @BytesWriter();
+    let wr = @BytesWriter::new();
     f(wr as @Writer);
     let @BytesWriter { bytes, _ } = wr;
     copy *bytes
@@ -1760,6 +1766,12 @@ pub mod fsync {
         arg: Arg<t>,
     }
 
+    impl <t: Copy> Res<t> {
+        pub fn new(arg: Arg<t>) -> Res<t> {
+            Res { arg: arg }
+        }
+    }
+
     #[unsafe_destructor]
     impl<T:Copy> Drop for Res<T> {
         fn finalize(&self) {
@@ -1774,12 +1786,6 @@ pub mod fsync {
         }
     }
 
-    pub fn Res<t: Copy>(arg: Arg<t>) -> Res<t>{
-        Res {
-            arg: arg
-        }
-    }
-
     pub struct Arg<t> {
         val: t,
         opt_level: Option<Level>,
@@ -1791,7 +1797,7 @@ pub mod fsync {
     // outer res
     pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
                          blk: &fn(v: Res<*libc::FILE>)) {
-        blk(Res(Arg {
+        blk(Res::new(Arg {
             val: file.f, opt_level: opt_level,
             fsync_fn: |file, l| {
                 unsafe {
@@ -1804,7 +1810,7 @@ pub mod fsync {
     // fsync fd after executing blk
     pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
                        blk: &fn(v: Res<fd_t>)) {
-        blk(Res(Arg {
+        blk(Res::new(Arg {
             val: fd.fd, opt_level: opt_level,
             fsync_fn: |fd, l| os::fsync_fd(fd, l) as int
         }));
@@ -1816,7 +1822,7 @@ pub mod fsync {
     // Call o.fsync after executing blk
     pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
                     blk: &fn(v: Res<@FSyncable>)) {
-        blk(Res(Arg {
+        blk(Res::new(Arg {
             val: o, opt_level: opt_level,
             fsync_fn: |o, l| o.fsync(l)
         }));
@@ -1830,7 +1836,6 @@ mod tests {
     use io;
     use path::Path;
     use result;
-    use str;
     use u64;
     use vec;
 
@@ -1931,7 +1936,7 @@ mod tests {
     #[test]
     fn file_reader_not_exist() {
         match io::file_reader(&Path("not a file")) {
-          result::Err(copy e) => {
+          result::Err(e) => {
             assert_eq!(e, ~"error opening not a file");
           }
           result::Ok(_) => fail!()
@@ -1972,8 +1977,8 @@ mod tests {
     #[test]
     fn file_writer_bad_name() {
         match io::file_writer(&Path("?/?"), []) {
-          result::Err(copy e) => {
-            assert!(str::starts_with(e, "error opening"));
+          result::Err(e) => {
+            assert!(e.starts_with("error opening"));
           }
           result::Ok(_) => fail!()
         }
@@ -1982,8 +1987,8 @@ mod tests {
     #[test]
     fn buffered_file_writer_bad_name() {
         match io::buffered_file_writer(&Path("?/?")) {
-          result::Err(copy e) => {
-            assert!(str::starts_with(e, "error opening"));
+          result::Err(e) => {
+            assert!(e.starts_with("error opening"));
           }
           result::Ok(_) => fail!()
         }
@@ -1991,7 +1996,7 @@ mod tests {
 
     #[test]
     fn bytes_buffer_overwrite() {
-        let wr = BytesWriter();
+        let wr = BytesWriter::new();
         wr.write([0u8, 1u8, 2u8, 3u8]);
         assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
         wr.seek(-2, SeekCur);
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 800ce9f05dc..2197feea452 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -24,8 +24,6 @@ An external iterator object implementing the interface in the `iterator` module
 internal iterator by calling the `advance` method. For example:
 
 ~~~ {.rust}
-use core::iterator::*;
-
 let xs = [0u, 1, 2, 3, 4, 5];
 let ys = [30, 40, 50, 60];
 let mut it = xs.iter().chain(ys.iter());
@@ -42,30 +40,26 @@ much easier to implement.
 
 use cmp::Ord;
 use option::{Option, Some, None};
-use vec::OwnedVector;
 use num::{One, Zero};
 use ops::{Add, Mul};
 
+#[allow(missing_doc)]
 pub trait Times {
     fn times(&self, it: &fn() -> bool) -> bool;
 }
 
-/**
- * Transform an internal iterator into an owned vector.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * let xs = ~[1, 2, 3];
- * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
- * assert_eq!(xs, ys);
- * ~~~
- */
-#[inline(always)]
-pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
-    let mut v = ~[];
-    for iter |x| { v.push(x) }
-    v
+#[allow(missing_doc)]
+pub trait FromIter<T> {
+    /// Build a container with elements from an internal iterator.
+    ///
+    /// # Example:
+    ///
+    /// ~~~ {.rust}
+    /// let xs = ~[1, 2, 3];
+    /// let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) };
+    /// assert_eq!(xs, ys);
+    /// ~~~
+    pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self;
 }
 
 /**
@@ -257,10 +251,13 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use int;
+    use uint;
+
     #[test]
-    fn test_to_vec() {
+    fn test_from_iter() {
         let xs = ~[1, 2, 3];
-        let ys = do to_vec |f| { xs.each(|x| f(*x)) };
+        let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) };
         assert_eq!(xs, ys);
     }
 
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index a5679e6dbff..e65904a6899 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -17,9 +17,17 @@ implementing the `Iterator` trait.
 
 */
 
-use prelude::*;
+use cmp;
+use iter::{FromIter, Times};
 use num::{Zero, One};
-
+use option::{Option, Some, None};
+use ops::{Add, Mul};
+use cmp::Ord;
+use clone::Clone;
+
+/// An interface for dealing with "external iterators". These types of iterators
+/// can be resumed at any time as all state is stored internally as opposed to
+/// being located on the call stack.
 pub trait Iterator<A> {
     /// Advance the iterator and return the next value. Return `None` when the end is reached.
     fn next(&mut self) -> Option<A>;
@@ -30,27 +38,276 @@ pub trait Iterator<A> {
 ///
 /// In the future these will be default methods instead of a utility trait.
 pub trait IteratorUtil<A> {
-    fn chain<U: Iterator<A>>(self, other: U) -> ChainIterator<Self, U>;
-    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<Self, U>;
+    /// Chain this iterator with another, returning a new iterator which will
+    /// finish iterating over the current iterator, and then it will iterate
+    /// over the other specified iterator.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [0];
+    /// let b = [1];
+    /// let mut it = a.iter().chain_(b.iter());
+    /// assert_eq!(it.next().get(), &0);
+    /// assert_eq!(it.next().get(), &1);
+    /// assert!(it.next().is_none());
+    /// ~~~
+    fn chain_<U: Iterator<A>>(self, other: U) -> ChainIterator<A, Self, U>;
+
+    /// Creates an iterator which iterates over both this and the specified
+    /// iterators simultaneously, yielding the two elements as pairs. When
+    /// either iterator returns None, all further invocations of next() will
+    /// return None.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [0];
+    /// let b = [1];
+    /// let mut it = a.iter().zip(b.iter());
+    /// assert_eq!(it.next().get(), (&0, &1));
+    /// assert!(it.next().is_none());
+    /// ~~~
+    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<A, Self, B, U>;
+
     // FIXME: #5898: should be called map
+    /// Creates a new iterator which will apply the specified function to each
+    /// element returned by the first, yielding the mapped element instead. This
+    /// similar to the `vec::map` function.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2];
+    /// let mut it = a.iter().transform(|&x| 2 * x);
+    /// assert_eq!(it.next().get(), 2);
+    /// assert_eq!(it.next().get(), 4);
+    /// assert!(it.next().is_none());
+    /// ~~~
     fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
+
+    /// Creates an iterator which applies the predicate to each element returned
+    /// by this iterator. Only elements which have the predicate evaluate to
+    /// `true` will be yielded.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2];
+    /// let mut it = a.iter().filter(|&x| *x > 1);
+    /// assert_eq!(it.next().get(), &2);
+    /// assert!(it.next().is_none());
+    /// ~~~
     fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>;
+
+    /// Creates an iterator which both filters and maps elements.
+    /// If the specified function returns None, the element is skipped.
+    /// Otherwise the option is unwrapped and the new value is yielded.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2];
+    /// let mut it = a.iter().filter_map(|&x| if x > 1 {Some(2 * x)} else {None});
+    /// assert_eq!(it.next().get(), 4);
+    /// assert!(it.next().is_none());
+    /// ~~~
     fn filter_map<'r,  B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, Self>;
-    fn enumerate(self) -> EnumerateIterator<Self>;
+
+    /// Creates an iterator which yields a pair of the value returned by this
+    /// iterator plus the current index of iteration.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [100, 200];
+    /// let mut it = a.iter().enumerate();
+    /// assert_eq!(it.next().get(), (0, &100));
+    /// assert_eq!(it.next().get(), (1, &200));
+    /// assert!(it.next().is_none());
+    /// ~~~
+    fn enumerate(self) -> EnumerateIterator<A, Self>;
+
+    /// Creates an iterator which invokes the predicate on elements until it
+    /// returns false. Once the predicate returns false, all further elements are
+    /// yielded.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 2, 1];
+    /// let mut it = a.iter().skip_while(|&a| *a < 3);
+    /// assert_eq!(it.next().get(), &3);
+    /// assert_eq!(it.next().get(), &2);
+    /// assert_eq!(it.next().get(), &1);
+    /// assert!(it.next().is_none());
+    /// ~~~
     fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>;
+
+    /// Creates an iterator which yields elements so long as the predicate
+    /// returns true. After the predicate returns false for the first time, no
+    /// further elements will be yielded.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 2, 1];
+    /// let mut it = a.iter().take_while(|&a| *a < 3);
+    /// assert_eq!(it.next().get(), &1);
+    /// assert_eq!(it.next().get(), &2);
+    /// assert!(it.next().is_none());
+    /// ~~~
     fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
-    fn skip(self, n: uint) -> SkipIterator<Self>;
-    fn take(self, n: uint) -> TakeIterator<Self>;
+
+    /// Creates an iterator which skips the first `n` elements of this iterator,
+    /// and then it yields all further items.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter().skip(3);
+    /// assert_eq!(it.next().get(), &4);
+    /// assert_eq!(it.next().get(), &5);
+    /// assert!(it.next().is_none());
+    /// ~~~
+    fn skip(self, n: uint) -> SkipIterator<A, Self>;
+
+    // FIXME: #5898: should be called take
+    /// Creates an iterator which yields the first `n` elements of this
+    /// iterator, and then it will always return None.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter().take_(3);
+    /// assert_eq!(it.next().get(), &1);
+    /// assert_eq!(it.next().get(), &2);
+    /// assert_eq!(it.next().get(), &3);
+    /// assert!(it.next().is_none());
+    /// ~~~
+    fn take_(self, n: uint) -> TakeIterator<A, Self>;
+
+    /// Creates a new iterator which behaves in a similar fashion to foldl.
+    /// There is a state which is passed between each iteration and can be
+    /// mutated as necessary. The yielded values from the closure are yielded
+    /// from the ScanIterator instance when not None.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter().scan(1, |fac, &x| {
+    ///   *fac = *fac * x;
+    ///   Some(*fac)
+    /// });
+    /// assert_eq!(it.next().get(), 1);
+    /// assert_eq!(it.next().get(), 2);
+    /// assert_eq!(it.next().get(), 6);
+    /// assert_eq!(it.next().get(), 24);
+    /// assert_eq!(it.next().get(), 120);
+    /// assert!(it.next().is_none());
+    /// ~~~
     fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>)
         -> ScanIterator<'r, A, B, Self, St>;
+
+    /// An adaptation of an external iterator to the for-loop protocol of rust.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::iterator::Counter;
+    ///
+    /// for Counter::new(0, 10).advance |i| {
+    ///     io::println(fmt!("%d", i));
+    /// }
+    /// ~~~
     fn advance(&mut self, f: &fn(A) -> bool) -> bool;
-    fn to_vec(&mut self) -> ~[A];
+
+    /// Loops through the entire iterator, collecting all of the elements into
+    /// a container implementing `FromIter`.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let b: ~[int] = a.iter().transform(|&x| x).collect();
+    /// assert!(a == b);
+    /// ~~~
+    fn collect<B: FromIter<A>>(&mut self) -> B;
+
+    /// Loops through `n` iterations, returning the `n`th element of the
+    /// iterator.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter();
+    /// assert!(it.nth(2).get() == &3);
+    /// assert!(it.nth(2) == None);
+    /// ~~~
     fn nth(&mut self, n: uint) -> Option<A>;
-    fn last(&mut self) -> Option<A>;
+
+    /// Loops through the entire iterator, returning the last element of the
+    /// iterator.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// assert!(a.iter().last().get() == &5);
+    /// ~~~
+    // FIXME: #5898: should be called `last`
+    fn last_(&mut self) -> Option<A>;
+
+    /// Performs a fold operation over the entire iterator, returning the
+    /// eventual state at the end of the iteration.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// assert!(a.iter().fold(0, |a, &b| a + b) == 15);
+    /// ~~~
     fn fold<B>(&mut self, start: B, f: &fn(B, A) -> B) -> B;
+
+    /// Counts the number of elements in this iterator.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter();
+    /// assert!(it.count() == 5);
+    /// assert!(it.count() == 0);
+    /// ~~~
     fn count(&mut self) -> uint;
-    fn all(&mut self, f: &fn(&A) -> bool) -> bool;
-    fn any(&mut self, f: &fn(&A) -> bool) -> bool;
+
+    /// Tests whether the predicate holds true for all elements in the iterator.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// assert!(a.iter().all(|&x| *x > 0));
+    /// assert!(!a.iter().all(|&x| *x > 2));
+    /// ~~~
+    fn all(&mut self, f: &fn(A) -> bool) -> bool;
+
+    /// Tests whether any element of an iterator satisfies the specified
+    /// predicate.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter();
+    /// assert!(it.any_(|&x| *x == 3));
+    /// assert!(!it.any_(|&x| *x == 3));
+    /// ~~~
+    fn any_(&mut self, f: &fn(A) -> bool) -> bool;
 }
 
 /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
@@ -59,12 +316,12 @@ pub trait IteratorUtil<A> {
 /// In the future these will be default methods instead of a utility trait.
 impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     #[inline(always)]
-    fn chain<U: Iterator<A>>(self, other: U) -> ChainIterator<T, U> {
+    fn chain_<U: Iterator<A>>(self, other: U) -> ChainIterator<A, T, U> {
         ChainIterator{a: self, b: other, flag: false}
     }
 
     #[inline(always)]
-    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> {
+    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<A, T, B, U> {
         ZipIterator{a: self, b: other}
     }
 
@@ -85,7 +342,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     }
 
     #[inline(always)]
-    fn enumerate(self) -> EnumerateIterator<T> {
+    fn enumerate(self) -> EnumerateIterator<A, T> {
         EnumerateIterator{iter: self, count: 0}
     }
 
@@ -100,12 +357,13 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     }
 
     #[inline(always)]
-    fn skip(self, n: uint) -> SkipIterator<T> {
+    fn skip(self, n: uint) -> SkipIterator<A, T> {
         SkipIterator{iter: self, n: n}
     }
 
+    // FIXME: #5898: should be called take
     #[inline(always)]
-    fn take(self, n: uint) -> TakeIterator<T> {
+    fn take_(self, n: uint) -> TakeIterator<A, T> {
         TakeIterator{iter: self, n: n}
     }
 
@@ -129,8 +387,8 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     }
 
     #[inline(always)]
-    fn to_vec(&mut self) -> ~[A] {
-        iter::to_vec::<A>(|f| self.advance(f))
+    fn collect<B: FromIter<A>>(&mut self) -> B {
+        FromIter::from_iter::<A, B>(|f| self.advance(f))
     }
 
     /// Return the `n`th item yielded by an iterator.
@@ -147,7 +405,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
 
     /// Return the last item yielded by an iterator.
     #[inline(always)]
-    fn last(&mut self) -> Option<A> {
+    fn last_(&mut self) -> Option<A> {
         let mut last = None;
         for self.advance |x| { last = Some(x); }
         last
@@ -171,19 +429,29 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) }
 
     #[inline(always)]
-    fn all(&mut self, f: &fn(&A) -> bool) -> bool {
-        for self.advance |x| { if !f(&x) { return false; } }
+    fn all(&mut self, f: &fn(A) -> bool) -> bool {
+        for self.advance |x| { if !f(x) { return false; } }
         return true;
     }
 
     #[inline(always)]
-    fn any(&mut self, f: &fn(&A) -> bool) -> bool {
-        for self.advance |x| { if f(&x) { return true; } }
+    fn any_(&mut self, f: &fn(A) -> bool) -> bool {
+        for self.advance |x| { if f(x) { return true; } }
         return false;
     }
 }
 
+/// A trait for iterators over elements which can be added together
 pub trait AdditiveIterator<A> {
+    /// Iterates over the entire iterator, summing up all the elements
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter().transform(|&x| x);
+    /// assert!(it.sum() == 15);
+    /// ~~~
     fn sum(&mut self) -> A;
 }
 
@@ -192,7 +460,23 @@ impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
     fn sum(&mut self) -> A { self.fold(Zero::zero::<A>(), |s, x| s + x) }
 }
 
+/// A trait for iterators over elements whose elements can be multiplied
+/// together.
 pub trait MultiplicativeIterator<A> {
+    /// Iterates over the entire iterator, multiplying all the elements
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::iterator::Counter;
+    ///
+    /// fn factorial(n: uint) -> uint {
+    ///     Counter::new(1u, 1).take_while(|&i| i <= n).product()
+    /// }
+    /// assert!(factorial(0) == 1);
+    /// assert!(factorial(1) == 1);
+    /// assert!(factorial(5) == 120);
+    /// ~~~
     fn product(&mut self) -> A;
 }
 
@@ -201,8 +485,27 @@ impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
     fn product(&mut self) -> A { self.fold(One::one::<A>(), |p, x| p * x) }
 }
 
+/// A trait for iterators over elements which can be compared to one another.
+/// The type of each element must ascribe to the `Ord` trait.
 pub trait OrdIterator<A> {
+    /// Consumes the entire iterator to return the maximum element.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// assert!(a.iter().max().get() == &5);
+    /// ~~~
     fn max(&mut self) -> Option<A>;
+
+    /// Consumes the entire iterator to return the minimum element.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// assert!(a.iter().min().get() == &1);
+    /// ~~~
     fn min(&mut self) -> Option<A>;
 }
 
@@ -228,13 +531,15 @@ impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
     }
 }
 
-pub struct ChainIterator<T, U> {
+/// An iterator which strings two iterators together
+// FIXME #6967: Dummy A parameter to get around type inference bug
+pub struct ChainIterator<A, T, U> {
     priv a: T,
     priv b: U,
     priv flag: bool
 }
 
-impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for ChainIterator<T, U> {
+impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for ChainIterator<A, T, U> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.flag {
@@ -250,12 +555,14 @@ impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for ChainIterator<T, U> {
     }
 }
 
-pub struct ZipIterator<T, U> {
+/// An iterator which iterates two other iterators simultaneously
+// FIXME #6967: Dummy A & B parameters to get around type inference bug
+pub struct ZipIterator<A, T, B, U> {
     priv a: T,
     priv b: U
 }
 
-impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U> {
+impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<A, T, B, U> {
     #[inline]
     fn next(&mut self) -> Option<(A, B)> {
         match (self.a.next(), self.b.next()) {
@@ -265,6 +572,7 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U
     }
 }
 
+/// An iterator which maps the values of `iter` with `f`
 pub struct MapIterator<'self, A, B, T> {
     priv iter: T,
     priv f: &'self fn(A) -> B
@@ -280,6 +588,7 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
     }
 }
 
+/// An iterator which filters the elements of `iter` with `predicate`
 pub struct FilterIterator<'self, A, T> {
     priv iter: T,
     priv predicate: &'self fn(&A) -> bool
@@ -299,6 +608,7 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
     }
 }
 
+/// An iterator which uses `f` to both filter and map elements from `iter`
 pub struct FilterMapIterator<'self, A, B, T> {
     priv iter: T,
     priv f: &'self fn(A) -> Option<B>
@@ -317,12 +627,14 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMapIterator<'self, A, B,
     }
 }
 
-pub struct EnumerateIterator<T> {
+/// An iterator which yields the current count and the element during iteration
+// FIXME #6967: Dummy A parameter to get around type inference bug
+pub struct EnumerateIterator<A, T> {
     priv iter: T,
     priv count: uint
 }
 
-impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
+impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<A, T> {
     #[inline]
     fn next(&mut self) -> Option<(uint, A)> {
         match self.iter.next() {
@@ -336,6 +648,7 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
     }
 }
 
+/// An iterator which rejects elements while `predicate` is true
 pub struct SkipWhileIterator<'self, A, T> {
     priv iter: T,
     priv flag: bool,
@@ -367,6 +680,7 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for SkipWhileIterator<'self, A, T> {
     }
 }
 
+/// An iterator which only accepts elements while `predicate` is true
 pub struct TakeWhileIterator<'self, A, T> {
     priv iter: T,
     priv flag: bool,
@@ -394,12 +708,14 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
     }
 }
 
-pub struct SkipIterator<T> {
+/// An iterator which skips over `n` elements of `iter`.
+// FIXME #6967: Dummy A parameter to get around type inference bug
+pub struct SkipIterator<A, T> {
     priv iter: T,
     priv n: uint
 }
 
-impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<T> {
+impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<A, T> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         let mut next = self.iter.next();
@@ -425,12 +741,14 @@ impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<T> {
     }
 }
 
-pub struct TakeIterator<T> {
+/// An iterator which only iterates over the first `n` iterations of `iter`.
+// FIXME #6967: Dummy A parameter to get around type inference bug
+pub struct TakeIterator<A, T> {
     priv iter: T,
     priv n: uint
 }
 
-impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
+impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<A, T> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         let next = self.iter.next();
@@ -443,9 +761,12 @@ impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
     }
 }
 
+/// An iterator to maintain state while iterating another iterator
 pub struct ScanIterator<'self, A, B, T, St> {
     priv iter: T,
     priv f: &'self fn(&mut St, A) -> Option<B>,
+
+    /// The current internal state to be passed to the closure next.
     state: St
 }
 
@@ -456,14 +777,18 @@ impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for ScanIterator<'self, A, B,
     }
 }
 
+/// An iterator which just modifies the contained state throughout iteration.
 pub struct UnfoldrIterator<'self, A, St> {
     priv f: &'self fn(&mut St) -> Option<A>,
+    /// Internal state that will be yielded on the next iteration
     state: St
 }
 
-pub impl<'self, A, St> UnfoldrIterator<'self, A, St> {
+impl<'self, A, St> UnfoldrIterator<'self, A, St> {
+    /// Creates a new iterator with the specified closure as the "iterator
+    /// function" and an initial state to eventually pass to the iterator
     #[inline]
-    fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St)
+    pub fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St)
         -> UnfoldrIterator<'self, A, St> {
         UnfoldrIterator {
             f: f,
@@ -479,15 +804,19 @@ impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
     }
 }
 
-/// An infinite iterator starting at `start` and advancing by `step` with each iteration
+/// An infinite iterator starting at `start` and advancing by `step` with each
+/// iteration
 pub struct Counter<A> {
+    /// The current state the counter is at (next value to be yielded)
     state: A,
+    /// The amount that this iterator is stepping by
     step: A
 }
 
-pub impl<A> Counter<A> {
+impl<A> Counter<A> {
+    /// Creates a new counter with the specified start/step
     #[inline(always)]
-    fn new(start: A, step: A) -> Counter<A> {
+    pub fn new(start: A, step: A) -> Counter<A> {
         Counter{state: start, step: step}
     }
 }
@@ -506,10 +835,13 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use iter;
+    use uint;
+
     #[test]
-    fn test_counter_to_vec() {
-        let mut it = Counter::new(0, 5).take(10);
-        let xs = iter::to_vec(|f| it.advance(f));
+    fn test_counter_from_iter() {
+        let mut it = Counter::new(0, 5).take_(10);
+        let xs: ~[int] = iter::FromIter::from_iter::<int, ~[int]>(|f| it.advance(f));
         assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
     }
 
@@ -518,18 +850,18 @@ mod tests {
         let xs = [0u, 1, 2, 3, 4, 5];
         let ys = [30u, 40, 50, 60];
         let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
-        let mut it = xs.iter().chain(ys.iter());
+        let mut it = xs.iter().chain_(ys.iter());
         let mut i = 0;
-        for it.advance |&x: &uint| {
+        for it.advance |&x| {
             assert_eq!(x, expected[i]);
             i += 1;
         }
         assert_eq!(i, expected.len());
 
-        let ys = Counter::new(30u, 10).take(4);
-        let mut it = xs.iter().transform(|&x| x).chain(ys);
+        let ys = Counter::new(30u, 10).take_(4);
+        let mut it = xs.iter().transform(|&x| x).chain_(ys);
         let mut i = 0;
-        for it.advance |x: uint| {
+        for it.advance |x| {
             assert_eq!(x, expected[i]);
             i += 1;
         }
@@ -538,16 +870,16 @@ mod tests {
 
     #[test]
     fn test_filter_map() {
-        let mut it = Counter::new(0u, 1u).take(10)
-            .filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None });
-        assert_eq!(it.to_vec(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
+        let mut it = Counter::new(0u, 1u).take_(10)
+            .filter_map(|x| if x.is_even() { Some(x*x) } else { None });
+        assert_eq!(it.collect::<~[uint]>(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
     }
 
     #[test]
     fn test_iterator_enumerate() {
         let xs = [0u, 1, 2, 3, 4, 5];
         let mut it = xs.iter().enumerate();
-        for it.advance |(i, &x): (uint, &uint)| {
+        for it.advance |(i, &x)| {
             assert_eq!(i, x);
         }
     }
@@ -558,7 +890,7 @@ mod tests {
         let ys = [0u, 1, 2, 3, 5, 13];
         let mut it = xs.iter().take_while(|&x| *x < 15u);
         let mut i = 0;
-        for it.advance |&x: &uint| {
+        for it.advance |&x| {
             assert_eq!(x, ys[i]);
             i += 1;
         }
@@ -571,7 +903,7 @@ mod tests {
         let ys = [15, 16, 17, 19];
         let mut it = xs.iter().skip_while(|&x| *x < 15u);
         let mut i = 0;
-        for it.advance |&x: &uint| {
+        for it.advance |&x| {
             assert_eq!(x, ys[i]);
             i += 1;
         }
@@ -584,7 +916,7 @@ mod tests {
         let ys = [13, 15, 16, 17, 19, 20, 30];
         let mut it = xs.iter().skip(5);
         let mut i = 0;
-        for it.advance |&x: &uint| {
+        for it.advance |&x| {
             assert_eq!(x, ys[i]);
             i += 1;
         }
@@ -595,9 +927,9 @@ mod tests {
     fn test_iterator_take() {
         let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
         let ys = [0u, 1, 2, 3, 5];
-        let mut it = xs.iter().take(5);
+        let mut it = xs.iter().take_(5);
         let mut i = 0;
-        for it.advance |&x: &uint| {
+        for it.advance |&x| {
             assert_eq!(x, ys[i]);
             i += 1;
         }
@@ -655,8 +987,8 @@ mod tests {
     #[test]
     fn test_iterator_last() {
         let v = &[0, 1, 2, 3, 4];
-        assert_eq!(v.iter().last().unwrap(), &4);
-        assert_eq!(v.slice(0, 1).iter().last().unwrap(), &0);
+        assert_eq!(v.iter().last_().unwrap(), &4);
+        assert_eq!(v.slice(0, 1).iter().last_().unwrap(), &0);
     }
 
     #[test]
@@ -700,20 +1032,27 @@ mod tests {
     }
 
     #[test]
+    fn test_collect() {
+        let a = ~[1, 2, 3, 4, 5];
+        let b: ~[int] = a.iter().transform(|&x| x).collect();
+        assert_eq!(a, b);
+    }
+
+    #[test]
     fn test_all() {
         let v = ~&[1, 2, 3, 4, 5];
-        assert!(v.iter().all(|&x| *x < 10));
+        assert!(v.iter().all(|&x| x < 10));
         assert!(!v.iter().all(|&x| x.is_even()));
-        assert!(!v.iter().all(|&x| *x > 100));
+        assert!(!v.iter().all(|&x| x > 100));
         assert!(v.slice(0, 0).iter().all(|_| fail!()));
     }
 
     #[test]
     fn test_any() {
         let v = ~&[1, 2, 3, 4, 5];
-        assert!(v.iter().any(|&x| *x < 10));
-        assert!(v.iter().any(|&x| x.is_even()));
-        assert!(!v.iter().any(|&x| *x > 100));
-        assert!(!v.slice(0, 0).iter().any(|_| fail!()));
+        assert!(v.iter().any_(|&x| x < 10));
+        assert!(v.iter().any_(|&x| x.is_even()));
+        assert!(!v.iter().any_(|&x| x > 100));
+        assert!(!v.slice(0, 0).iter().any_(|_| fail!()));
     }
 }
diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs
index d9b3e35b6b9..05c963a32cc 100644
--- a/src/libstd/kinds.rs
+++ b/src/libstd/kinds.rs
@@ -37,6 +37,8 @@ instead implement `Clone`.
 
 */
 
+#[allow(missing_doc)];
+
 #[lang="copy"]
 pub trait Copy {
     // Empty.
@@ -51,3 +53,8 @@ pub trait Owned {
 pub trait Const {
     // Empty.
 }
+
+#[lang="sized"]
+pub trait Sized {
+    // Empty.
+}
diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs
index 7ae3f0fd2d4..26205c930f0 100644
--- a/src/libstd/libc.rs
+++ b/src/libstd/libc.rs
@@ -64,6 +64,7 @@
 */
 
 #[allow(non_camel_case_types)];
+#[allow(missing_doc)];
 
 // Initial glob-exports mean that all the contents of all the modules
 // wind up exported, if you're interested in writing platform-specific code.
@@ -158,8 +159,8 @@ pub use libc::funcs::c95::stdlib::{free, getenv, labs, malloc, rand};
 pub use libc::funcs::c95::stdlib::{realloc, srand, strtod, strtol};
 pub use libc::funcs::c95::stdlib::{strtoul, system};
 
-pub use libc::funcs::c95::string::{memchr, memcmp, memcpy, memmove};
-pub use libc::funcs::c95::string::{memset, strcat, strchr, strcmp};
+pub use libc::funcs::c95::string::{memchr, memcmp};
+pub use libc::funcs::c95::string::{strcat, strchr, strcmp};
 pub use libc::funcs::c95::string::{strcoll, strcpy, strcspn, strerror};
 pub use libc::funcs::c95::string::{strlen, strncat, strncmp, strncpy};
 pub use libc::funcs::c95::string::{strpbrk, strrchr, strspn, strstr};
@@ -1451,26 +1452,17 @@ pub mod funcs {
                                -> size_t;
                 unsafe fn wcslen(buf: *wchar_t) -> size_t;
 
+                // Omitted: memcpy, memmove, memset (provided by LLVM)
+
                 // These are fine to execute on the Rust stack. They must be,
                 // in fact, because LLVM generates calls to them!
                 #[rust_stack]
                 #[inline(always)]
-                unsafe fn memcpy(s: *c_void, ct: *c_void, n: size_t)
-                              -> *c_void;
-                #[rust_stack]
-                #[inline(always)]
-                unsafe fn memmove(s: *c_void, ct: *c_void, n: size_t)
-                               -> *c_void;
-                #[rust_stack]
-                #[inline(always)]
                 unsafe fn memcmp(cx: *c_void, ct: *c_void, n: size_t)
                               -> c_int;
                 #[rust_stack]
                 #[inline(always)]
                 unsafe fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
-                #[rust_stack]
-                #[inline(always)]
-                unsafe fn memset(s: *c_void, c: c_int, n: size_t) -> *c_void;
             }
         }
     }
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index 2cbf8b9f05e..82c01c998cf 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -27,8 +27,11 @@ magic.
 */
 
 use prelude::*;
+
 use task::local_data_priv::{local_get, local_pop, local_modify, local_set, Handle};
 
+#[cfg(test)] use task;
+
 /**
  * Indexes a task-local data slot. The function's code pointer is used for
  * comparison. Recommended use is to write an empty function for each desired
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
index 693d7863297..c2f854179b8 100644
--- a/src/libstd/logging.rs
+++ b/src/libstd/logging.rs
@@ -36,6 +36,7 @@ pub fn console_off() {
 
 #[cfg(not(test))]
 #[lang="log_type"]
+#[allow(missing_doc)]
 pub fn log_type<T>(level: u32, object: &T) {
     use cast;
     use container::Container;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index fda48b6ffb7..8d221fe6a1b 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -38,16 +38,19 @@ macro_rules! rtassert (
     } )
 )
 
+
+// The do_abort function was originally inside the abort macro, but
+// this was ICEing the compiler so it has been moved outside. Now this
+// seems to work?
+#[allow(missing_doc)]
+pub fn do_abort() -> ! {
+    unsafe { ::libc::abort(); }
+}
+
 macro_rules! abort(
     ($( $msg:expr),+) => ( {
         rtdebug!($($msg),+);
-
-        do_abort();
-
-        // NB: This is in a fn to avoid putting the `unsafe` block in a macro,
-        // which causes spurious 'unnecessary unsafe block' warnings.
-        fn do_abort() -> ! {
-            unsafe { ::libc::abort(); }
-        }
+        ::macros::do_abort();
     } )
 )
+
diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs
index ecde1eb1917..7d0defea05a 100644
--- a/src/libstd/managed.rs
+++ b/src/libstd/managed.rs
@@ -21,6 +21,7 @@ pub mod raw {
     pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
     pub static RC_IMMORTAL : uint = 0x77777777;
 
+    #[allow(missing_doc)]
     pub struct BoxHeaderRepr {
         ref_count: uint,
         type_desc: *TyDesc,
@@ -28,6 +29,7 @@ pub mod raw {
         next: *BoxRepr,
     }
 
+    #[allow(missing_doc)]
     pub struct BoxRepr {
         header: BoxHeaderRepr,
         data: u8
@@ -38,14 +40,14 @@ pub mod raw {
 /// Determine if two shared boxes point to the same object
 #[inline(always)]
 pub fn ptr_eq<T>(a: @T, b: @T) -> bool {
-    let a_ptr: *T = to_unsafe_ptr(&*a), b_ptr: *T = to_unsafe_ptr(&*b);
+    let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
     a_ptr == b_ptr
 }
 
 /// Determine if two mutable shared boxes point to the same object
 #[inline(always)]
 pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
-    let a_ptr: *T = to_unsafe_ptr(&*a), b_ptr: *T = to_unsafe_ptr(&*b);
+    let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
     a_ptr == b_ptr
 }
 
diff --git a/src/libstd/num/cmath.rs b/src/libstd/num/cmath.rs
index 9626224916b..96d3b79e338 100644
--- a/src/libstd/num/cmath.rs
+++ b/src/libstd/num/cmath.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(missing_doc)];
+
 // function names are almost identical to C's libmath, a few have been
 // renamed, grep for "rename:"
 
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index b578084268a..7f981187300 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -9,11 +9,14 @@
 // except according to those terms.
 
 //! Operations and constants for `f32`
+#[allow(missing_doc)];
 
 use libc::c_int;
 use num::{Zero, One, strconv};
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
+use num;
 use prelude::*;
+use to_str;
 
 pub use cmath::c_float_targ_consts::*;
 
@@ -388,7 +391,7 @@ impl Fractional for f32 {
 
 impl Algebraic for f32 {
     #[inline(always)]
-    fn pow(&self, n: f32) -> f32 { pow(*self, n) }
+    fn pow(&self, n: &f32) -> f32 { pow(*self, *n) }
 
     #[inline(always)]
     fn sqrt(&self) -> f32 { sqrt(*self) }
@@ -400,7 +403,7 @@ impl Algebraic for f32 {
     fn cbrt(&self) -> f32 { cbrt(*self) }
 
     #[inline(always)]
-    fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
+    fn hypot(&self, other: &f32) -> f32 { hypot(*self, *other) }
 }
 
 impl Trigonometric for f32 {
@@ -423,7 +426,7 @@ impl Trigonometric for f32 {
     fn atan(&self) -> f32 { atan(*self) }
 
     #[inline(always)]
-    fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
+    fn atan2(&self, other: &f32) -> f32 { atan2(*self, *other) }
 
     /// Simultaneously computes the sine and cosine of the number
     #[inline(always)]
@@ -447,7 +450,7 @@ impl Exponential for f32 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base
     #[inline(always)]
-    fn log(&self, base: f32) -> f32 { self.ln() / base.ln() }
+    fn log(&self, base: &f32) -> f32 { self.ln() / base.ln() }
 
     /// Returns the base 2 logarithm of the number
     #[inline(always)]
@@ -958,9 +961,12 @@ impl num::FromStrRadix for f32 {
 #[cfg(test)]
 mod tests {
     use f32::*;
-    use num::*;
     use prelude::*;
 
+    use num::*;
+    use num;
+    use sys;
+
     #[test]
     fn test_num() {
         num::test_num(10f32, 2f32);
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index bca730c5748..6303e304576 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -10,10 +10,14 @@
 
 //! Operations and constants for `f64`
 
+#[allow(missing_doc)];
+
 use libc::c_int;
 use num::{Zero, One, strconv};
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
+use num;
 use prelude::*;
+use to_str;
 
 pub use cmath::c_double_targ_consts::*;
 pub use cmp::{min, max};
@@ -399,7 +403,7 @@ impl Fractional for f64 {
 
 impl Algebraic for f64 {
     #[inline(always)]
-    fn pow(&self, n: f64) -> f64 { pow(*self, n) }
+    fn pow(&self, n: &f64) -> f64 { pow(*self, *n) }
 
     #[inline(always)]
     fn sqrt(&self) -> f64 { sqrt(*self) }
@@ -411,7 +415,7 @@ impl Algebraic for f64 {
     fn cbrt(&self) -> f64 { cbrt(*self) }
 
     #[inline(always)]
-    fn hypot(&self, other: f64) -> f64 { hypot(*self, other) }
+    fn hypot(&self, other: &f64) -> f64 { hypot(*self, *other) }
 }
 
 impl Trigonometric for f64 {
@@ -434,7 +438,7 @@ impl Trigonometric for f64 {
     fn atan(&self) -> f64 { atan(*self) }
 
     #[inline(always)]
-    fn atan2(&self, other: f64) -> f64 { atan2(*self, other) }
+    fn atan2(&self, other: &f64) -> f64 { atan2(*self, *other) }
 
     /// Simultaneously computes the sine and cosine of the number
     #[inline(always)]
@@ -458,7 +462,7 @@ impl Exponential for f64 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base
     #[inline(always)]
-    fn log(&self, base: f64) -> f64 { self.ln() / base.ln() }
+    fn log(&self, base: &f64) -> f64 { self.ln() / base.ln() }
 
     /// Returns the base 2 logarithm of the number
     #[inline(always)]
@@ -999,9 +1003,12 @@ impl num::FromStrRadix for f64 {
 #[cfg(test)]
 mod tests {
     use f64::*;
-    use num::*;
     use prelude::*;
 
+    use num::*;
+    use num;
+    use sys;
+
     #[test]
     fn test_num() {
         num::test_num(10f64, 2f64);
diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs
index acc5e5a6f39..267a8890e82 100644
--- a/src/libstd/num/float.rs
+++ b/src/libstd/num/float.rs
@@ -20,10 +20,15 @@
 
 // PORT this must match in width according to architecture
 
+#[allow(missing_doc)];
+
+use f64;
 use libc::c_int;
 use num::{Zero, One, strconv};
 use num::FPCategory;
+use num;
 use prelude::*;
+use to_str;
 
 pub use f64::{add, sub, mul, div, rem, lt, le, eq, ne, ge, gt};
 pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor};
@@ -42,8 +47,8 @@ pub static neg_infinity: float = -1.0/0.0;
 /* Module: consts */
 pub mod consts {
     // FIXME (requires Issue #1433 to fix): replace with mathematical
-    // staticants from cmath.
-    /// Archimedes' staticant
+    // constants from cmath.
+    /// Archimedes' constant
     pub static pi: float = 3.14159265358979323846264338327950288;
 
     /// pi/2.0
@@ -470,8 +475,8 @@ impl Fractional for float {
 
 impl Algebraic for float {
     #[inline(always)]
-    fn pow(&self, n: float) -> float {
-        (*self as f64).pow(n as f64) as float
+    fn pow(&self, n: &float) -> float {
+        (*self as f64).pow(&(*n as f64)) as float
     }
 
     #[inline(always)]
@@ -490,8 +495,8 @@ impl Algebraic for float {
     }
 
     #[inline(always)]
-    fn hypot(&self, other: float) -> float {
-        (*self as f64).hypot(other as f64) as float
+    fn hypot(&self, other: &float) -> float {
+        (*self as f64).hypot(&(*other as f64)) as float
     }
 }
 
@@ -527,8 +532,8 @@ impl Trigonometric for float {
     }
 
     #[inline(always)]
-    fn atan2(&self, other: float) -> float {
-        (*self as f64).atan2(other as f64) as float
+    fn atan2(&self, other: &float) -> float {
+        (*self as f64).atan2(&(*other as f64)) as float
     }
 
     /// Simultaneously computes the sine and cosine of the number
@@ -561,8 +566,8 @@ impl Exponential for float {
 
     /// Returns the logarithm of the number with respect to an arbitrary base
     #[inline(always)]
-    fn log(&self, base: float) -> float {
-        (*self as f64).log(base as f64) as float
+    fn log(&self, base: &float) -> float {
+        (*self as f64).log(&(*base as f64)) as float
     }
 
     /// Returns the base 2 logarithm of the number
@@ -945,10 +950,13 @@ impl Float for float {
 
 #[cfg(test)]
 mod tests {
-    use num::*;
     use super::*;
     use prelude::*;
 
+    use num::*;
+    use num;
+    use sys;
+
     #[test]
     fn test_num() {
         num::test_num(10f, 2f);
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 27e872003ec..74f74d11b73 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -26,12 +26,17 @@ pub static bytes : uint = ($bits / 8);
 pub static min_value: $T = (-1 as $T) << (bits - 1);
 pub static max_value: $T = min_value - 1 as $T;
 
+/// Calculates the sum of two numbers
 #[inline(always)]
 pub fn add(x: $T, y: $T) -> $T { x + y }
+/// Subtracts the second number from the first
 #[inline(always)]
 pub fn sub(x: $T, y: $T) -> $T { x - y }
+/// Multiplies two numbers together
 #[inline(always)]
 pub fn mul(x: $T, y: $T) -> $T { x * y }
+/// Divides the first argument by the second argument (using integer division)
+/// Divides the first argument by the second argument (using integer division)
 #[inline(always)]
 pub fn div(x: $T, y: $T) -> $T { x / y }
 
@@ -58,16 +63,22 @@ pub fn div(x: $T, y: $T) -> $T { x / y }
 #[inline(always)]
 pub fn rem(x: $T, y: $T) -> $T { x % y }
 
+/// Returns true iff `x < y`
 #[inline(always)]
 pub fn lt(x: $T, y: $T) -> bool { x < y }
+/// Returns true iff `x <= y`
 #[inline(always)]
 pub fn le(x: $T, y: $T) -> bool { x <= y }
+/// Returns true iff `x == y`
 #[inline(always)]
 pub fn eq(x: $T, y: $T) -> bool { x == y }
+/// Returns true iff `x != y`
 #[inline(always)]
 pub fn ne(x: $T, y: $T) -> bool { x != y }
+/// Returns true iff `x >= y`
 #[inline(always)]
 pub fn ge(x: $T, y: $T) -> bool { x >= y }
+/// Returns true iff `x > y`
 #[inline(always)]
 pub fn gt(x: $T, y: $T) -> bool { x > y }
 
@@ -389,7 +400,7 @@ impl Integer for $T {
     #[inline(always)]
     fn gcd(&self, other: &$T) -> $T {
         // Use Euclid's algorithm
-        let mut m = *self, n = *other;
+        let mut (m, n) = (*self, *other);
         while m != 0 {
             let temp = m;
             m = n % temp;
@@ -557,6 +568,13 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use i16;
+    use i32;
+    use i64;
+    use i8;
+    use num;
+    use sys;
+
     #[test]
     fn test_num() {
         num::test_num(10 as $T, 2 as $T);
@@ -775,27 +793,27 @@ mod tests {
 
     #[test]
     fn test_parse_bytes() {
-        use str::to_bytes;
-        assert_eq!(parse_bytes(to_bytes("123"), 10u), Some(123 as $T));
-        assert_eq!(parse_bytes(to_bytes("1001"), 2u), Some(9 as $T));
-        assert_eq!(parse_bytes(to_bytes("123"), 8u), Some(83 as $T));
-        assert_eq!(i32::parse_bytes(to_bytes("123"), 16u), Some(291 as i32));
-        assert_eq!(i32::parse_bytes(to_bytes("ffff"), 16u), Some(65535 as i32));
-        assert_eq!(i32::parse_bytes(to_bytes("FFFF"), 16u), Some(65535 as i32));
-        assert_eq!(parse_bytes(to_bytes("z"), 36u), Some(35 as $T));
-        assert_eq!(parse_bytes(to_bytes("Z"), 36u), Some(35 as $T));
-
-        assert_eq!(parse_bytes(to_bytes("-123"), 10u), Some(-123 as $T));
-        assert_eq!(parse_bytes(to_bytes("-1001"), 2u), Some(-9 as $T));
-        assert_eq!(parse_bytes(to_bytes("-123"), 8u), Some(-83 as $T));
-        assert_eq!(i32::parse_bytes(to_bytes("-123"), 16u), Some(-291 as i32));
-        assert_eq!(i32::parse_bytes(to_bytes("-ffff"), 16u), Some(-65535 as i32));
-        assert_eq!(i32::parse_bytes(to_bytes("-FFFF"), 16u), Some(-65535 as i32));
-        assert_eq!(parse_bytes(to_bytes("-z"), 36u), Some(-35 as $T));
-        assert_eq!(parse_bytes(to_bytes("-Z"), 36u), Some(-35 as $T));
-
-        assert!(parse_bytes(to_bytes("Z"), 35u).is_none());
-        assert!(parse_bytes(to_bytes("-9"), 2u).is_none());
+        use str::StrSlice;
+        assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123 as $T));
+        assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9 as $T));
+        assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83 as $T));
+        assert_eq!(i32::parse_bytes("123".as_bytes(), 16u), Some(291 as i32));
+        assert_eq!(i32::parse_bytes("ffff".as_bytes(), 16u), Some(65535 as i32));
+        assert_eq!(i32::parse_bytes("FFFF".as_bytes(), 16u), Some(65535 as i32));
+        assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35 as $T));
+        assert_eq!(parse_bytes("Z".as_bytes(), 36u), Some(35 as $T));
+
+        assert_eq!(parse_bytes("-123".as_bytes(), 10u), Some(-123 as $T));
+        assert_eq!(parse_bytes("-1001".as_bytes(), 2u), Some(-9 as $T));
+        assert_eq!(parse_bytes("-123".as_bytes(), 8u), Some(-83 as $T));
+        assert_eq!(i32::parse_bytes("-123".as_bytes(), 16u), Some(-291 as i32));
+        assert_eq!(i32::parse_bytes("-ffff".as_bytes(), 16u), Some(-65535 as i32));
+        assert_eq!(i32::parse_bytes("-FFFF".as_bytes(), 16u), Some(-65535 as i32));
+        assert_eq!(parse_bytes("-z".as_bytes(), 36u), Some(-35 as $T));
+        assert_eq!(parse_bytes("-Z".as_bytes(), 36u), Some(-35 as $T));
+
+        assert!(parse_bytes("Z".as_bytes(), 35u).is_none());
+        assert!(parse_bytes("-9".as_bytes(), 2u).is_none());
     }
 
     #[test]
diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs
index 96b302d3174..a9893579721 100644
--- a/src/libstd/num/num.rs
+++ b/src/libstd/num/num.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 //! An interface for numeric types
+
+#[allow(missing_doc)];
+
 use cmp::{Eq, ApproxEq, Ord};
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
@@ -103,11 +106,11 @@ pub trait Fractional: Num
 }
 
 pub trait Algebraic {
-    fn pow(&self, n: Self) -> Self;
+    fn pow(&self, n: &Self) -> Self;
     fn sqrt(&self) -> Self;
     fn rsqrt(&self) -> Self;
     fn cbrt(&self) -> Self;
-    fn hypot(&self, other: Self) -> Self;
+    fn hypot(&self, other: &Self) -> Self;
 }
 
 pub trait Trigonometric {
@@ -117,7 +120,7 @@ pub trait Trigonometric {
     fn asin(&self) -> Self;
     fn acos(&self) -> Self;
     fn atan(&self) -> Self;
-    fn atan2(&self, other: Self) -> Self;
+    fn atan2(&self, other: &Self) -> Self;
     fn sin_cos(&self) -> (Self, Self);
 }
 
@@ -125,7 +128,7 @@ pub trait Exponential {
     fn exp(&self) -> Self;
     fn exp2(&self) -> Self;
     fn ln(&self) -> Self;
-    fn log(&self, base: Self) -> Self;
+    fn log(&self, base: &Self) -> Self;
     fn log2(&self) -> Self;
     fn log10(&self) -> Self;
 }
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 1d65b84b7ce..3905d82cd0f 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(missing_doc)];
+
 use container::Container;
 use core::cmp::{Ord, Eq};
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use option::{None, Option, Some};
 use char;
 use str;
+use str::{StrSlice};
 use kinds::Copy;
 use vec;
 use vec::{CopyableVector, ImmutableVector};
@@ -187,18 +190,18 @@ pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
     let _1: T = One::one();
 
     if is_NaN(num) {
-        return (str::to_bytes("NaN"), true);
+        return ("NaN".as_bytes().to_owned(), true);
     }
     else if is_inf(num){
         return match sign {
-            SignAll => (str::to_bytes("+inf"), true),
-            _       => (str::to_bytes("inf"), true)
+            SignAll => ("+inf".as_bytes().to_owned(), true),
+            _       => ("inf".as_bytes().to_owned(), true)
         }
     }
     else if is_neg_inf(num) {
         return match sign {
-            SignNone => (str::to_bytes("inf"), true),
-            _        => (str::to_bytes("-inf"), true),
+            SignNone => ("inf".as_bytes().to_owned(), true),
+            _        => ("-inf".as_bytes().to_owned(), true),
         }
     }
 
@@ -636,7 +639,7 @@ pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+Mul<T,T>+
         special: bool, exponent: ExponentFormat, empty_zero: bool,
         ignore_underscores: bool
         ) -> Option<T> {
-    from_str_bytes_common(str::to_bytes(buf), radix, negative,
+    from_str_bytes_common(buf.as_bytes(), radix, negative,
                           fractional, special, exponent, empty_zero,
                           ignore_underscores)
 }
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index e6267bfe9e1..2bc1ca9c673 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -27,34 +27,55 @@ pub static bytes : uint = ($bits / 8);
 pub static min_value: $T = 0 as $T;
 pub static max_value: $T = 0 as $T - 1 as $T;
 
+/// Calculates the sum of two numbers
 #[inline(always)]
 pub fn add(x: $T, y: $T) -> $T { x + y }
+/// Subtracts the second number from the first
 #[inline(always)]
 pub fn sub(x: $T, y: $T) -> $T { x - y }
+/// Multiplies two numbers together
 #[inline(always)]
 pub fn mul(x: $T, y: $T) -> $T { x * y }
+/// Divides the first argument by the second argument (using integer division)
 #[inline(always)]
 pub fn div(x: $T, y: $T) -> $T { x / y }
+/// Calculates the integer remainder when x is divided by y (equivalent to the
+/// '%' operator)
 #[inline(always)]
 pub fn rem(x: $T, y: $T) -> $T { x % y }
 
+/// Returns true iff `x < y`
 #[inline(always)]
 pub fn lt(x: $T, y: $T) -> bool { x < y }
+/// Returns true iff `x <= y`
 #[inline(always)]
 pub fn le(x: $T, y: $T) -> bool { x <= y }
+/// Returns true iff `x == y`
 #[inline(always)]
 pub fn eq(x: $T, y: $T) -> bool { x == y }
+/// Returns true iff `x != y`
 #[inline(always)]
 pub fn ne(x: $T, y: $T) -> bool { x != y }
+/// Returns true iff `x >= y`
 #[inline(always)]
 pub fn ge(x: $T, y: $T) -> bool { x >= y }
+/// Returns true iff `x > y`
 #[inline(always)]
 pub fn gt(x: $T, y: $T) -> bool { x > y }
 
 #[inline(always)]
-///
-/// Iterate over the range [`start`,`start`+`step`..`stop`)
-///
+/**
+ * Iterate through a range with a given step value.
+ *
+ * # Examples
+ * ~~~ {.rust}
+ * let nums = [1,2,3,4,5,6,7];
+ *
+ * for uint::range_step(0, nums.len() - 1, 2) |i| {
+ *     println(fmt!("%d & %d", nums[i], nums[i+1]));
+ * }
+ * ~~~
+ */
 pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool {
     let mut i = start;
     if step == 0 {
@@ -216,7 +237,7 @@ impl Integer for $T {
     #[inline(always)]
     fn gcd(&self, other: &$T) -> $T {
         // Use Euclid's algorithm
-        let mut m = *self, n = *other;
+        let mut (m, n) = (*self, *other);
         while m != 0 {
             let temp = m;
             m = n % temp;
@@ -402,6 +423,14 @@ mod tests {
     use super::*;
     use prelude::*;
 
+    use num;
+    use sys;
+    use u16;
+    use u32;
+    use u64;
+    use u8;
+    use uint;
+
     #[test]
     fn test_num() {
         num::test_num(10 as $T, 2 as $T);
@@ -509,16 +538,16 @@ mod tests {
 
     #[test]
     pub fn test_parse_bytes() {
-        use str::to_bytes;
-        assert_eq!(parse_bytes(to_bytes("123"), 10u), Some(123u as $T));
-        assert_eq!(parse_bytes(to_bytes("1001"), 2u), Some(9u as $T));
-        assert_eq!(parse_bytes(to_bytes("123"), 8u), Some(83u as $T));
-        assert_eq!(u16::parse_bytes(to_bytes("123"), 16u), Some(291u as u16));
-        assert_eq!(u16::parse_bytes(to_bytes("ffff"), 16u), Some(65535u as u16));
-        assert_eq!(parse_bytes(to_bytes("z"), 36u), Some(35u as $T));
-
-        assert!(parse_bytes(to_bytes("Z"), 10u).is_none());
-        assert!(parse_bytes(to_bytes("_"), 2u).is_none());
+        use str::StrSlice;
+        assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123u as $T));
+        assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9u as $T));
+        assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83u as $T));
+        assert_eq!(u16::parse_bytes("123".as_bytes(), 16u), Some(291u as u16));
+        assert_eq!(u16::parse_bytes("ffff".as_bytes(), 16u), Some(65535u as u16));
+        assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35u as $T));
+
+        assert!(parse_bytes("Z".as_bytes(), 10u).is_none());
+        assert!(parse_bytes("_".as_bytes(), 2u).is_none());
     }
 
     #[test]
diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs
index 389b643572c..9fea4376816 100644
--- a/src/libstd/old_iter.rs
+++ b/src/libstd/old_iter.rs
@@ -14,6 +14,8 @@
 
 */
 
+#[allow(missing_doc)];
+
 use cmp::{Eq, Ord};
 use kinds::Copy;
 use option::{None, Option, Some};
@@ -31,10 +33,6 @@ pub trait ReverseIter<A>: BaseIter<A> {
     fn each_reverse(&self, blk: &fn(&A) -> bool) -> bool;
 }
 
-pub trait MutableIter<A>: BaseIter<A> {
-    fn each_mut(&mut self, blk: &fn(&mut A) -> bool) -> bool;
-}
-
 pub trait ExtendedIter<A> {
     fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool;
     fn all(&self, blk: &fn(&A) -> bool) -> bool;
@@ -45,10 +43,6 @@ pub trait ExtendedIter<A> {
     fn flat_map_to_vec<B,IB: BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B];
 }
 
-pub trait ExtendedMutableIter<A> {
-    fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool) -> bool;
-}
-
 pub trait EqIter<A:Eq> {
     fn contains(&self, x: &A) -> bool;
     fn count(&self, x: &A) -> uint;
@@ -65,13 +59,6 @@ pub trait CopyableOrderedIter<A:Copy + Ord> {
     fn max(&self) -> A;
 }
 
-pub trait CopyableNonstrictIter<A:Copy> {
-    // Like "each", but copies out the value. If the receiver is mutated while
-    // iterating over it, the semantics must not be memory-unsafe but are
-    // otherwise undefined.
-    fn each_val(&const self, f: &fn(A) -> bool) -> bool;
-}
-
 // A trait for sequences that can be built by imperatively pushing elements
 // onto them.
 pub trait Buildable<A> {
diff --git a/src/libstd/ops.rs b/src/libstd/ops.rs
index 47ff45be687..77cfe62e495 100644
--- a/src/libstd/ops.rs
+++ b/src/libstd/ops.rs
@@ -10,6 +10,8 @@
 
 //! Traits for the built-in operators
 
+#[allow(missing_doc)];
+
 #[lang="drop"]
 pub trait Drop {
     fn finalize(&self);  // FIXME(#4332): Rename to "drop"? --pcwalton
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index be6ec8c8518..80f4fb7643c 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -46,12 +46,12 @@ use ops::Add;
 use kinds::Copy;
 use util;
 use num::Zero;
-use old_iter::{BaseIter, MutableIter, ExtendedIter};
-use old_iter;
+use iterator::Iterator;
 use str::StrSlice;
 use clone::DeepClone;
 
 #[cfg(test)] use str;
+#[cfg(test)] use iterator::IteratorUtil;
 
 /// The option type
 #[deriving(Clone, DeepClone, Eq)]
@@ -100,66 +100,39 @@ impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
     }
 }
 
-impl<T> BaseIter<T> for Option<T> {
-    /// Performs an operation on the contained value by reference
-    #[inline(always)]
-    fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) -> bool {
-        match *self { None => true, Some(ref t) => { f(t) } }
-    }
-
-    #[inline(always)]
-    fn size_hint(&self) -> Option<uint> {
-        if self.is_some() { Some(1) } else { Some(0) }
-    }
-}
-
-impl<T> MutableIter<T> for Option<T> {
-    #[inline(always)]
-    fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) -> bool {
-        match *self { None => true, Some(ref mut t) => { f(t) } }
+impl<T> Option<T> {
+    /// Return an iterator over the possibly contained value
+    #[inline]
+    pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
+        match *self {
+            Some(ref x) => OptionIterator{opt: Some(x)},
+            None => OptionIterator{opt: None}
+        }
     }
-}
 
-impl<A> ExtendedIter<A> for Option<A> {
-    pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool {
-        old_iter::eachi(self, blk)
-    }
-    pub fn all(&self, blk: &fn(&A) -> bool) -> bool {
-        old_iter::all(self, blk)
-    }
-    pub fn any(&self, blk: &fn(&A) -> bool) -> bool {
-        old_iter::any(self, blk)
-    }
-    pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B {
-        old_iter::foldl(self, b0, blk)
-    }
-    pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> {
-        old_iter::position(self, f)
-    }
-    fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] {
-        old_iter::map_to_vec(self, op)
-    }
-    fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB)
-        -> ~[B] {
-        old_iter::flat_map_to_vec(self, op)
+    /// Return a mutable iterator over the possibly contained value
+    #[inline]
+    pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
+        match *self {
+            Some(ref mut x) => OptionMutIterator{opt: Some(x)},
+            None => OptionMutIterator{opt: None}
+        }
     }
-}
 
-pub impl<T> Option<T> {
     /// Returns true if the option equals `none`
-    fn is_none(&const self) -> bool {
+    #[inline]
+    pub fn is_none(&const self) -> bool {
         match *self { None => true, Some(_) => false }
     }
 
     /// Returns true if the option contains some value
     #[inline(always)]
-    fn is_some(&const self) -> bool { !self.is_none() }
+    pub fn is_some(&const self) -> bool { !self.is_none() }
 
     /// Update an optional value by optionally running its content through a
     /// function that returns an option.
     #[inline(always)]
-    fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
-
+    pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
         match self {
             Some(t) => f(t),
             None => None
@@ -168,7 +141,7 @@ pub impl<T> Option<T> {
 
     /// Returns the leftmost Some() value, or None if both are None.
     #[inline(always)]
-    fn or(self, optb: Option<T>) -> Option<T> {
+    pub fn or(self, optb: Option<T>) -> Option<T> {
         match self {
             Some(opta) => Some(opta),
             _ => optb
@@ -178,45 +151,49 @@ pub impl<T> Option<T> {
     /// Update an optional value by optionally running its content by reference
     /// through a function that returns an option.
     #[inline(always)]
-    fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
-        match *self { Some(ref x) => f(x), None => None }
+    pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
+                            -> Option<U> {
+        match *self {
+            Some(ref x) => f(x),
+            None => None
+        }
     }
 
     /// Maps a `some` value from one type to another by reference
     #[inline(always)]
-    fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
+    pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
         match *self { Some(ref x) => Some(f(x)), None => None }
     }
 
     /// As `map`, but consumes the option and gives `f` ownership to avoid
     /// copying.
     #[inline(always)]
-    fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
+    pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
         match self { None => None, Some(v) => Some(f(v)) }
     }
 
     /// Applies a function to the contained value or returns a default
     #[inline(always)]
-    fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
+    pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
         match *self { None => def, Some(ref t) => f(t) }
     }
 
     /// As `map_default`, but consumes the option and gives `f`
     /// ownership to avoid copying.
     #[inline(always)]
-    fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
+    pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
         match self { None => def, Some(v) => f(v) }
     }
 
     /// Apply a function to the contained value or do nothing
-    fn mutate(&mut self, f: &fn(T) -> T) {
+    pub fn mutate(&mut self, f: &fn(T) -> T) {
         if self.is_some() {
             *self = Some(f(self.swap_unwrap()));
         }
     }
 
     /// Apply a function to the contained value or set it to a default
-    fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
+    pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
         if self.is_some() {
             *self = Some(f(self.swap_unwrap()));
         } else {
@@ -239,7 +216,7 @@ pub impl<T> Option<T> {
     case explicitly.
      */
     #[inline(always)]
-    fn get_ref<'a>(&'a self) -> &'a T {
+    pub fn get_ref<'a>(&'a self) -> &'a T {
         match *self {
           Some(ref x) => x,
           None => fail!("option::get_ref none")
@@ -261,7 +238,7 @@ pub impl<T> Option<T> {
     case explicitly.
      */
     #[inline(always)]
-    fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
+    pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
         match *self {
           Some(ref mut x) => x,
           None => fail!("option::get_mut_ref none")
@@ -269,7 +246,7 @@ pub impl<T> Option<T> {
     }
 
     #[inline(always)]
-    fn unwrap(self) -> T {
+    pub fn unwrap(self) -> T {
         /*!
         Moves a value out of an option type and returns it.
 
@@ -301,7 +278,7 @@ pub impl<T> Option<T> {
      * Fails if the value equals `None`.
      */
     #[inline(always)]
-    fn swap_unwrap(&mut self) -> T {
+    pub fn swap_unwrap(&mut self) -> T {
         if self.is_none() { fail!("option::swap_unwrap none") }
         util::replace(self, None).unwrap()
     }
@@ -315,7 +292,7 @@ pub impl<T> Option<T> {
      * Fails if the value equals `none`
      */
     #[inline(always)]
-    fn expect(self, reason: &str) -> T {
+    pub fn expect(self, reason: &str) -> T {
         match self {
           Some(val) => val,
           None => fail!(reason.to_owned()),
@@ -323,7 +300,7 @@ pub impl<T> Option<T> {
     }
 }
 
-pub impl<T:Copy> Option<T> {
+impl<T:Copy> Option<T> {
     /**
     Gets the value out of an option
 
@@ -339,22 +316,22 @@ pub impl<T:Copy> Option<T> {
     case explicitly.
     */
     #[inline(always)]
-    fn get(self) -> T {
+    pub fn get(self) -> T {
         match self {
-          Some(copy x) => return x,
+          Some(x) => return x,
           None => fail!("option::get none")
         }
     }
 
     /// Returns the contained value or a default
     #[inline(always)]
-    fn get_or_default(self, def: T) -> T {
-        match self { Some(copy x) => x, None => def }
+    pub fn get_or_default(self, def: T) -> T {
+        match self { Some(x) => x, None => def }
     }
 
     /// Applies a function zero or more times until the result is none.
     #[inline(always)]
-    fn while_some(self, blk: &fn(v: T) -> Option<T>) {
+    pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
         let mut opt = self;
         while opt.is_some() {
             opt = blk(opt.unwrap());
@@ -362,11 +339,36 @@ pub impl<T:Copy> Option<T> {
     }
 }
 
-pub impl<T:Copy + Zero> Option<T> {
+impl<T:Copy + Zero> Option<T> {
     /// Returns the contained value or zero (for this type)
     #[inline(always)]
-    fn get_or_zero(self) -> T {
-        match self { Some(copy x) => x, None => Zero::zero() }
+    pub fn get_or_zero(self) -> T {
+        match self {
+            Some(x) => x,
+            None => Zero::zero()
+        }
+    }
+}
+
+/// Immutable iterator over an `Option<A>`
+pub struct OptionIterator<'self, A> {
+    priv opt: Option<&'self A>
+}
+
+impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
+    fn next(&mut self) -> Option<&'self A> {
+        util::replace(&mut self.opt, None)
+    }
+}
+
+/// Mutable iterator over an `Option<A>`
+pub struct OptionMutIterator<'self, A> {
+    priv opt: Option<&'self mut A>
+}
+
+impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
+    fn next(&mut self) -> Option<&'self mut A> {
+        util::replace(&mut self.opt, None)
     }
 }
 
@@ -423,7 +425,7 @@ fn test_option_dance() {
     let x = Some(());
     let mut y = Some(5);
     let mut y2 = 0;
-    for x.each |_x| {
+    for x.iter().advance |_x| {
         y2 = y.swap_unwrap();
     }
     assert_eq!(y2, 5);
@@ -431,7 +433,7 @@ fn test_option_dance() {
 }
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_option_too_much_dance() {
-    let mut y = Some(util::NonCopyable());
+    let mut y = Some(util::NonCopyable::new());
     let _y2 = y.swap_unwrap();
     let _y3 = y.swap_unwrap();
 }
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 15c68efc7cc..044b305a0dd 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -26,13 +26,18 @@
  * to write OS-ignorant code by default.
  */
 
+#[allow(missing_doc)];
+
 use cast;
 use io;
+use iterator::IteratorUtil;
 use libc;
 use libc::{c_char, c_void, c_int, size_t};
 use libc::{mode_t, FILE};
+use local_data;
 use option;
 use option::{Some, None};
+use os;
 use prelude::*;
 use ptr;
 use str;
@@ -43,6 +48,7 @@ use vec;
 pub use libc::fclose;
 pub use os::consts::*;
 
+/// Delegates to the libc close() function, returning the same return value.
 pub fn close(fd: c_int) -> c_int {
     unsafe {
         libc::close(fd)
@@ -140,7 +146,7 @@ pub mod win32 {
     pub fn as_utf16_p<T>(s: &str, f: &fn(*u16) -> T) -> T {
         let mut t = str::to_utf16(s);
         // Null terminate before passing on.
-        t += ~[0u16];
+        t += [0u16];
         vec::as_imm_buf(t, |buf, _len| f(buf))
     }
 }
@@ -169,6 +175,8 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
     }
 }
 
+/// Returns a vector of (variable, value) pairs for all the environment
+/// variables of the current process.
 pub fn env() -> ~[(~str,~str)] {
     unsafe {
         #[cfg(windows)]
@@ -217,12 +225,11 @@ pub fn env() -> ~[(~str,~str)] {
         fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
             let mut pairs = ~[];
             for input.each |p| {
-                let mut vs = ~[];
-                for str::each_splitn_char(*p, '=', 1) |s| { vs.push(s.to_owned()) }
+                let vs: ~[&str] = p.splitn_iter('=', 1).collect();
                 debug!("splitting: len: %u",
                     vs.len());
                 assert_eq!(vs.len(), 2);
-                pairs.push((copy vs[0], copy vs[1]));
+                pairs.push((vs[0].to_owned(), vs[1].to_owned()));
             }
             pairs
         }
@@ -234,6 +241,8 @@ pub fn env() -> ~[(~str,~str)] {
 }
 
 #[cfg(unix)]
+/// Fetches the environment variable `n` from the current process, returning
+/// None if the variable isn't set.
 pub fn getenv(n: &str) -> Option<~str> {
     unsafe {
         do with_env_lock {
@@ -249,6 +258,8 @@ pub fn getenv(n: &str) -> Option<~str> {
 }
 
 #[cfg(windows)]
+/// Fetches the environment variable `n` from the current process, returning
+/// None if the variable isn't set.
 pub fn getenv(n: &str) -> Option<~str> {
     unsafe {
         do with_env_lock {
@@ -264,6 +275,8 @@ pub fn getenv(n: &str) -> Option<~str> {
 
 
 #[cfg(unix)]
+/// Sets the environment variable `n` to the value `v` for the currently running
+/// process
 pub fn setenv(n: &str, v: &str) {
     unsafe {
         do with_env_lock {
@@ -278,6 +291,8 @@ pub fn setenv(n: &str, v: &str) {
 
 
 #[cfg(windows)]
+/// Sets the environment variable `n` to the value `v` for the currently running
+/// process
 pub fn setenv(n: &str, v: &str) {
     unsafe {
         do with_env_lock {
@@ -420,13 +435,13 @@ fn dup2(src: c_int, dst: c_int) -> c_int {
     }
 }
 
-
+/// Returns the proper dll filename for the given basename of a file.
 pub fn dll_filename(base: &str) -> ~str {
-    return str::to_owned(DLL_PREFIX) + str::to_owned(base) +
-           str::to_owned(DLL_SUFFIX)
+    fmt!("%s%s%s", DLL_PREFIX, base, DLL_SUFFIX)
 }
 
-
+/// Optionally returns the filesystem path to the current executable which is
+/// running. If any failure occurs, None is returned.
 pub fn self_exe_path() -> Option<Path> {
 
     #[cfg(target_os = "freebsd")]
@@ -510,7 +525,7 @@ pub fn self_exe_path() -> Option<Path> {
  */
 pub fn homedir() -> Option<Path> {
     return match getenv("HOME") {
-        Some(ref p) => if !str::is_empty(*p) {
+        Some(ref p) => if !p.is_empty() {
           Some(Path(*p))
         } else {
           secondary()
@@ -526,7 +541,7 @@ pub fn homedir() -> Option<Path> {
     #[cfg(windows)]
     fn secondary() -> Option<Path> {
         do getenv(~"USERPROFILE").chain |p| {
-            if !str::is_empty(p) {
+            if !p.is_empty() {
                 Some(Path(p))
             } else {
                 None
@@ -551,7 +566,7 @@ pub fn tmpdir() -> Path {
     fn getenv_nonempty(v: &str) -> Option<Path> {
         match getenv(v) {
             Some(x) =>
-                if str::is_empty(x) {
+                if x.is_empty() {
                     None
                 } else {
                     Some(Path(x))
@@ -826,6 +841,8 @@ pub fn remove_dir(p: &Path) -> bool {
     }
 }
 
+/// Changes the current working directory to the specified path, returning
+/// whether the change was completed successfully or not.
 pub fn change_dir(p: &Path) -> bool {
     return chdir(p);
 
@@ -861,20 +878,18 @@ pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
 
     fn key(_: Exclusive<()>) { }
 
-    let result = unsafe {
-        global_data_clone_create(key, || {
-            ~exclusive(())
-        })
-    };
+    unsafe {
+        let result = global_data_clone_create(key, || { ~exclusive(()) });
 
-    do result.with_imm() |_| {
-        let old_dir = os::getcwd();
-        if change_dir(p) {
-            action();
-            change_dir(&old_dir)
-        }
-        else {
-            false
+        do result.with_imm() |_| {
+            let old_dir = os::getcwd();
+            if change_dir(p) {
+                action();
+                change_dir(&old_dir)
+            }
+            else {
+                false
+            }
         }
     }
 }
@@ -981,6 +996,7 @@ pub fn remove_file(p: &Path) -> bool {
 }
 
 #[cfg(unix)]
+/// Returns the platform-specific value of errno
 pub fn errno() -> int {
     #[cfg(target_os = "macos")]
     #[cfg(target_os = "freebsd")]
@@ -1012,6 +1028,7 @@ pub fn errno() -> int {
 }
 
 #[cfg(windows)]
+/// Returns the platform-specific value of errno
 pub fn errno() -> uint {
     use libc::types::os::arch::extra::DWORD;
 
@@ -1162,7 +1179,7 @@ pub fn real_args() -> ~[~str] {
 #[cfg(windows)]
 pub fn real_args() -> ~[~str] {
     let mut nArgs: c_int = 0;
-    let lpArgCount = ptr::to_mut_unsafe_ptr(&mut nArgs);
+    let lpArgCount: *mut c_int = &mut nArgs;
     let lpCmdLine = unsafe { GetCommandLineW() };
     let szArgList = unsafe { CommandLineToArgvW(lpCmdLine, lpArgCount) };
 
@@ -1211,6 +1228,11 @@ struct OverriddenArgs {
 
 fn overridden_arg_key(_v: @OverriddenArgs) {}
 
+/// Returns the arguments which this program was started with (normally passed
+/// via the command line).
+///
+/// The return value of the function can be changed by invoking the
+/// `os::set_args` function.
 pub fn args() -> ~[~str] {
     unsafe {
         match local_data::local_data_get(overridden_arg_key) {
@@ -1220,6 +1242,9 @@ pub fn args() -> ~[~str] {
     }
 }
 
+/// For the current task, overrides the task-local cache of the arguments this
+/// program had when it started. These new arguments are only available to the
+/// current task via the `os::args` method.
 pub fn set_args(new_args: ~[~str]) {
     unsafe {
         let overridden_args = @OverriddenArgs { val: copy new_args };
@@ -1423,8 +1448,9 @@ mod tests {
     use rand::RngUtil;
     use rand;
     use run;
-    use str;
+    use str::StrSlice;
     use vec;
+    use vec::CopyableVector;
     use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
 
 
@@ -1548,7 +1574,7 @@ mod tests {
         setenv("HOME", "");
         assert!(os::homedir().is_none());
 
-        for oldhome.each |s| { setenv("HOME", *s) }
+        for oldhome.iter().advance |s| { setenv("HOME", *s) }
     }
 
     #[test]
@@ -1581,7 +1607,7 @@ mod tests {
 
     #[test]
     fn tmpdir() {
-        assert!(!str::is_empty(os::tmpdir().to_str()));
+        assert!(!os::tmpdir().to_str().is_empty());
     }
 
     // Issue #712
@@ -1646,7 +1672,7 @@ mod tests {
         unsafe {
           let tempdir = getcwd(); // would like to use $TMPDIR,
                                   // doesn't seem to work on Linux
-          assert!((str::len(tempdir.to_str()) > 0u));
+          assert!((tempdir.to_str().len() > 0u));
           let in = tempdir.push("in.txt");
           let out = tempdir.push("out.txt");
 
@@ -1658,10 +1684,10 @@ mod tests {
           };
           assert!((ostream as uint != 0u));
           let s = ~"hello";
-          let mut buf = str::to_bytes(s) + [0 as u8];
+          let mut buf = s.as_bytes_with_null().to_owned();
           do vec::as_mut_buf(buf) |b, _len| {
               assert!((libc::fwrite(b as *c_void, 1u as size_t,
-                                   (str::len(s) + 1u) as size_t, ostream)
+                                   (s.len() + 1u) as size_t, ostream)
                       == buf.len() as size_t))
           }
           assert_eq!(libc::fclose(ostream), (0u as c_int));
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index ed9ef864f80..400657d0c25 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -14,12 +14,15 @@ Cross-platform file path handling
 
 */
 
+#[allow(missing_doc)];
+
 use container::Container;
 use cmp::Eq;
+use iterator::IteratorUtil;
 use libc;
 use option::{None, Option, Some};
 use str;
-use str::StrSlice;
+use str::{Str, StrSlice, StrVector};
 use to_str::ToStr;
 use ascii::{AsciiCast, AsciiStr};
 use old_iter::BaseIter;
@@ -99,7 +102,7 @@ pub trait GenericPath {
     fn push_rel(&self, (&Self)) -> Self;
     /// Returns a new Path consisting of the path given by the given vector
     /// of strings, relative to `self`.
-    fn push_many(&self, (&[~str])) -> Self;
+    fn push_many<S: Str>(&self, (&[S])) -> Self;
     /// Identical to `dir_path` except in the case where `self` has only one
     /// component. In this case, `pop` returns the empty path.
     fn pop(&self) -> Self;
@@ -306,8 +309,8 @@ mod stat {
 }
 
 
-pub impl Path {
-    fn stat(&self) -> Option<libc::stat> {
+impl Path {
+    pub fn stat(&self) -> Option<libc::stat> {
         unsafe {
              do str::as_c_str(self.to_str()) |buf| {
                 let mut st = stat::arch::default_stat();
@@ -320,7 +323,7 @@ pub impl Path {
     }
 
     #[cfg(unix)]
-    fn lstat(&self) -> Option<libc::stat> {
+    pub fn lstat(&self) -> Option<libc::stat> {
         unsafe {
             do str::as_c_str(self.to_str()) |buf| {
                 let mut st = stat::arch::default_stat();
@@ -332,21 +335,21 @@ pub impl Path {
         }
     }
 
-    fn exists(&self) -> bool {
+    pub fn exists(&self) -> bool {
         match self.stat() {
             None => false,
             Some(_) => true,
         }
     }
 
-    fn get_size(&self) -> Option<i64> {
+    pub fn get_size(&self) -> Option<i64> {
         match self.stat() {
             None => None,
             Some(ref st) => Some(st.st_size as i64),
         }
     }
 
-    fn get_mode(&self) -> Option<uint> {
+    pub fn get_mode(&self) -> Option<uint> {
         match self.stat() {
             None => None,
             Some(ref st) => Some(st.st_mode as uint),
@@ -357,8 +360,8 @@ pub impl Path {
 #[cfg(target_os = "freebsd")]
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "macos")]
-pub impl Path {
-    fn get_atime(&self) -> Option<(i64, int)> {
+impl Path {
+    pub fn get_atime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -368,7 +371,7 @@ pub impl Path {
         }
     }
 
-    fn get_mtime(&self) -> Option<(i64, int)> {
+    pub fn get_mtime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -378,7 +381,7 @@ pub impl Path {
         }
     }
 
-    fn get_ctime(&self) -> Option<(i64, int)> {
+    pub fn get_ctime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -391,8 +394,8 @@ pub impl Path {
 
 #[cfg(target_os = "freebsd")]
 #[cfg(target_os = "macos")]
-pub impl Path {
-    fn get_birthtime(&self) -> Option<(i64, int)> {
+impl Path {
+    pub fn get_birthtime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -404,8 +407,8 @@ pub impl Path {
 }
 
 #[cfg(target_os = "win32")]
-pub impl Path {
-    fn get_atime(&self) -> Option<(i64, int)> {
+impl Path {
+    pub fn get_atime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -414,7 +417,7 @@ pub impl Path {
         }
     }
 
-    fn get_mtime(&self) -> Option<(i64, int)> {
+    pub fn get_mtime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -423,7 +426,7 @@ pub impl Path {
         }
     }
 
-    fn get_ctime(&self) -> Option<(i64, int)> {
+    pub fn get_ctime(&self) -> Option<(i64, int)> {
         match self.stat() {
             None => None,
             Some(ref st) => {
@@ -439,7 +442,7 @@ impl ToStr for PosixPath {
         if self.is_absolute {
             s += "/";
         }
-        s + str::connect(self.components, "/")
+        s + self.components.connect("/")
     }
 }
 
@@ -447,10 +450,9 @@ impl ToStr for PosixPath {
 // PosixPath and WindowsPath, most of their methods are common.
 impl GenericPath for PosixPath {
     fn from_str(s: &str) -> PosixPath {
-        let mut components = ~[];
-        for str::each_split_nonempty(s, |c| c == '/') |s| {
-            components.push(s.to_owned())
-        }
+        let components = s.split_iter('/')
+            .filter_map(|s| if s.is_empty() {None} else {Some(s.to_owned())})
+            .collect();
         let is_absolute = (s.len() != 0 && s[0] == '/' as u8);
         PosixPath {
             is_absolute: is_absolute,
@@ -477,8 +479,8 @@ impl GenericPath for PosixPath {
         match self.filename() {
             None => None,
             Some(ref f) => {
-                match str::rfind_char(*f, '.') {
-                    Some(p) => Some(f.slice(0, p).to_owned()),
+                match f.rfind('.') {
+                    Some(p) => Some(f.slice_to(p).to_owned()),
                     None => Some(copy *f),
                 }
             }
@@ -489,8 +491,8 @@ impl GenericPath for PosixPath {
         match self.filename() {
             None => None,
             Some(ref f) => {
-                match str::rfind_char(*f, '.') {
-                    Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()),
+                match f.rfind('.') {
+                    Some(p) if p < f.len() => Some(f.slice_from(p).to_owned()),
                     _ => None,
                 }
             }
@@ -506,7 +508,7 @@ impl GenericPath for PosixPath {
     }
 
     fn with_filename(&self, f: &str) -> PosixPath {
-        assert!(! str::any(f, |c| windows::is_sep(c as u8)));
+        assert!(! f.iter().all(windows::is_sep));
         self.dir_path().push(f)
     }
 
@@ -564,14 +566,14 @@ impl GenericPath for PosixPath {
         false
     }
 
-    fn push_many(&self, cs: &[~str]) -> PosixPath {
+    fn push_many<S: Str>(&self, cs: &[S]) -> PosixPath {
         let mut v = copy self.components;
         for cs.each |e| {
-            let mut ss = ~[];
-            for str::each_split_nonempty(*e, |c| windows::is_sep(c as u8)) |s| {
-                ss.push(s.to_owned())
+            for e.as_slice().split_iter(windows::is_sep).advance |s| {
+                if !s.is_empty() {
+                    v.push(s.to_owned())
+                }
             }
-            v.push_all_move(ss);
         }
         PosixPath {
             is_absolute: self.is_absolute,
@@ -581,11 +583,11 @@ impl GenericPath for PosixPath {
 
     fn push(&self, s: &str) -> PosixPath {
         let mut v = copy self.components;
-        let mut ss = ~[];
-        for str::each_split_nonempty(s, |c| windows::is_sep(c as u8)) |s| {
-            ss.push(s.to_owned())
+        for s.split_iter(windows::is_sep).advance |s| {
+            if !s.is_empty() {
+                v.push(s.to_owned())
+            }
         }
-        v.push_all_move(ss);
         PosixPath { components: v, ..copy *self }
     }
 
@@ -627,7 +629,7 @@ impl ToStr for WindowsPath {
         if self.is_absolute {
             s += "\\";
         }
-        s + str::connect(self.components, "\\")
+        s + self.components.connect("\\")
     }
 }
 
@@ -659,11 +661,11 @@ impl GenericPath for WindowsPath {
             }
         }
 
-        let mut components = ~[];
-        for str::each_split_nonempty(rest, |c| windows::is_sep(c as u8)) |s| {
-            components.push(s.to_owned())
-        }
-        let is_absolute = (rest.len() != 0 && windows::is_sep(rest[0]));
+        let components = rest.split_iter(windows::is_sep)
+            .filter_map(|s| if s.is_empty() {None} else {Some(s.to_owned())})
+            .collect();
+
+        let is_absolute = (rest.len() != 0 && windows::is_sep(rest[0] as char));
         WindowsPath {
             host: host,
             device: device,
@@ -691,8 +693,8 @@ impl GenericPath for WindowsPath {
         match self.filename() {
             None => None,
             Some(ref f) => {
-                match str::rfind_char(*f, '.') {
-                    Some(p) => Some(f.slice(0, p).to_owned()),
+                match f.rfind('.') {
+                    Some(p) => Some(f.slice_to(p).to_owned()),
                     None => Some(copy *f),
                 }
             }
@@ -703,8 +705,8 @@ impl GenericPath for WindowsPath {
         match self.filename() {
           None => None,
           Some(ref f) => {
-            match str::rfind_char(*f, '.') {
-                Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()),
+            match f.rfind('.') {
+                Some(p) if p < f.len() => Some(f.slice_from(p).to_owned()),
                 _ => None,
             }
           }
@@ -720,7 +722,7 @@ impl GenericPath for WindowsPath {
     }
 
     fn with_filename(&self, f: &str) -> WindowsPath {
-        assert!(! str::any(f, |c| windows::is_sep(c as u8)));
+        assert!(! f.iter().all(windows::is_sep));
         self.dir_path().push(f)
     }
 
@@ -772,9 +774,9 @@ impl GenericPath for WindowsPath {
 
         /* if rhs has a host set, then the whole thing wins */
         match other.host {
-            Some(copy host) => {
+            Some(ref host) => {
                 return WindowsPath {
-                    host: Some(host),
+                    host: Some(copy *host),
                     device: copy other.device,
                     is_absolute: true,
                     components: copy other.components,
@@ -785,10 +787,10 @@ impl GenericPath for WindowsPath {
 
         /* if rhs has a device set, then a part wins */
         match other.device {
-            Some(copy device) => {
+            Some(ref device) => {
                 return WindowsPath {
                     host: None,
-                    device: Some(device),
+                    device: Some(copy *device),
                     is_absolute: true,
                     components: copy other.components,
                 };
@@ -821,14 +823,14 @@ impl GenericPath for WindowsPath {
         }
     }
 
-    fn push_many(&self, cs: &[~str]) -> WindowsPath {
+    fn push_many<S: Str>(&self, cs: &[S]) -> WindowsPath {
         let mut v = copy self.components;
         for cs.each |e| {
-            let mut ss = ~[];
-            for str::each_split_nonempty(*e, |c| windows::is_sep(c as u8)) |s| {
-                ss.push(s.to_owned())
+            for e.as_slice().split_iter(windows::is_sep).advance |s| {
+                if !s.is_empty() {
+                    v.push(s.to_owned())
+                }
             }
-            v.push_all_move(ss);
         }
         // tedious, but as-is, we can't use ..self
         WindowsPath {
@@ -841,11 +843,11 @@ impl GenericPath for WindowsPath {
 
     fn push(&self, s: &str) -> WindowsPath {
         let mut v = copy self.components;
-        let mut ss = ~[];
-        for str::each_split_nonempty(s, |c| windows::is_sep(c as u8)) |s| {
-            ss.push(s.to_owned())
+        for s.split_iter(windows::is_sep).advance |s| {
+            if !s.is_empty() {
+                v.push(s.to_owned())
+            }
         }
-        v.push_all_move(ss);
         WindowsPath { components: v, ..copy *self }
     }
 
@@ -903,8 +905,8 @@ pub mod windows {
     use option::{None, Option, Some};
 
     #[inline(always)]
-    pub fn is_sep(u: u8) -> bool {
-        u == '/' as u8 || u == '\\' as u8
+    pub fn is_sep(u: char) -> bool {
+        u == '/' || u == '\\'
     }
 
     pub fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
@@ -913,7 +915,7 @@ pub mod windows {
             s[0] == s[1]) {
             let mut i = 2;
             while i < s.len() {
-                if is_sep(s[i]) {
+                if is_sep(s[i] as char) {
                     let pre = s.slice(2, i).to_owned();
                     let rest = s.slice(i, s.len()).to_owned();
                     return Some((pre, rest));
diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs
index 4203f87f139..012ad0ed80d 100644
--- a/src/libstd/pipes.rs
+++ b/src/libstd/pipes.rs
@@ -82,9 +82,12 @@ bounded and unbounded protocols allows for less code duplication.
 
 */
 
+#[allow(missing_doc)];
+
 use container::Container;
 use cast::{forget, transmute, transmute_copy};
 use either::{Either, Left, Right};
+use iterator::IteratorUtil;
 use kinds::Owned;
 use libc;
 use ops::Drop;
@@ -92,10 +95,9 @@ use option::{None, Option, Some};
 use unstable::finally::Finally;
 use unstable::intrinsics;
 use ptr;
-use ptr::Ptr;
+use ptr::RawPtr;
 use task;
-use vec;
-use vec::OwnedVector;
+use vec::{OwnedVector, MutableVector};
 use util::replace;
 
 static SPIN_COUNT: uint = 0;
@@ -150,16 +152,16 @@ pub fn PacketHeader() -> PacketHeader {
     }
 }
 
-pub impl PacketHeader {
+impl PacketHeader {
     // Returns the old state.
-    unsafe fn mark_blocked(&mut self, this: *rust_task) -> State {
+    pub unsafe fn mark_blocked(&mut self, this: *rust_task) -> State {
         rustrt::rust_task_ref(this);
         let old_task = swap_task(&mut self.blocked_task, this);
         assert!(old_task.is_null());
         swap_state_acq(&mut self.state, Blocked)
     }
 
-    unsafe fn unblock(&mut self) {
+    pub unsafe fn unblock(&mut self) {
         let old_task = swap_task(&mut self.blocked_task, ptr::null());
         if !old_task.is_null() {
             rustrt::rust_task_deref(old_task)
@@ -174,12 +176,12 @@ pub impl PacketHeader {
     // unsafe because this can do weird things to the space/time
     // continuum. It ends making multiple unique pointers to the same
     // thing. You'll probably want to forget them when you're done.
-    unsafe fn buf_header(&mut self) -> ~BufferHeader {
+    pub unsafe fn buf_header(&mut self) -> ~BufferHeader {
         assert!(self.buffer.is_not_null());
         transmute_copy(&self.buffer)
     }
 
-    fn set_buffer<T:Owned>(&mut self, b: ~Buffer<T>) {
+    pub fn set_buffer<T:Owned>(&mut self, b: ~Buffer<T>) {
         unsafe {
             self.buffer = transmute_copy(&b);
         }
@@ -235,11 +237,11 @@ pub fn packet<T>() -> *mut Packet<T> {
 pub fn entangle_buffer<T:Owned,Tstart:Owned>(
     mut buffer: ~Buffer<T>,
     init: &fn(*libc::c_void, x: &mut T) -> *mut Packet<Tstart>)
-    -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) {
+    -> (RecvPacketBuffered<Tstart, T>, SendPacketBuffered<Tstart, T>) {
     unsafe {
         let p = init(transmute_copy(&buffer), &mut buffer.data);
         forget(buffer);
-        (SendPacketBuffered(p), RecvPacketBuffered(p))
+        (RecvPacketBuffered(p), SendPacketBuffered(p))
     }
 }
 
@@ -313,6 +315,7 @@ struct BufferResource<T> {
 impl<T> Drop for BufferResource<T> {
     fn finalize(&self) {
         unsafe {
+            // FIXME(#4330) Need self by value to get mutability.
             let this: &mut BufferResource<T> = transmute(self);
 
             let mut b = move_it!(this.buffer);
@@ -598,7 +601,7 @@ pub fn wait_many<T: Selectable>(pkts: &mut [T]) -> uint {
 
     let mut data_avail = false;
     let mut ready_packet = pkts.len();
-    for vec::eachi_mut(pkts) |i, p| {
+    for pkts.mut_iter().enumerate().advance |(i, p)| {
         unsafe {
             let p = &mut *p.header();
             let old = p.mark_blocked(this);
@@ -620,7 +623,7 @@ pub fn wait_many<T: Selectable>(pkts: &mut [T]) -> uint {
         let event = wait_event(this) as *PacketHeader;
 
         let mut pos = None;
-        for vec::eachi_mut(pkts) |i, p| {
+        for pkts.mut_iter().enumerate().advance |(i, p)| {
             if p.header() == event {
                 pos = Some(i);
                 break;
@@ -638,7 +641,7 @@ pub fn wait_many<T: Selectable>(pkts: &mut [T]) -> uint {
 
     debug!("%?", &mut pkts[ready_packet]);
 
-    for vec::each_mut(pkts) |p| {
+    for pkts.mut_iter().advance |p| {
         unsafe {
             (*p.header()).unblock()
         }
@@ -692,12 +695,12 @@ pub fn SendPacketBuffered<T,Tbuffer>(p: *mut Packet<T>)
     }
 }
 
-pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> {
-    fn unwrap(&mut self) -> *mut Packet<T> {
+impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> {
+    pub fn unwrap(&mut self) -> *mut Packet<T> {
         replace(&mut self.p, None).unwrap()
     }
 
-    fn header(&mut self) -> *mut PacketHeader {
+    pub fn header(&mut self) -> *mut PacketHeader {
         match self.p {
             Some(packet) => unsafe {
                 let packet = &mut *packet;
@@ -708,7 +711,7 @@ pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> {
         }
     }
 
-    fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> {
+    pub fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> {
         //error!("send reuse_buffer");
         replace(&mut self.buffer, None).unwrap()
     }
@@ -740,12 +743,12 @@ impl<T:Owned,Tbuffer:Owned> Drop for RecvPacketBuffered<T,Tbuffer> {
     }
 }
 
-pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> {
-    fn unwrap(&mut self) -> *mut Packet<T> {
+impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> {
+    pub fn unwrap(&mut self) -> *mut Packet<T> {
         replace(&mut self.p, None).unwrap()
     }
 
-    fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> {
+    pub fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> {
         replace(&mut self.buffer, None).unwrap()
     }
 }
@@ -773,9 +776,9 @@ pub fn RecvPacketBuffered<T,Tbuffer>(p: *mut Packet<T>)
     }
 }
 
-pub fn entangle<T>() -> (SendPacket<T>, RecvPacket<T>) {
+pub fn entangle<T>() -> (RecvPacket<T>, SendPacket<T>) {
     let p = packet();
-    (SendPacket(p), RecvPacket(p))
+    (RecvPacket(p), SendPacket(p))
 }
 
 /** Receives a message from one of two endpoints.
@@ -851,7 +854,7 @@ pub fn select<T:Owned,Tb:Owned>(mut endpoints: ~[RecvPacketBuffered<T, Tb>])
                                     Option<T>,
                                     ~[RecvPacketBuffered<T, Tb>]) {
     let mut endpoint_headers = ~[];
-    for vec::each_mut(endpoints) |endpoint| {
+    for endpoints.mut_iter().advance |endpoint| {
         endpoint_headers.push(endpoint.header());
     }
 
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 58d0c40efa0..61b8d36266e 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -8,12 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! The Rust prelude. Imported into every module by default.
+/*!
 
-/* Reexported core operators */
+Many programming languages have a 'prelude': a particular subset of the
+libraries that come with the language. Every program imports the prelude by
+default.
 
+For example, it would be annoying to add `use std::io::println;` to every single
+program, and the vast majority of Rust programs will wish to print to standard
+output. Therefore, it makes sense to import it into every program.
+
+Rust's prelude has three main parts:
+
+1. io::print and io::println.
+2. Core operators, such as `Add`, `Mul`, and `Not`.
+3. Various types and traits, such as `Clone`, `Eq`, and `comm::Chan`.
+
+*/
+
+
+// Reexported core operators
 pub use either::{Either, Left, Right};
-pub use kinds::{Const, Copy, Owned};
+pub use kinds::{Const, Copy, Owned, Sized};
 pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Drop};
@@ -21,21 +37,19 @@ pub use ops::{Shl, Shr, Index};
 pub use option::{Option, Some, None};
 pub use result::{Result, Ok, Err};
 
-/* Reexported functions */
-
+// Reexported functions
 pub use io::{print, println};
 
-/* Reexported types and traits */
-
+// Reexported types and traits
 pub use clone::{Clone, DeepClone};
 pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
 pub use char::Char;
 pub use container::{Container, Mutable, Map, Set};
 pub use hash::Hash;
-pub use old_iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter};
-pub use old_iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter};
-pub use old_iter::{ExtendedMutableIter};
-pub use iter::Times;
+pub use old_iter::{BaseIter, ReverseIter, ExtendedIter, EqIter};
+pub use old_iter::{CopyableIter, CopyableOrderedIter};
+pub use iter::{Times, FromIter};
+pub use iterator::{Iterator, IteratorUtil};
 pub use num::{Num, NumCast};
 pub use num::{Orderable, Signed, Unsigned, Round};
 pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
@@ -46,9 +60,9 @@ pub use path::GenericPath;
 pub use path::Path;
 pub use path::PosixPath;
 pub use path::WindowsPath;
-pub use ptr::Ptr;
+pub use ptr::RawPtr;
 pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr};
-pub use str::{StrSlice, OwnedStr};
+pub use str::{Str, StrVector, StrSlice, OwnedStr, StrUtil, NullTerminatedStr};
 pub use from_str::{FromStr};
 pub use to_bytes::IterBytes;
 pub use to_str::{ToStr, ToStrConsume};
@@ -59,53 +73,11 @@ pub use tuple::{CloneableTuple10, CloneableTuple11, CloneableTuple12};
 pub use tuple::{ImmutableTuple2, ImmutableTuple3, ImmutableTuple4, ImmutableTuple5};
 pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTuple9};
 pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12};
-pub use vec::{CopyableVector, ImmutableVector};
+pub use vec::{VectorVector, CopyableVector, ImmutableVector};
 pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
 pub use vec::{OwnedVector, OwnedCopyableVector, MutableVector};
 pub use io::{Reader, ReaderUtil, Writer, WriterUtil};
 
-/* Reexported runtime types */
+// Reexported runtime types
 pub use comm::{stream, Port, Chan, GenericChan, GenericSmartChan, GenericPort, Peekable};
 pub use task::spawn;
-
-/* Reexported modules */
-
-pub use at_vec;
-pub use bool;
-pub use cast;
-pub use char;
-pub use cmp;
-pub use either;
-pub use f32;
-pub use f64;
-pub use float;
-pub use i16;
-pub use i32;
-pub use i64;
-pub use i8;
-pub use int;
-pub use io;
-pub use iter;
-pub use old_iter;
-pub use libc;
-pub use local_data;
-pub use num;
-pub use ops;
-pub use option;
-pub use os;
-pub use path;
-pub use comm;
-pub use unstable;
-pub use ptr;
-pub use rand;
-pub use result;
-pub use str;
-pub use sys;
-pub use task;
-pub use to_str;
-pub use u16;
-pub use u32;
-pub use u64;
-pub use u8;
-pub use uint;
-pub use vec;
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 38d7095a366..cd5a3182f6b 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -11,30 +11,13 @@
 //! Unsafe pointer utility functions
 
 use cast;
-#[cfg(stage0)] use libc;
-#[cfg(stage0)] use libc::{c_void, size_t};
 use option::{Option, Some, None};
 use sys;
+use unstable::intrinsics;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
 use uint;
 
-#[cfg(stage0)]
-pub mod libc_ {
-    use libc::c_void;
-    use libc;
-
-    #[nolink]
-    #[abi = "cdecl"]
-    pub extern {
-        #[rust_stack]
-        unsafe fn memset(dest: *mut c_void,
-                         c: libc::c_int,
-                         len: libc::size_t)
-                      -> *c_void;
-    }
-}
-
 /// Calculate the offset from a pointer
 #[inline(always)]
 pub fn offset<T>(ptr: *T, count: uint) -> *T {
@@ -71,11 +54,11 @@ pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint {
 
 /// Create an unsafe null pointer
 #[inline(always)]
-pub fn null<T>() -> *T { unsafe { cast::transmute(0u) } }
+pub fn null<T>() -> *T { 0 as *T }
 
 /// Create an unsafe mutable null pointer
 #[inline(always)]
-pub fn mut_null<T>() -> *mut T { unsafe { cast::transmute(0u) } }
+pub fn mut_null<T>() -> *mut T { 0 as *mut T }
 
 /// Returns true if the pointer is equal to the null pointer.
 #[inline(always)]
@@ -86,7 +69,7 @@ pub fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
 pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
 
 /**
- * Copies data from one location to another
+ * Copies data from one location to another.
  *
  * Copies `count` elements (not bytes) from `src` to `dst`. The source
  * and destination may overlap.
@@ -100,7 +83,7 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
 }
 
 /**
- * Copies data from one location to another
+ * Copies data from one location to another.
  *
  * Copies `count` elements (not bytes) from `src` to `dst`. The source
  * and destination may overlap.
@@ -112,6 +95,12 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
     memmove32(dst, src as *T, count as u32);
 }
 
+/**
+ * Copies data from one location to another.
+ *
+ * Copies `count` elements (not bytes) from `src` to `dst`. The source
+ * and destination may overlap.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "64", stage0)]
 pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
@@ -120,6 +109,12 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
     memmove64(dst as *mut u8, src as *u8, n as u64);
 }
 
+/**
+ * Copies data from one location to another.
+ *
+ * Copies `count` elements (not bytes) from `src` to `dst`. The source
+ * and destination may overlap.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "64", not(stage0))]
 pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
@@ -127,6 +122,12 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
     memmove64(dst, src as *T, count as u64);
 }
 
+/**
+ * Copies data from one location to another.
+ *
+ * Copies `count` elements (not bytes) from `src` to `dst`. The source
+ * and destination may *not* overlap.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "32", stage0)]
 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
@@ -135,6 +136,12 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
     memmove32(dst as *mut u8, src as *u8, n as u32);
 }
 
+/**
+ * Copies data from one location to another.
+ *
+ * Copies `count` elements (not bytes) from `src` to `dst`. The source
+ * and destination may *not* overlap.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "32", not(stage0))]
 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
@@ -142,6 +149,12 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
     memcpy32(dst, src as *T, count as u32);
 }
 
+/**
+ * Copies data from one location to another.
+ *
+ * Copies `count` elements (not bytes) from `src` to `dst`. The source
+ * and destination may *not* overlap.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "64", stage0)]
 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
@@ -150,6 +163,12 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
     memmove64(dst as *mut u8, src as *u8, n as u64);
 }
 
+/**
+ * Copies data from one location to another.
+ *
+ * Copies `count` elements (not bytes) from `src` to `dst`. The source
+ * and destination may *not* overlap.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "64", not(stage0))]
 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
@@ -157,13 +176,10 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
     memcpy64(dst, src as *T, count as u64);
 }
 
-#[inline(always)]
-#[cfg(stage0)]
-pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) {
-    let n = count * sys::size_of::<T>();
-    libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t);
-}
-
+/**
+ * Invokes memset on the specified pointer, setting `count * size_of::<T>()`
+ * bytes of memory starting at `dst` to `c`.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "32", not(stage0))]
 pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
@@ -171,6 +187,10 @@ pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
     memset32(dst, c, count as u32);
 }
 
+/**
+ * Invokes memset on the specified pointer, setting `count * size_of::<T>()`
+ * bytes of memory starting at `dst` to `c`.
+ */
 #[inline(always)]
 #[cfg(target_word_size = "64", not(stage0))]
 pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
@@ -179,53 +199,51 @@ pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
 }
 
 /**
-  Transform a region pointer - &T - to an unsafe pointer - *T.
-  This is safe, but is implemented with an unsafe block due to
-  transmute.
-*/
-#[inline(always)]
-pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
-    unsafe { cast::transmute(thing) }
+ * Swap the values at two mutable locations of the same type, without
+ * deinitialising or copying either one.
+ */
+#[inline]
+pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
+    // Give ourselves some scratch space to work with
+    let mut tmp: T = intrinsics::uninit();
+    let t: *mut T = &mut tmp;
+
+    // Perform the swap
+    copy_memory(t, x, 1);
+    copy_memory(x, y, 1);
+    copy_memory(y, t, 1);
+
+    // y and t now point to the same thing, but we need to completely forget `tmp`
+    // because it's no longer relevant.
+    cast::forget(tmp);
 }
 
 /**
-  Transform a const region pointer - &const T - to a const unsafe pointer -
-  *const T. This is safe, but is implemented with an unsafe block due to
-  transmute.
-*/
+ * Replace the value at a mutable location with a new one, returning the old
+ * value, without deinitialising or copying either one.
+ */
 #[inline(always)]
-pub fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
-    unsafe { cast::transmute(thing) }
+pub unsafe fn replace_ptr<T>(dest: *mut T, mut src: T) -> T {
+    swap_ptr(dest, &mut src);
+    src
 }
 
-/**
-  Transform a mutable region pointer - &mut T - to a mutable unsafe pointer -
-  *mut T. This is safe, but is implemented with an unsafe block due to
-  transmute.
-*/
+/// Transform a region pointer - &T - to an unsafe pointer - *T.
 #[inline(always)]
-pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
-    unsafe { cast::transmute(thing) }
+pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
+    thing as *T
 }
 
-/**
-  Cast a region pointer - &T - to a uint.
-  This is safe, but is implemented with an unsafe block due to
-  transmute.
-
-  (I couldn't think of a cutesy name for this one.)
-*/
+/// Transform a const region pointer - &const T - to a const unsafe pointer - *const T.
 #[inline(always)]
-pub fn to_uint<T>(thing: &T) -> uint {
-    unsafe {
-        cast::transmute(thing)
-    }
+pub fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
+    thing as *const T
 }
 
-/// Determine if two borrowed pointers point to the same thing.
+/// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
 #[inline(always)]
-pub fn ref_eq<'a,'b,T>(thing: &'a T, other: &'b T) -> bool {
-    to_uint(thing) == to_uint(other)
+pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
+    thing as *mut T
 }
 
 /**
@@ -268,7 +286,8 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
     array_each_with_len(arr, len, cb);
 }
 
-pub trait Ptr<T> {
+#[allow(missing_doc)]
+pub trait RawPtr<T> {
     fn is_null(&const self) -> bool;
     fn is_not_null(&const self) -> bool;
     unsafe fn to_option(&const self) -> Option<&T>;
@@ -276,7 +295,7 @@ pub trait Ptr<T> {
 }
 
 /// Extension methods for immutable pointers
-impl<T> Ptr<T> for *T {
+impl<T> RawPtr<T> for *T {
     /// Returns true if the pointer is equal to the null pointer.
     #[inline(always)]
     fn is_null(&const self) -> bool { is_null(*self) }
@@ -308,7 +327,7 @@ impl<T> Ptr<T> for *T {
 }
 
 /// Extension methods for mutable pointers
-impl<T> Ptr<T> for *mut T {
+impl<T> RawPtr<T> for *mut T {
     /// Returns true if the pointer is equal to the null pointer.
     #[inline(always)]
     fn is_null(&const self) -> bool { is_null(*self) }
@@ -344,14 +363,10 @@ impl<T> Ptr<T> for *mut T {
 impl<T> Eq for *const T {
     #[inline(always)]
     fn eq(&self, other: &*const T) -> bool {
-        unsafe {
-            let a: uint = cast::transmute(*self);
-            let b: uint = cast::transmute(*other);
-            return a == b;
-        }
+        (*self as uint) == (*other as uint)
     }
     #[inline(always)]
-    fn ne(&self, other: &*const T) -> bool { !(*self).eq(other) }
+    fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
 }
 
 // Comparison for pointers
@@ -359,69 +374,19 @@ impl<T> Eq for *const T {
 impl<T> Ord for *const T {
     #[inline(always)]
     fn lt(&self, other: &*const T) -> bool {
-        unsafe {
-            let a: uint = cast::transmute(*self);
-            let b: uint = cast::transmute(*other);
-            return a < b;
-        }
+        (*self as uint) < (*other as uint)
     }
     #[inline(always)]
     fn le(&self, other: &*const T) -> bool {
-        unsafe {
-            let a: uint = cast::transmute(*self);
-            let b: uint = cast::transmute(*other);
-            return a <= b;
-        }
+        (*self as uint) <= (*other as uint)
     }
     #[inline(always)]
     fn ge(&self, other: &*const T) -> bool {
-        unsafe {
-            let a: uint = cast::transmute(*self);
-            let b: uint = cast::transmute(*other);
-            return a >= b;
-        }
+        (*self as uint) >= (*other as uint)
     }
     #[inline(always)]
     fn gt(&self, other: &*const T) -> bool {
-        unsafe {
-            let a: uint = cast::transmute(*self);
-            let b: uint = cast::transmute(*other);
-            return a > b;
-        }
-    }
-}
-
-// Equality for region pointers
-#[cfg(not(test))]
-impl<'self,T:Eq> Eq for &'self T {
-    #[inline(always)]
-    fn eq(&self, other: & &'self T) -> bool {
-        return *(*self) == *(*other);
-    }
-    #[inline(always)]
-    fn ne(&self, other: & &'self T) -> bool {
-        return *(*self) != *(*other);
-    }
-}
-
-// Comparison for region pointers
-#[cfg(not(test))]
-impl<'self,T:Ord> Ord for &'self T {
-    #[inline(always)]
-    fn lt(&self, other: & &'self T) -> bool {
-        *(*self) < *(*other)
-    }
-    #[inline(always)]
-    fn le(&self, other: & &'self T) -> bool {
-        *(*self) <= *(*other)
-    }
-    #[inline(always)]
-    fn ge(&self, other: & &'self T) -> bool {
-        *(*self) >= *(*other)
-    }
-    #[inline(always)]
-    fn gt(&self, other: & &'self T) -> bool {
-        *(*self) > *(*other)
+        (*self as uint) > (*other as uint)
     }
 }
 
@@ -430,6 +395,11 @@ pub mod ptr_tests {
     use super::*;
     use prelude::*;
 
+    use cast;
+    use libc;
+    use str;
+    use vec;
+
     #[test]
     fn test() {
         unsafe {
@@ -522,18 +492,19 @@ pub mod ptr_tests {
 
     #[test]
     fn test_to_option() {
-        let p: *int = null();
-        // FIXME (#6641): Usage of unsafe methods in safe code doesn't cause an error.
-        assert_eq!(p.to_option(), None);
+        unsafe {
+            let p: *int = null();
+            assert_eq!(p.to_option(), None);
 
-        let q: *int = &2;
-        assert_eq!(q.to_option().unwrap(), &2);     // FIXME (#6641)
+            let q: *int = &2;
+            assert_eq!(q.to_option().unwrap(), &2);
 
-        let p: *mut int = mut_null();
-        assert_eq!(p.to_option(), None);            // FIXME (#6641)
+            let p: *mut int = mut_null();
+            assert_eq!(p.to_option(), None);
 
-        let q: *mut int = &mut 2;
-        assert_eq!(q.to_option().unwrap(), &2);     // FIXME (#6641)
+            let q: *mut int = &mut 2;
+            assert_eq!(q.to_option().unwrap(), &2);
+        }
     }
 
     #[test]
@@ -621,6 +592,7 @@ pub mod ptr_tests {
     }
 
     #[test]
+    #[cfg(not(stage0))]
     fn test_set_memory() {
         let mut xs = [0u8, ..20];
         let ptr = vec::raw::to_mut_ptr(xs);
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index 2bcc9c8bba2..7946f7e4f13 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -25,7 +25,7 @@ distributions like normal and exponential.
 use core::rand::RngUtil;
 
 fn main() {
-    let rng = rand::rng();
+    let mut rng = rand::rng();
     if rng.gen() { // bool
         println(fmt!("int: %d, uint: %u", rng.gen(), rng.gen()))
     }
@@ -40,10 +40,14 @@ fn main () {
 ~~~
 */
 
-
+use cast;
+use cmp;
 use int;
+use iterator::IteratorUtil;
+use local_data;
 use prelude::*;
 use str;
+use sys;
 use u32;
 use uint;
 use util;
@@ -55,6 +59,8 @@ pub mod distributions;
 
 /// A type that can be randomly generated using an Rng
 pub trait Rand {
+    /// Generates a random instance of this type using the specified source of
+    /// randomness
     fn rand<R: Rng>(rng: &mut R) -> Self;
 }
 
@@ -253,10 +259,13 @@ pub trait Rng {
 
 /// A value with a particular weight compared to other values
 pub struct Weighted<T> {
+    /// The numerical weight of this item
     weight: uint,
+    /// The actual item which is being weighted
     item: T,
 }
 
+/// Helper functions attached to the Rng type
 pub trait RngUtil {
     /// Return a random value of a Rand type
     fn gen<T:Rand>(&mut self) -> T;
@@ -471,7 +480,7 @@ impl<R: Rng> RngUtil for R {
     fn gen_char_from(&mut self, chars: &str) -> char {
         assert!(!chars.is_empty());
         let mut cs = ~[];
-        for str::each_char(chars) |c| { cs.push(c) }
+        for chars.iter().advance |c| { cs.push(c) }
         self.choose(cs)
     }
 
@@ -604,9 +613,9 @@ pub struct IsaacRng {
     priv c: u32
 }
 
-pub impl IsaacRng {
+impl IsaacRng {
     /// Create an ISAAC random number generator with a random seed.
-    fn new() -> IsaacRng {
+    pub fn new() -> IsaacRng {
         IsaacRng::new_seeded(seed())
     }
 
@@ -615,7 +624,7 @@ pub impl IsaacRng {
     /// will be silently ignored. A generator constructed with a given seed
     /// will generate the same sequence of values as all other generators
     /// constructed with the same seed.
-    fn new_seeded(seed: &[u8]) -> IsaacRng {
+    pub fn new_seeded(seed: &[u8]) -> IsaacRng {
         let mut rng = IsaacRng {
             cnt: 0,
             rsl: [0, .. RAND_SIZE],
@@ -635,7 +644,7 @@ pub impl IsaacRng {
 
     /// Create an ISAAC random number generator using the default
     /// fixed seed.
-    fn new_unseeded() -> IsaacRng {
+    pub fn new_unseeded() -> IsaacRng {
         let mut rng = IsaacRng {
             cnt: 0,
             rsl: [0, .. RAND_SIZE],
@@ -649,14 +658,15 @@ pub impl IsaacRng {
     /// Initialises `self`. If `use_rsl` is true, then use the current value
     /// of `rsl` as a seed, otherwise construct one algorithmically (not
     /// randomly).
-    priv fn init(&mut self, use_rsl: bool) {
-        macro_rules! init_mut_many (
-            ($( $var:ident ),* = $val:expr ) => {
-                let mut $( $var = $val ),*;
-            }
-        );
-        init_mut_many!(a, b, c, d, e, f, g, h = 0x9e3779b9);
-
+    fn init(&mut self, use_rsl: bool) {
+        let mut a = 0x9e3779b9;
+        let mut b = a;
+        let mut c = a;
+        let mut d = a;
+        let mut e = a;
+        let mut f = a;
+        let mut g = a;
+        let mut h = a;
 
         macro_rules! mix(
             () => {{
@@ -707,12 +717,12 @@ pub impl IsaacRng {
 
     /// Refills the output buffer (`self.rsl`)
     #[inline]
-    priv fn isaac(&mut self) {
+    fn isaac(&mut self) {
         self.c += 1;
         // abbreviations
-        let mut a = self.a, b = self.b + self.c;
+        let mut (a, b) = (self.a, self.b + self.c);
 
-        static midpoint: uint =  RAND_SIZE as uint / 2;
+        static midpoint: uint = RAND_SIZE as uint / 2;
 
         macro_rules! ind (($x:expr) => {
             self.mem[($x >> 2) & (RAND_SIZE - 1)]
@@ -787,9 +797,9 @@ impl Rng for XorShiftRng {
     }
 }
 
-pub impl XorShiftRng {
+impl XorShiftRng {
     /// Create an xor shift random number generator with a default seed.
-    fn new() -> XorShiftRng {
+    pub fn new() -> XorShiftRng {
         // constants taken from http://en.wikipedia.org/wiki/Xorshift
         XorShiftRng::new_seeded(123456789u32,
                                 362436069u32,
@@ -799,10 +809,10 @@ pub impl XorShiftRng {
 
     /**
      * Create a random number generator using the specified seed. A generator
-     * constructed with a given seed will generate the same sequence of values as
-     * all other generators constructed with the same seed.
+     * constructed with a given seed will generate the same sequence of values
+     * as all other generators constructed with the same seed.
      */
-    fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
+    pub fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
         XorShiftRng {
             x: x,
             y: y,
diff --git a/src/libstd/rand/distributions.rs b/src/libstd/rand/distributions.rs
index 72cff5111e7..f08d967cbe0 100644
--- a/src/libstd/rand/distributions.rs
+++ b/src/libstd/rand/distributions.rs
@@ -20,7 +20,7 @@
 // Generating Random Variables"], but more robust. If one wanted, one
 // could implement VIZIGNOR the ZIGNOR paper for more speed.
 
-use prelude::*;
+use f64;
 use rand::{Rng,Rand};
 
 mod ziggurat_tables;
@@ -89,7 +89,7 @@ impl Rand for StandardNormal {
             // do-while, so the condition should be true on the first
             // run, they get overwritten anyway (0 < 1, so these are
             // good).
-            let mut x = 1.0, y = 0.0;
+            let mut (x, y) = (1.0, 0.0);
 
             // XXX infinities?
             while -2.0*y < x * x {
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index 30f60dce041..1eb3d3a0daa 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -14,6 +14,8 @@ Runtime type reflection
 
 */
 
+#[allow(missing_doc)];
+
 use intrinsic::{TyDesc, TyVisitor};
 use intrinsic::Opaque;
 use libc::c_void;
@@ -46,28 +48,28 @@ pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
     MovePtrAdaptor { inner: v }
 }
 
-pub impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
+impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
     #[inline(always)]
-    fn bump(&self, sz: uint) {
-      do self.inner.move_ptr() |p| {
+    pub fn bump(&self, sz: uint) {
+        do self.inner.move_ptr() |p| {
             ((p as uint) + sz) as *c_void
-      };
+        };
     }
 
     #[inline(always)]
-    fn align(&self, a: uint) {
-      do self.inner.move_ptr() |p| {
+    pub fn align(&self, a: uint) {
+        do self.inner.move_ptr() |p| {
             align(p as uint, a) as *c_void
-      };
+        };
     }
 
     #[inline(always)]
-    fn align_to<T>(&self) {
+    pub fn align_to<T>(&self) {
         self.align(sys::min_align_of::<T>());
     }
 
     #[inline(always)]
-    fn bump_past<T>(&self) {
+    pub fn bump_past<T>(&self) {
         self.bump(sys::size_of::<T>());
     }
 }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index a05009e375c..46f69d020d1 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -14,12 +14,15 @@ More runtime type reflection
 
 */
 
+#[allow(missing_doc)];
+
 use cast::transmute;
 use char;
 use intrinsic;
 use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
 use intrinsic::Opaque;
 use io::{Writer, WriterUtil};
+use iterator::IteratorUtil;
 use libc::c_void;
 use managed;
 use ptr;
@@ -172,12 +175,11 @@ impl MovePtr for ReprVisitor {
     }
 }
 
-pub impl ReprVisitor {
-
+impl ReprVisitor {
     // Various helpers for the TyVisitor impl
 
     #[inline(always)]
-    fn get<T>(&self, f: &fn(&T)) -> bool {
+    pub fn get<T>(&self, f: &fn(&T)) -> bool {
         unsafe {
             f(transmute::<*c_void,&T>(*self.ptr));
         }
@@ -185,12 +187,12 @@ pub impl ReprVisitor {
     }
 
     #[inline(always)]
-    fn visit_inner(&self, inner: *TyDesc) -> bool {
+    pub fn visit_inner(&self, inner: *TyDesc) -> bool {
         self.visit_ptr_inner(*self.ptr, inner)
     }
 
     #[inline(always)]
-    fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool {
+    pub fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool {
         unsafe {
             let u = ReprVisitor(ptr, self.writer);
             let v = reflect::MovePtrAdaptor(u);
@@ -200,21 +202,21 @@ pub impl ReprVisitor {
     }
 
     #[inline(always)]
-    fn write<T:Repr>(&self) -> bool {
+    pub fn write<T:Repr>(&self) -> bool {
         do self.get |v:&T| {
             v.write_repr(self.writer);
         }
     }
 
-    fn write_escaped_slice(&self, slice: &str) {
+    pub fn write_escaped_slice(&self, slice: &str) {
         self.writer.write_char('"');
-        for slice.each_char |ch| {
+        for slice.iter().advance |ch| {
             self.writer.write_escaped_char(ch);
         }
         self.writer.write_char('"');
     }
 
-    fn write_mut_qualifier(&self, mtbl: uint) {
+    pub fn write_mut_qualifier(&self, mtbl: uint) {
         if mtbl == 0 {
             self.writer.write_str("mut ");
         } else if mtbl == 1 {
@@ -225,8 +227,12 @@ pub impl ReprVisitor {
         }
     }
 
-    fn write_vec_range(&self, mtbl: uint, ptr: *u8, len: uint,
-                       inner: *TyDesc) -> bool {
+    pub fn write_vec_range(&self,
+                           mtbl: uint,
+                           ptr: *u8,
+                           len: uint,
+                           inner: *TyDesc)
+                           -> bool {
         let mut p = ptr;
         let end = ptr::offset(p, len);
         let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
@@ -246,13 +252,14 @@ pub impl ReprVisitor {
         true
     }
 
-    fn write_unboxed_vec_repr(&self, mtbl: uint, v: &UnboxedVecRepr,
-                              inner: *TyDesc) -> bool {
+    pub fn write_unboxed_vec_repr(&self,
+                                  mtbl: uint,
+                                  v: &UnboxedVecRepr,
+                                  inner: *TyDesc)
+                                  -> bool {
         self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
                              v.fill, inner)
     }
-
-
 }
 
 impl TyVisitor for ReprVisitor {
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index cda2fe13e37..24751b66925 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -10,7 +10,7 @@
 
 //! A type representing either success or failure
 
-// NB: transitionary, de-mode-ing.
+#[allow(missing_doc)];
 
 use cmp::Eq;
 use either;
@@ -20,6 +20,7 @@ use option::{None, Option, Some};
 use old_iter::BaseIter;
 use vec;
 use vec::OwnedVector;
+use container::Container;
 
 /// The result type
 #[deriving(Clone, Eq)]
@@ -40,7 +41,7 @@ pub enum Result<T, U> {
 #[inline(always)]
 pub fn get<T:Copy,U>(res: &Result<T, U>) -> T {
     match *res {
-      Ok(copy t) => t,
+      Ok(ref t) => copy *t,
       Err(ref the_err) =>
         fail!("get called on error result: %?", *the_err)
     }
@@ -72,7 +73,7 @@ pub fn get_ref<'a, T, U>(res: &'a Result<T, U>) -> &'a T {
 #[inline(always)]
 pub fn get_err<T, U: Copy>(res: &Result<T, U>) -> U {
     match *res {
-      Err(copy u) => u,
+      Err(ref u) => copy *u,
       Ok(_) => fail!("get_err called on ok result")
     }
 }
@@ -102,8 +103,8 @@ pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
 pub fn to_either<T:Copy,U:Copy>(res: &Result<U, T>)
     -> Either<T, U> {
     match *res {
-      Ok(copy res) => either::Right(res),
-      Err(copy fail_) => either::Left(fail_)
+      Ok(ref res) => either::Right(copy *res),
+      Err(ref fail_) => either::Left(copy *fail_)
     }
 }
 
@@ -206,7 +207,7 @@ pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: &fn(&T) -> U)
   -> Result<U, E> {
     match *res {
       Ok(ref t) => Ok(op(t)),
-      Err(copy e) => Err(e)
+      Err(ref e) => Err(copy *e)
     }
 }
 
@@ -222,60 +223,60 @@ pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: &fn(&T) -> U)
 pub fn map_err<T:Copy,E,F:Copy>(res: &Result<T, E>, op: &fn(&E) -> F)
   -> Result<T, F> {
     match *res {
-      Ok(copy t) => Ok(t),
+      Ok(ref t) => Ok(copy *t),
       Err(ref e) => Err(op(e))
     }
 }
 
-pub impl<T, E> Result<T, E> {
+impl<T, E> Result<T, E> {
     #[inline(always)]
-    fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }
+    pub fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }
 
     #[inline(always)]
-    fn is_ok(&self) -> bool { is_ok(self) }
+    pub fn is_ok(&self) -> bool { is_ok(self) }
 
     #[inline(always)]
-    fn is_err(&self) -> bool { is_err(self) }
+    pub fn is_err(&self) -> bool { is_err(self) }
 
     #[inline(always)]
-    fn iter(&self, f: &fn(&T)) { iter(self, f) }
+    pub fn iter(&self, f: &fn(&T)) { iter(self, f) }
 
     #[inline(always)]
-    fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) }
+    pub fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) }
 
     #[inline(always)]
-    fn unwrap(self) -> T { unwrap(self) }
+    pub fn unwrap(self) -> T { unwrap(self) }
 
     #[inline(always)]
-    fn unwrap_err(self) -> E { unwrap_err(self) }
+    pub fn unwrap_err(self) -> E { unwrap_err(self) }
 
     #[inline(always)]
-    fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
+    pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
         chain(self, op)
     }
 
     #[inline(always)]
-    fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
+    pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
         chain_err(self, op)
     }
 }
 
-pub impl<T:Copy,E> Result<T, E> {
+impl<T:Copy,E> Result<T, E> {
     #[inline(always)]
-    fn get(&self) -> T { get(self) }
+    pub fn get(&self) -> T { get(self) }
 
     #[inline(always)]
-    fn map_err<F:Copy>(&self, op: &fn(&E) -> F) -> Result<T,F> {
+    pub fn map_err<F:Copy>(&self, op: &fn(&E) -> F) -> Result<T,F> {
         map_err(self, op)
     }
 }
 
-pub impl<T, E: Copy> Result<T, E> {
+impl<T, E: Copy> Result<T, E> {
     #[inline(always)]
-    fn get_err(&self) -> E { get_err(self) }
+    pub fn get_err(&self) -> E { get_err(self) }
 
     #[inline(always)]
-    fn map<U:Copy>(&self, op: &fn(&T) -> U) -> Result<U,E> {
+    pub fn map<U:Copy>(&self, op: &fn(&T) -> U) -> Result<U,E> {
         map(self, op)
     }
 }
@@ -301,25 +302,26 @@ pub impl<T, E: Copy> Result<T, E> {
 pub fn map_vec<T,U:Copy,V:Copy>(
     ts: &[T], op: &fn(&T) -> Result<V,U>) -> Result<~[V],U> {
 
-    let mut vs: ~[V] = vec::with_capacity(vec::len(ts));
+    let mut vs: ~[V] = vec::with_capacity(ts.len());
     for ts.each |t| {
         match op(t) {
-          Ok(copy v) => vs.push(v),
-          Err(copy u) => return Err(u)
+          Ok(v) => vs.push(v),
+          Err(u) => return Err(u)
         }
     }
     return Ok(vs);
 }
 
 #[inline(always)]
+#[allow(missing_doc)]
 pub fn map_opt<T,U:Copy,V:Copy>(
     o_t: &Option<T>, op: &fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
 
     match *o_t {
       None => Ok(None),
       Some(ref t) => match op(t) {
-        Ok(copy v) => Ok(Some(v)),
-        Err(copy e) => Err(e)
+        Ok(v) => Ok(Some(v)),
+        Err(e) => Err(e)
       }
     }
 }
@@ -338,13 +340,13 @@ pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
                 op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
 
     assert!(vec::same_length(ss, ts));
-    let n = vec::len(ts);
+    let n = ts.len();
     let mut vs = vec::with_capacity(n);
     let mut i = 0u;
     while i < n {
         match op(&ss[i],&ts[i]) {
-          Ok(copy v) => vs.push(v),
-          Err(copy u) => return Err(u)
+          Ok(v) => vs.push(v),
+          Err(u) => return Err(u)
         }
         i += 1u;
     }
@@ -361,12 +363,12 @@ pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
                          op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
 
     assert!(vec::same_length(ss, ts));
-    let n = vec::len(ts);
+    let n = ts.len();
     let mut i = 0u;
     while i < n {
         match op(&ss[i],&ts[i]) {
           Ok(()) => (),
-          Err(copy u) => return Err(u)
+          Err(u) => return Err(u)
         }
         i += 1u;
     }
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index b00df78f433..82e6d44fe62 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -120,13 +120,13 @@ impl<T> ChanOne<T> {
             match oldstate {
                 STATE_BOTH => {
                     // Port is not waiting yet. Nothing to do
-                    do Local::borrow::<Scheduler> |sched| {
+                    do Local::borrow::<Scheduler, ()> |sched| {
                         rtdebug!("non-rendezvous send");
                         sched.metrics.non_rendezvous_sends += 1;
                     }
                 }
                 STATE_ONE => {
-                    do Local::borrow::<Scheduler> |sched| {
+                    do Local::borrow::<Scheduler, ()> |sched| {
                         rtdebug!("rendezvous send");
                         sched.metrics.rendezvous_sends += 1;
                     }
@@ -331,8 +331,8 @@ pub struct Port<T> {
 
 pub fn stream<T: Owned>() -> (Port<T>, Chan<T>) {
     let (pone, cone) = oneshot();
-    let port = Port { next: Cell(pone) };
-    let chan = Chan { next: Cell(cone) };
+    let port = Port { next: Cell::new(pone) };
+    let chan = Chan { next: Cell::new(cone) };
     return (port, chan);
 }
 
@@ -647,7 +647,7 @@ mod test {
     fn oneshot_multi_task_recv_then_send() {
         do run_in_newsched_task {
             let (port, chan) = oneshot::<~int>();
-            let port_cell = Cell(port);
+            let port_cell = Cell::new(port);
             do spawntask_immediately {
                 assert!(port_cell.take().recv() == ~10);
             }
@@ -660,8 +660,8 @@ mod test {
     fn oneshot_multi_task_recv_then_close() {
         do run_in_newsched_task {
             let (port, chan) = oneshot::<~int>();
-            let port_cell = Cell(port);
-            let chan_cell = Cell(chan);
+            let port_cell = Cell::new(port);
+            let chan_cell = Cell::new(chan);
             do spawntask_later {
                 let _cell = chan_cell.take();
             }
@@ -677,7 +677,7 @@ mod test {
         for stress_factor().times {
             do run_in_newsched_task {
                 let (port, chan) = oneshot::<int>();
-                let port_cell = Cell(port);
+                let port_cell = Cell::new(port);
                 let _thread = do spawntask_thread {
                     let _p = port_cell.take();
                 };
@@ -691,8 +691,8 @@ mod test {
         for stress_factor().times {
             do run_in_newsched_task {
                 let (port, chan) = oneshot::<int>();
-                let chan_cell = Cell(chan);
-                let port_cell = Cell(port);
+                let chan_cell = Cell::new(chan);
+                let port_cell = Cell::new(port);
                 let _thread1 = do spawntask_thread {
                     let _p = port_cell.take();
                 };
@@ -709,17 +709,17 @@ mod test {
         for stress_factor().times {
             do run_in_newsched_task {
                 let (port, chan) = oneshot::<int>();
-                let chan_cell = Cell(chan);
-                let port_cell = Cell(port);
+                let chan_cell = Cell::new(chan);
+                let port_cell = Cell::new(port);
                 let _thread1 = do spawntask_thread {
-                    let port_cell = Cell(port_cell.take());
+                    let port_cell = Cell::new(port_cell.take());
                     let res = do spawntask_try {
                         port_cell.take().recv();
                     };
                     assert!(res.is_err());
                 };
                 let _thread2 = do spawntask_thread {
-                    let chan_cell = Cell(chan_cell.take());
+                    let chan_cell = Cell::new(chan_cell.take());
                     do spawntask {
                         chan_cell.take();
                     }
@@ -733,8 +733,8 @@ mod test {
         for stress_factor().times {
             do run_in_newsched_task {
                 let (port, chan) = oneshot::<~int>();
-                let chan_cell = Cell(chan);
-                let port_cell = Cell(port);
+                let chan_cell = Cell::new(chan);
+                let port_cell = Cell::new(port);
                 let _thread1 = do spawntask_thread {
                     chan_cell.take().send(~10);
                 };
@@ -757,7 +757,7 @@ mod test {
                 fn send(chan: Chan<~int>, i: int) {
                     if i == 10 { return }
 
-                    let chan_cell = Cell(chan);
+                    let chan_cell = Cell::new(chan);
                     do spawntask_random {
                         let chan = chan_cell.take();
                         chan.send(~i);
@@ -768,7 +768,7 @@ mod test {
                 fn recv(port: Port<~int>, i: int) {
                     if i == 10 { return }
 
-                    let port_cell = Cell(port);
+                    let port_cell = Cell::new(port);
                     do spawntask_random {
                         let port = port_cell.take();
                         assert!(port.recv() == ~i);
@@ -918,4 +918,3 @@ mod test {
         }
     }
 }
-
diff --git a/src/libstd/rt/context.rs b/src/libstd/rt/context.rs
index 0d011ce42ba..d5ca8473cee 100644
--- a/src/libstd/rt/context.rs
+++ b/src/libstd/rt/context.rs
@@ -27,8 +27,8 @@ pub struct Context {
     regs: ~Registers
 }
 
-pub impl Context {
-    fn empty() -> Context {
+impl Context {
+    pub fn empty() -> Context {
         Context {
             start: None,
             regs: new_regs()
@@ -36,7 +36,7 @@ pub impl Context {
     }
 
     /// Create a new context that will resume execution by running ~fn()
-    fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
+    pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
         // XXX: Putting main into a ~ so it's a thin pointer and can
         // be passed to the spawn function.  Another unfortunate
         // allocation
@@ -71,7 +71,7 @@ pub impl Context {
     saving the registers values of the executing thread to a Context
     then loading the registers from a previously saved Context.
     */
-    fn swap(out_context: &mut Context, in_context: &Context) {
+    pub fn swap(out_context: &mut Context, in_context: &Context) {
         let out_regs: &mut Registers = match out_context {
             &Context { regs: ~ref mut r, _ } => r
         };
diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs
index ad9658e48ba..c7c3eadbe21 100644
--- a/src/libstd/rt/io/extensions.rs
+++ b/src/libstd/rt/io/extensions.rs
@@ -342,7 +342,7 @@ impl<T: Reader> ReaderByteConversions for T {
     fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
         assert!(nbytes > 0 && nbytes <= 8);
 
-        let mut val = 0u64, pos = 0, i = nbytes;
+        let mut (val, pos, i) = (0u64, 0, nbytes);
         while i > 0 {
             val += (self.read_u8() as u64) << pos;
             pos += 8;
@@ -358,7 +358,7 @@ impl<T: Reader> ReaderByteConversions for T {
     fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
         assert!(nbytes > 0 && nbytes <= 8);
 
-        let mut val = 0u64, i = nbytes;
+        let mut (val, i) = (0u64, nbytes);
         while i > 0 {
             i -= 1;
             val += (self.read_u8() as u64) << i * 8;
@@ -604,7 +604,7 @@ mod test {
     #[test]
     fn read_byte_0_bytes() {
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
@@ -652,7 +652,7 @@ mod test {
     #[test]
     fn read_bytes_partial() {
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
@@ -691,7 +691,7 @@ mod test {
     #[test]
     fn push_bytes_partial() {
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
@@ -725,7 +725,7 @@ mod test {
     #[test]
     fn push_bytes_error() {
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
@@ -752,7 +752,7 @@ mod test {
         // push_bytes unsafely sets the vector length. This is testing that
         // upon failure the length is reset correctly.
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
@@ -778,7 +778,7 @@ mod test {
     #[test]
     fn read_to_end() {
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
@@ -805,7 +805,7 @@ mod test {
     #[ignore(cfg(windows))]
     fn read_to_end_error() {
         let mut reader = MockReader::new();
-        let count = Cell(0);
+        let count = Cell::new(0);
         reader.read = |buf| {
             do count.with_mut_ref |count| {
                 if *count == 0 {
diff --git a/src/libstd/rt/io/file.rs b/src/libstd/rt/io/file.rs
index 1f61cf25fbd..a99f5da032c 100644
--- a/src/libstd/rt/io/file.rs
+++ b/src/libstd/rt/io/file.rs
@@ -75,5 +75,5 @@ fn super_simple_smoke_test_lets_go_read_some_files_and_have_a_good_time() {
     let message = "it's alright. have a good time";
     let filename = &Path("test.txt");
     let mut outstream = FileStream::open(filename, Create, Read).unwrap();
-    outstream.write(message.to_bytes());
+    outstream.write(message.as_bytes());
 }
diff --git a/src/libstd/rt/io/flate.rs b/src/libstd/rt/io/flate.rs
index db2683dc85d..e57b80658ee 100644
--- a/src/libstd/rt/io/flate.rs
+++ b/src/libstd/rt/io/flate.rs
@@ -100,13 +100,15 @@ mod test {
     use super::super::mem::*;
     use super::super::Decorator;
 
+    use str;
+
     #[test]
     #[ignore]
     fn smoke_test() {
         let mem_writer = MemWriter::new();
         let mut deflate_writer = DeflateWriter::new(mem_writer);
         let in_msg = "test";
-        let in_bytes = in_msg.to_bytes();
+        let in_bytes = in_msg.as_bytes();
         deflate_writer.write(in_bytes);
         deflate_writer.flush();
         let buf = deflate_writer.inner().inner();
diff --git a/src/libstd/rt/io/mem.rs b/src/libstd/rt/io/mem.rs
index b2701c1fdc3..bd9cff76e57 100644
--- a/src/libstd/rt/io/mem.rs
+++ b/src/libstd/rt/io/mem.rs
@@ -15,9 +15,10 @@
 //! * Should probably have something like this for strings.
 //! * Should they implement Closable? Would take extra state.
 
+use cmp::min;
 use prelude::*;
 use super::*;
-use cmp::min;
+use vec;
 
 /// Writes to an owned, growable byte vector
 pub struct MemWriter {
diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs
index f7c03c13a58..3607f781da3 100644
--- a/src/libstd/rt/io/net/tcp.rs
+++ b/src/libstd/rt/io/net/tcp.rs
@@ -287,7 +287,7 @@ mod test {
             do spawntask_immediately {
                 let mut listener = TcpListener::bind(addr);
                 for int::range(0, MAX) |i| {
-                    let stream = Cell(listener.accept());
+                    let stream = Cell::new(listener.accept());
                     rtdebug!("accepted");
                     // Start another task to handle the connection
                     do spawntask_immediately {
@@ -326,7 +326,7 @@ mod test {
             do spawntask_immediately {
                 let mut listener = TcpListener::bind(addr);
                 for int::range(0, MAX) |_| {
-                    let stream = Cell(listener.accept());
+                    let stream = Cell::new(listener.accept());
                     rtdebug!("accepted");
                     // Start another task to handle the connection
                     do spawntask_later {
diff --git a/src/libstd/rt/io/stdio.rs b/src/libstd/rt/io/stdio.rs
index 247fe954408..57bec79563f 100644
--- a/src/libstd/rt/io/stdio.rs
+++ b/src/libstd/rt/io/stdio.rs
@@ -50,4 +50,3 @@ impl Writer for StdWriter {
 
     fn flush(&mut self) { fail!() }
 }
-
diff --git a/src/libstd/rt/join_latch.rs b/src/libstd/rt/join_latch.rs
new file mode 100644
index 00000000000..ad5cf2eb378
--- /dev/null
+++ b/src/libstd/rt/join_latch.rs
@@ -0,0 +1,645 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The JoinLatch is a concurrent type that establishes the task
+//! tree and propagates failure.
+//!
+//! Each task gets a JoinLatch that is derived from the JoinLatch
+//! of its parent task. Every latch must be released by either calling
+//! the non-blocking `release` method or the task-blocking `wait` method.
+//! Releasing a latch does not complete until all of its child latches
+//! complete.
+//!
+//! Latches carry a `success` flag that is set to `false` during task
+//! failure and is propagated both from children to parents and parents
+//! to children. The status af this flag may be queried for the purposes
+//! of linked failure.
+//!
+//! In addition to failure propagation the task tree serves to keep the
+//! default task schedulers alive. The runtime only sends the shutdown
+//! message to schedulers once the root task exits.
+//!
+//! Under this scheme tasks that terminate before their children become
+//! 'zombies' since they may not exit until their children do. Zombie
+//! tasks are 'tombstoned' as `Tombstone(~JoinLatch)` and the tasks
+//! themselves allowed to terminate.
+//!
+//! XXX: Propagate flag from parents to children.
+//! XXX: Tombstoning actually doesn't work.
+//! XXX: This could probably be done in a way that doesn't leak tombstones
+//!      longer than the life of the child tasks.
+
+use comm::{GenericPort, Peekable, GenericSmartChan};
+use clone::Clone;
+use container::Container;
+use option::{Option, Some, None};
+use ops::Drop;
+use rt::comm::{SharedChan, Port, stream};
+use rt::local::Local;
+use rt::sched::Scheduler;
+use unstable::atomics::{AtomicUint, SeqCst};
+use util;
+use vec::OwnedVector;
+
+// FIXME #7026: Would prefer this to be an enum
+pub struct JoinLatch {
+    priv parent: Option<ParentLink>,
+    priv child: Option<ChildLink>,
+    closed: bool,
+}
+
+// Shared between parents and all their children.
+struct SharedState {
+    /// Reference count, held by a parent and all children.
+    count: AtomicUint,
+    success: bool
+}
+
+struct ParentLink {
+    shared: *mut SharedState,
+    // For communicating with the parent.
+    chan: SharedChan<Message>
+}
+
+struct ChildLink {
+    shared: ~SharedState,
+    // For receiving from children.
+    port: Port<Message>,
+    chan: SharedChan<Message>,
+    // Prevents dropping the child SharedState reference counts multiple times.
+    dropped_child: bool
+}
+
+// Messages from child latches to parent.
+enum Message {
+    Tombstone(~JoinLatch),
+    ChildrenTerminated
+}
+
+impl JoinLatch {
+    pub fn new_root() -> ~JoinLatch {
+        let this = ~JoinLatch {
+            parent: None,
+            child: None,
+            closed: false
+        };
+        rtdebug!("new root latch %x", this.id());
+        return this;
+    }
+
+    fn id(&self) -> uint {
+        unsafe { ::cast::transmute(&*self) }
+    }
+
+    pub fn new_child(&mut self) -> ~JoinLatch {
+        rtassert!(!self.closed);
+
+        if self.child.is_none() {
+            // This is the first time spawning a child
+            let shared = ~SharedState {
+                count: AtomicUint::new(1),
+                success: true
+            };
+            let (port, chan) = stream();
+            let chan = SharedChan::new(chan);
+            let child = ChildLink {
+                shared: shared,
+                port: port,
+                chan: chan,
+                dropped_child: false
+            };
+            self.child = Some(child);
+        }
+
+        let child_link: &mut ChildLink = self.child.get_mut_ref();
+        let shared_state: *mut SharedState = &mut *child_link.shared;
+
+        child_link.shared.count.fetch_add(1, SeqCst);
+
+        let child = ~JoinLatch {
+            parent: Some(ParentLink {
+                shared: shared_state,
+                chan: child_link.chan.clone()
+            }),
+            child: None,
+            closed: false
+        };
+        rtdebug!("NEW child latch %x", child.id());
+        return child;
+    }
+
+    pub fn release(~self, local_success: bool) {
+        // XXX: This should not block, but there's a bug in the below
+        // code that I can't figure out.
+        self.wait(local_success);
+    }
+
+    // XXX: Should not require ~self
+    fn release_broken(~self, local_success: bool) {
+        rtassert!(!self.closed);
+
+        rtdebug!("releasing %x", self.id());
+
+        let id = self.id();
+        let _ = id; // XXX: `id` is only used in debug statements so appears unused
+        let mut this = self;
+        let mut child_success = true;
+        let mut children_done = false;
+
+        if this.child.is_some() {
+            rtdebug!("releasing children");
+            let child_link: &mut ChildLink = this.child.get_mut_ref();
+            let shared: &mut SharedState = &mut *child_link.shared;
+
+            if !child_link.dropped_child {
+                let last_count = shared.count.fetch_sub(1, SeqCst);
+                rtdebug!("child count before sub %u %x", last_count, id);
+                if last_count == 1 {
+                    assert!(child_link.chan.try_send(ChildrenTerminated));
+                }
+                child_link.dropped_child = true;
+            }
+
+            // Wait for messages from children
+            let mut tombstones = ~[];
+            loop {
+                if child_link.port.peek() {
+                    match child_link.port.recv() {
+                        Tombstone(t) => {
+                            tombstones.push(t);
+                        },
+                        ChildrenTerminated => {
+                            children_done = true;
+                            break;
+                        }
+                    }
+                } else {
+                    break
+                }
+            }
+
+            rtdebug!("releasing %u tombstones %x", tombstones.len(), id);
+
+            // Try to release the tombstones. Those that still have
+            // outstanding will be re-enqueued.  When this task's
+            // parents release their latch we'll end up back here
+            // trying them again.
+            while !tombstones.is_empty() {
+                tombstones.pop().release(true);
+            }
+
+            if children_done {
+                let count = shared.count.load(SeqCst);
+                assert!(count == 0);
+                // self_count is the acquire-read barrier
+                child_success = shared.success;
+            }
+        } else {
+            children_done = true;
+        }
+
+        let total_success = local_success && child_success;
+
+        rtassert!(this.parent.is_some());
+
+        unsafe {
+            {
+                let parent_link: &mut ParentLink = this.parent.get_mut_ref();
+                let shared: *mut SharedState = parent_link.shared;
+
+                if !total_success {
+                    // parent_count is the write-wait barrier
+                    (*shared).success = false;
+                }
+            }
+
+            if children_done {
+                rtdebug!("children done");
+                do Local::borrow::<Scheduler, ()> |sched| {
+                    sched.metrics.release_tombstone += 1;
+                }
+                {
+                    rtdebug!("RELEASING parent %x", id);
+                    let parent_link: &mut ParentLink = this.parent.get_mut_ref();
+                    let shared: *mut SharedState = parent_link.shared;
+                    let last_count = (*shared).count.fetch_sub(1, SeqCst);
+                    rtdebug!("count before parent sub %u %x", last_count, id);
+                    if last_count == 1 {
+                        assert!(parent_link.chan.try_send(ChildrenTerminated));
+                    }
+                }
+                this.closed = true;
+                util::ignore(this);
+            } else {
+                rtdebug!("children not done");
+                rtdebug!("TOMBSTONING %x", id);
+                do Local::borrow::<Scheduler, ()> |sched| {
+                    sched.metrics.release_no_tombstone += 1;
+                }
+                let chan = {
+                    let parent_link: &mut ParentLink = this.parent.get_mut_ref();
+                    parent_link.chan.clone()
+                };
+                assert!(chan.try_send(Tombstone(this)));
+            }
+        }
+    }
+
+    // XXX: Should not require ~self
+    pub fn wait(~self, local_success: bool) -> bool {
+        rtassert!(!self.closed);
+
+        rtdebug!("WAITING %x", self.id());
+
+        let mut this = self;
+        let mut child_success = true;
+
+        if this.child.is_some() {
+            rtdebug!("waiting for children");
+            let child_link: &mut ChildLink = this.child.get_mut_ref();
+            let shared: &mut SharedState = &mut *child_link.shared;
+
+            if !child_link.dropped_child {
+                let last_count = shared.count.fetch_sub(1, SeqCst);
+                rtdebug!("child count before sub %u", last_count);
+                if last_count == 1 {
+                    assert!(child_link.chan.try_send(ChildrenTerminated));
+                }
+                child_link.dropped_child = true;
+            }
+
+            // Wait for messages from children
+            loop {
+                match child_link.port.recv() {
+                    Tombstone(t) => {
+                        t.wait(true);
+                    }
+                    ChildrenTerminated => break
+                }
+            }
+
+            let count = shared.count.load(SeqCst);
+            if count != 0 { ::io::println(fmt!("%u", count)); }
+            assert!(count == 0);
+            // self_count is the acquire-read barrier
+            child_success = shared.success;
+        }
+
+        let total_success = local_success && child_success;
+
+        if this.parent.is_some() {
+            rtdebug!("releasing parent");
+            unsafe {
+                let parent_link: &mut ParentLink = this.parent.get_mut_ref();
+                let shared: *mut SharedState = parent_link.shared;
+
+                if !total_success {
+                    // parent_count is the write-wait barrier
+                    (*shared).success = false;
+                }
+
+                let last_count = (*shared).count.fetch_sub(1, SeqCst);
+                rtdebug!("count before parent sub %u", last_count);
+                if last_count == 1 {
+                    assert!(parent_link.chan.try_send(ChildrenTerminated));
+                }
+            }
+        }
+
+        this.closed = true;
+        util::ignore(this);
+
+        return total_success;
+    }
+}
+
+impl Drop for JoinLatch {
+    fn finalize(&self) {
+        rtdebug!("DESTROYING %x", self.id());
+        rtassert!(self.closed);
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use cell::Cell;
+    use container::Container;
+    use iter::Times;
+    use old_iter::BaseIter;
+    use rt::test::*;
+    use rand;
+    use rand::RngUtil;
+    use vec::{CopyableVector, ImmutableVector};
+
+    #[test]
+    fn success_immediately() {
+        do run_in_newsched_task {
+            let mut latch = JoinLatch::new_root();
+
+            let child_latch = latch.new_child();
+            let child_latch = Cell::new(child_latch);
+            do spawntask_immediately {
+                let child_latch = child_latch.take();
+                assert!(child_latch.wait(true));
+            }
+
+            assert!(latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn success_later() {
+        do run_in_newsched_task {
+            let mut latch = JoinLatch::new_root();
+
+            let child_latch = latch.new_child();
+            let child_latch = Cell::new(child_latch);
+            do spawntask_later {
+                let child_latch = child_latch.take();
+                assert!(child_latch.wait(true));
+            }
+
+            assert!(latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn mt_success() {
+        do run_in_mt_newsched_task {
+            let mut latch = JoinLatch::new_root();
+
+            for 10.times {
+                let child_latch = latch.new_child();
+                let child_latch = Cell::new(child_latch);
+                do spawntask_random {
+                    let child_latch = child_latch.take();
+                    assert!(child_latch.wait(true));
+                }
+            }
+
+            assert!(latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn mt_failure() {
+        do run_in_mt_newsched_task {
+            let mut latch = JoinLatch::new_root();
+
+            let spawn = |status| {
+                let child_latch = latch.new_child();
+                let child_latch = Cell::new(child_latch);
+                do spawntask_random {
+                    let child_latch = child_latch.take();
+                    child_latch.wait(status);
+                }
+            };
+
+            for 10.times { spawn(true) }
+            spawn(false);
+            for 10.times { spawn(true) }
+
+            assert!(!latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn mt_multi_level_success() {
+        do run_in_mt_newsched_task {
+            let mut latch = JoinLatch::new_root();
+
+            fn child(latch: &mut JoinLatch, i: int) {
+                let child_latch = latch.new_child();
+                let child_latch = Cell::new(child_latch);
+                do spawntask_random {
+                    let mut child_latch = child_latch.take();
+                    if i != 0 {
+                        child(&mut *child_latch, i - 1);
+                        child_latch.wait(true);
+                    } else {
+                        child_latch.wait(true);
+                    }
+                }
+            }
+
+            child(&mut *latch, 10);
+
+            assert!(latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn mt_multi_level_failure() {
+        do run_in_mt_newsched_task {
+            let mut latch = JoinLatch::new_root();
+
+            fn child(latch: &mut JoinLatch, i: int) {
+                let child_latch = latch.new_child();
+                let child_latch = Cell::new(child_latch);
+                do spawntask_random {
+                    let mut child_latch = child_latch.take();
+                    if i != 0 {
+                        child(&mut *child_latch, i - 1);
+                        child_latch.wait(false);
+                    } else {
+                        child_latch.wait(true);
+                    }
+                }
+            }
+
+            child(&mut *latch, 10);
+
+            assert!(!latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn release_child() {
+        do run_in_newsched_task {
+            let mut latch = JoinLatch::new_root();
+            let child_latch = latch.new_child();
+            let child_latch = Cell::new(child_latch);
+
+            do spawntask_immediately {
+                let latch = child_latch.take();
+                latch.release(false);
+            }
+
+            assert!(!latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn release_child_tombstone() {
+        do run_in_newsched_task {
+            let mut latch = JoinLatch::new_root();
+            let child_latch = latch.new_child();
+            let child_latch = Cell::new(child_latch);
+
+            do spawntask_immediately {
+                let mut latch = child_latch.take();
+                let child_latch = latch.new_child();
+                let child_latch = Cell::new(child_latch);
+                do spawntask_later {
+                    let latch = child_latch.take();
+                    latch.release(false);
+                }
+                latch.release(true);
+            }
+
+            assert!(!latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn release_child_no_tombstone() {
+        do run_in_newsched_task {
+            let mut latch = JoinLatch::new_root();
+            let child_latch = latch.new_child();
+            let child_latch = Cell::new(child_latch);
+
+            do spawntask_later {
+                let mut latch = child_latch.take();
+                let child_latch = latch.new_child();
+                let child_latch = Cell::new(child_latch);
+                do spawntask_immediately {
+                    let latch = child_latch.take();
+                    latch.release(false);
+                }
+                latch.release(true);
+            }
+
+            assert!(!latch.wait(true));
+        }
+    }
+
+    #[test]
+    fn release_child_tombstone_stress() {
+        fn rand_orders() -> ~[bool] {
+            let mut v = ~[false,.. 5];
+            v[0] = true;
+            let mut rng = rand::rng();
+            return rng.shuffle(v);
+        }
+
+        fn split_orders(orders: &[bool]) -> (~[bool], ~[bool]) {
+            if orders.is_empty() {
+                return (~[], ~[]);
+            } else if orders.len() <= 2 {
+                return (orders.to_owned(), ~[]);
+            }
+            let mut rng = rand::rng();
+            let n = rng.gen_uint_range(1, orders.len());
+            let first = orders.slice(0, n).to_owned();
+            let last = orders.slice(n, orders.len()).to_owned();
+            assert!(first.len() + last.len() == orders.len());
+            return (first, last);
+        }
+
+        for stress_factor().times {
+            do run_in_newsched_task {
+                fn doit(latch: &mut JoinLatch, orders: ~[bool], depth: uint) {
+                    let (my_orders, remaining_orders) = split_orders(orders);
+                    rtdebug!("(my_orders, remaining): %?", (&my_orders, &remaining_orders));
+                    rtdebug!("depth: %u", depth);
+                    let mut remaining_orders = remaining_orders;
+                    let mut num = 0;
+                    for my_orders.each |&order| {
+                        let child_latch = latch.new_child();
+                        let child_latch = Cell::new(child_latch);
+                        let (child_orders, remaining) = split_orders(remaining_orders);
+                        rtdebug!("(child_orders, remaining): %?", (&child_orders, &remaining));
+                        remaining_orders = remaining;
+                        let child_orders = Cell::new(child_orders);
+                        let child_num = num;
+                        let _ = child_num; // XXX unused except in rtdebug!
+                        do spawntask_random {
+                            rtdebug!("depth %u num %u", depth, child_num);
+                            let mut child_latch = child_latch.take();
+                            let child_orders = child_orders.take();
+                            doit(&mut *child_latch, child_orders, depth + 1);
+                            child_latch.release(order);
+                        }
+
+                        num += 1;
+                    }
+                }
+
+                let mut latch = JoinLatch::new_root();
+                let orders = rand_orders();
+                rtdebug!("orders: %?", orders);
+
+                doit(&mut *latch, orders, 0);
+
+                assert!(!latch.wait(true));
+            }
+        }
+    }
+
+    #[test]
+    fn whateverman() {
+        struct Order {
+            immediate: bool,
+            succeed: bool,
+            orders: ~[Order]
+        }
+        fn next(latch: &mut JoinLatch, orders: ~[Order]) {
+            for orders.each |order| {
+                let suborders = copy order.orders;
+                let child_latch = Cell::new(latch.new_child());
+                let succeed = order.succeed;
+                if order.immediate {
+                    do spawntask_immediately {
+                        let mut child_latch = child_latch.take();
+                        next(&mut *child_latch, copy suborders);
+                        rtdebug!("immediate releasing");
+                        child_latch.release(succeed);
+                    }
+                } else {
+                    do spawntask_later {
+                        let mut child_latch = child_latch.take();
+                        next(&mut *child_latch, copy suborders);
+                        rtdebug!("later releasing");
+                        child_latch.release(succeed);
+                    }
+                }
+            }
+        }
+
+        do run_in_newsched_task {
+            let mut latch = JoinLatch::new_root();
+            let orders = ~[ Order { // 0 0
+                immediate: true,
+                succeed: true,
+                orders: ~[ Order { // 1 0
+                    immediate: true,
+                    succeed: false,
+                    orders: ~[ Order { // 2 0
+                        immediate: false,
+                        succeed: false,
+                        orders: ~[ Order { // 3 0
+                            immediate: true,
+                            succeed: false,
+                            orders: ~[]
+                        }, Order { // 3 1
+                            immediate: false,
+                            succeed: false,
+                            orders: ~[]
+                        }]
+                    }]
+                }]
+            }];
+
+            next(&mut *latch, orders);
+            assert!(!latch.wait(true));
+        }
+    }
+}
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
index e6988c53888..6e0fbda5ec9 100644
--- a/src/libstd/rt/local.rs
+++ b/src/libstd/rt/local.rs
@@ -18,7 +18,7 @@ pub trait Local {
     fn put(value: ~Self);
     fn take() -> ~Self;
     fn exists() -> bool;
-    fn borrow(f: &fn(&mut Self));
+    fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
     unsafe fn unsafe_borrow() -> *mut Self;
     unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
 }
@@ -27,7 +27,20 @@ impl Local for Scheduler {
     fn put(value: ~Scheduler) { unsafe { local_ptr::put(value) }}
     fn take() -> ~Scheduler { unsafe { local_ptr::take() } }
     fn exists() -> bool { local_ptr::exists() }
-    fn borrow(f: &fn(&mut Scheduler)) { unsafe { local_ptr::borrow(f) } }
+    fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
+        let mut res: Option<T> = None;
+        let res_ptr: *mut Option<T> = &mut res;
+        unsafe {
+            do local_ptr::borrow |sched| {
+                let result = f(sched);
+                *res_ptr = Some(result);
+            }
+        }
+        match res {
+            Some(r) => { r }
+            None => abort!("function failed!")
+        }
+    }
     unsafe fn unsafe_borrow() -> *mut Scheduler { local_ptr::unsafe_borrow() }
     unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> { abort!("unimpl") }
 }
@@ -36,8 +49,8 @@ impl Local for Task {
     fn put(_value: ~Task) { abort!("unimpl") }
     fn take() -> ~Task { abort!("unimpl") }
     fn exists() -> bool { abort!("unimpl") }
-    fn borrow(f: &fn(&mut Task)) {
-        do Local::borrow::<Scheduler> |sched| {
+    fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
+        do Local::borrow::<Scheduler, T> |sched| {
             match sched.current_task {
                 Some(~ref mut task) => {
                     f(&mut *task.task)
@@ -74,7 +87,7 @@ impl Local for IoFactoryObject {
     fn put(_value: ~IoFactoryObject) { abort!("unimpl") }
     fn take() -> ~IoFactoryObject { abort!("unimpl") }
     fn exists() -> bool { abort!("unimpl") }
-    fn borrow(_f: &fn(&mut IoFactoryObject)) { abort!("unimpl") }
+    fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { abort!("unimpl") }
     unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
         let sched = Local::unsafe_borrow::<Scheduler>();
         let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
@@ -115,4 +128,16 @@ mod test {
         }
         let _scheduler: ~Scheduler = Local::take();
     }
+
+    #[test]
+    fn borrow_with_return() {
+        let scheduler = ~new_test_uv_sched();
+        Local::put(scheduler);
+        let res = do Local::borrow::<Scheduler,bool> |_sched| {
+            true
+        };
+        assert!(res)
+        let _scheduler: ~Scheduler = Local::take();
+    }
+
 }
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
index 80d797e8c65..0db903f81ee 100644
--- a/src/libstd/rt/local_ptr.rs
+++ b/src/libstd/rt/local_ptr.rs
@@ -79,7 +79,7 @@ pub unsafe fn borrow<T>(f: &fn(&mut T)) {
 
     // XXX: Need a different abstraction from 'finally' here to avoid unsafety
     let unsafe_ptr = cast::transmute_mut_region(&mut *value);
-    let value_cell = Cell(value);
+    let value_cell = Cell::new(value);
 
     do (|| {
         f(unsafe_ptr);
diff --git a/src/libstd/rt/message_queue.rs b/src/libstd/rt/message_queue.rs
index 21711bbe84c..734be808797 100644
--- a/src/libstd/rt/message_queue.rs
+++ b/src/libstd/rt/message_queue.rs
@@ -32,16 +32,20 @@ impl<T: Owned> MessageQueue<T> {
     }
 
     pub fn push(&mut self, value: T) {
-        let value = Cell(value);
-        self.queue.with(|q| q.push(value.take()) );
+        unsafe {
+            let value = Cell::new(value);
+            self.queue.with(|q| q.push(value.take()) );
+        }
     }
 
     pub fn pop(&mut self) -> Option<T> {
-        do self.queue.with |q| {
-            if !q.is_empty() {
-                Some(q.shift())
-            } else {
-                None
+        unsafe {
+            do self.queue.with |q| {
+                if !q.is_empty() {
+                    Some(q.shift())
+                } else {
+                    None
+                }
             }
         }
     }
diff --git a/src/libstd/rt/metrics.rs b/src/libstd/rt/metrics.rs
index 70e347fdfb6..b0c0fa5d708 100644
--- a/src/libstd/rt/metrics.rs
+++ b/src/libstd/rt/metrics.rs
@@ -34,7 +34,11 @@ pub struct SchedMetrics {
     // Message receives that do not block the receiver
     rendezvous_recvs: uint,
     // Message receives that block the receiver
-    non_rendezvous_recvs: uint
+    non_rendezvous_recvs: uint,
+    // JoinLatch releases that create tombstones
+    release_tombstone: uint,
+    // JoinLatch releases that do not create tombstones
+    release_no_tombstone: uint,
 }
 
 impl SchedMetrics {
@@ -51,7 +55,9 @@ impl SchedMetrics {
             rendezvous_sends: 0,
             non_rendezvous_sends: 0,
             rendezvous_recvs: 0,
-            non_rendezvous_recvs: 0
+            non_rendezvous_recvs: 0,
+            release_tombstone: 0,
+            release_no_tombstone: 0
         }
     }
 }
@@ -70,6 +76,8 @@ impl ToStr for SchedMetrics {
               non_rendezvous_sends: %u\n\
               rendezvous_recvs: %u\n\
               non_rendezvous_recvs: %u\n\
+              release_tombstone: %u\n\
+              release_no_tombstone: %u\n\
               ",
              self.turns,
              self.messages_received,
@@ -82,7 +90,9 @@ impl ToStr for SchedMetrics {
              self.rendezvous_sends,
              self.non_rendezvous_sends,
              self.rendezvous_recvs,
-             self.non_rendezvous_recvs
+             self.non_rendezvous_recvs,
+             self.release_tombstone,
+             self.release_no_tombstone
         )
     }
 }
\ No newline at end of file
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index caf3e15e535..1724361cabc 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -59,7 +59,8 @@ Several modules in `core` are clients of `rt`:
 #[deny(unused_mut)];
 #[deny(unused_variable)];
 
-use ptr::Ptr;
+use cell::Cell;
+use ptr::RawPtr;
 
 /// The global (exchange) heap.
 pub mod global_heap;
@@ -133,6 +134,9 @@ pub mod local_ptr;
 /// Bindings to pthread/windows thread-local storage.
 pub mod thread_local_storage;
 
+/// A concurrent data structure with which parent tasks wait on child tasks.
+pub mod join_latch;
+
 pub mod metrics;
 
 
@@ -164,7 +168,7 @@ pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {
     let sleepers = SleeperList::new();
     let mut sched = ~Scheduler::new(loop_, work_queue, sleepers);
     sched.no_sleep = true;
-    let main_task = ~Coroutine::new(&mut sched.stack_pool, main);
+    let main_task = ~Coroutine::new_root(&mut sched.stack_pool, main);
 
     sched.enqueue_task(main_task);
     sched.run();
@@ -207,8 +211,8 @@ pub fn context() -> RuntimeContext {
         return OldTaskContext;
     } else {
         if Local::exists::<Scheduler>() {
-            let context = ::cell::empty_cell();
-            do Local::borrow::<Scheduler> |sched| {
+            let context = Cell::new_empty();
+            do Local::borrow::<Scheduler, ()> |sched| {
                 if sched.in_task_context() {
                     context.put_back(TaskContext);
                 } else {
@@ -238,7 +242,7 @@ fn test_context() {
     do run_in_bare_thread {
         assert_eq!(context(), GlobalContext);
         let mut sched = ~new_test_uv_sched();
-        let task = ~do Coroutine::new(&mut sched.stack_pool) {
+        let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
             assert_eq!(context(), TaskContext);
             let sched = Local::take::<Scheduler>();
             do sched.deschedule_running_task_and_then() |sched, task| {
diff --git a/src/libstd/rt/rc.rs b/src/libstd/rt/rc.rs
index 1c0c8c14fdf..2977d081508 100644
--- a/src/libstd/rt/rc.rs
+++ b/src/libstd/rt/rc.rs
@@ -78,7 +78,7 @@ impl<T> Drop for RC<T> {
         assert!(self.refcount() > 0);
 
         unsafe {
-            // XXX: Mutable finalizer
+            // FIXME(#4330) Need self by value to get mutability.
             let this: &mut RC<T> = cast::transmute_mut(self);
 
             match *this.get_mut_state() {
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index df231f6d88a..be57247d514 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -26,6 +26,11 @@ use rt::local::Local;
 use rt::rtio::RemoteCallback;
 use rt::metrics::SchedMetrics;
 
+//use to_str::ToStr;
+
+/// To allow for using pointers as scheduler ids
+use borrow::{to_uint};
+
 /// The Scheduler is responsible for coordinating execution of Coroutines
 /// on a single thread. When the scheduler is running it is owned by
 /// thread local storage and the running task is owned by the
@@ -65,12 +70,15 @@ pub struct Scheduler {
     /// An action performed after a context switch on behalf of the
     /// code running before the context switch
     priv cleanup_job: Option<CleanupJob>,
-    metrics: SchedMetrics
+    metrics: SchedMetrics,
+    /// Should this scheduler run any task, or only pinned tasks?
+    run_anything: bool
 }
 
 pub struct SchedHandle {
     priv remote: ~RemoteCallbackObject,
-    priv queue: MessageQueue<SchedMessage>
+    priv queue: MessageQueue<SchedMessage>,
+    sched_id: uint
 }
 
 pub struct Coroutine {
@@ -81,12 +89,20 @@ pub struct Coroutine {
     /// the task is dead
     priv saved_context: Context,
     /// The heap, GC, unwinding, local storage, logging
-    task: ~Task
+    task: ~Task,
+}
+
+// A scheduler home is either a handle to the home scheduler, or an
+// explicit "AnySched".
+pub enum SchedHome {
+    AnySched,
+    Sched(SchedHandle)
 }
 
 pub enum SchedMessage {
     Wake,
-    Shutdown
+    Shutdown,
+    PinnedTask(~Coroutine)
 }
 
 enum CleanupJob {
@@ -94,13 +110,24 @@ enum CleanupJob {
     GiveTask(~Coroutine, UnsafeTaskReceiver)
 }
 
-pub impl Scheduler {
+impl Scheduler {
+    pub fn in_task_context(&self) -> bool { self.current_task.is_some() }
+
+    pub fn sched_id(&self) -> uint { to_uint(self) }
+
+    pub fn new(event_loop: ~EventLoopObject,
+               work_queue: WorkQueue<~Coroutine>,
+               sleeper_list: SleeperList)
+        -> Scheduler {
+
+        Scheduler::new_special(event_loop, work_queue, sleeper_list, true)
 
-    fn in_task_context(&self) -> bool { self.current_task.is_some() }
+    }
 
-    fn new(event_loop: ~EventLoopObject,
-           work_queue: WorkQueue<~Coroutine>,
-           sleeper_list: SleeperList)
+    pub fn new_special(event_loop: ~EventLoopObject,
+                       work_queue: WorkQueue<~Coroutine>,
+                       sleeper_list: SleeperList,
+                       run_anything: bool)
         -> Scheduler {
 
         // Lazily initialize the runtime TLS key
@@ -117,7 +144,8 @@ pub impl Scheduler {
             saved_context: Context::empty(),
             current_task: None,
             cleanup_job: None,
-            metrics: SchedMetrics::new()
+            metrics: SchedMetrics::new(),
+            run_anything: run_anything
         }
     }
 
@@ -125,7 +153,7 @@ pub impl Scheduler {
     // the scheduler itself doesn't have to call event_loop.run.
     // That will be important for embedding the runtime into external
     // event loops.
-    fn run(~self) -> ~Scheduler {
+    pub fn run(~self) -> ~Scheduler {
         assert!(!self.in_task_context());
 
         let mut self_sched = self;
@@ -147,11 +175,15 @@ pub impl Scheduler {
             (*event_loop).run();
         }
 
+        rtdebug!("run taking sched");
         let sched = Local::take::<Scheduler>();
         // XXX: Reenable this once we're using a per-task queue. With a shared
         // queue this is not true
         //assert!(sched.work_queue.is_empty());
-        rtdebug!("scheduler metrics: %s\n", sched.metrics.to_str());
+        rtdebug!("scheduler metrics: %s\n", {
+            use to_str::ToStr;
+            sched.metrics.to_str()
+        });
         return sched;
     }
 
@@ -167,6 +199,7 @@ pub impl Scheduler {
         if sched.interpret_message_queue() {
             // We performed a scheduling action. There may be other work
             // to do yet, so let's try again later.
+            rtdebug!("run_sched_once, interpret_message_queue taking sched");
             let mut sched = Local::take::<Scheduler>();
             sched.metrics.messages_received += 1;
             sched.event_loop.callback(Scheduler::run_sched_once);
@@ -175,6 +208,7 @@ pub impl Scheduler {
         }
 
         // Now, look in the work queue for tasks to run
+        rtdebug!("run_sched_once taking");
         let sched = Local::take::<Scheduler>();
         if sched.resume_task_from_queue() {
             // We performed a scheduling action. There may be other work
@@ -204,38 +238,60 @@ pub impl Scheduler {
         Local::put(sched);
     }
 
-    fn make_handle(&mut self) -> SchedHandle {
+    pub fn make_handle(&mut self) -> SchedHandle {
         let remote = self.event_loop.remote_callback(Scheduler::run_sched_once);
 
         return SchedHandle {
             remote: remote,
-            queue: self.message_queue.clone()
+            queue: self.message_queue.clone(),
+            sched_id: self.sched_id()
         };
     }
 
     /// Schedule a task to be executed later.
     ///
-    /// Pushes the task onto the work stealing queue and tells the event loop
-    /// to run it later. Always use this instead of pushing to the work queue
-    /// directly.
-    fn enqueue_task(&mut self, task: ~Coroutine) {
-        self.work_queue.push(task);
-        self.event_loop.callback(Scheduler::run_sched_once);
-
-        // We've made work available. Notify a sleeping scheduler.
-        // XXX: perf. Check for a sleeper without synchronizing memory.
-        // It's not critical that we always find it.
-        // XXX: perf. If there's a sleeper then we might as well just send
-        // it the task directly instead of pushing it to the
-        // queue. That is essentially the intent here and it is less
-        // work.
-        match self.sleeper_list.pop() {
+    /// Pushes the task onto the work stealing queue and tells the
+    /// event loop to run it later. Always use this instead of pushing
+    /// to the work queue directly.
+    pub fn enqueue_task(&mut self, task: ~Coroutine) {
+
+        // We don't want to queue tasks that belong on other threads,
+        // so we send them home at enqueue time.
+
+        // The borrow checker doesn't like our disassembly of the
+        // Coroutine struct and partial use and mutation of the
+        // fields. So completely disassemble here and stop using?
+
+        // XXX perf: I think we might be able to shuffle this code to
+        // only destruct when we need to.
+
+        rtdebug!("a task was queued on: %u", self.sched_id());
+
+        let this = self;
+
+        // We push the task onto our local queue clone.
+        this.work_queue.push(task);
+        this.event_loop.callback(Scheduler::run_sched_once);
+
+        // We've made work available. Notify a
+        // sleeping scheduler.
+
+        // XXX: perf. Check for a sleeper without
+        // synchronizing memory.  It's not critical
+        // that we always find it.
+
+        // XXX: perf. If there's a sleeper then we
+        // might as well just send it the task
+        // directly instead of pushing it to the
+        // queue. That is essentially the intent here
+        // and it is less work.
+        match this.sleeper_list.pop() {
             Some(handle) => {
                 let mut handle = handle;
                 handle.send(Wake)
             }
-            None => (/* pass */)
-        }
+            None => { (/* pass */) }
+        };
     }
 
     // * Scheduler-context operations
@@ -247,6 +303,15 @@ pub impl Scheduler {
 
         let mut this = self;
         match this.message_queue.pop() {
+            Some(PinnedTask(task)) => {
+                rtdebug!("recv BiasedTask message in sched: %u",
+                         this.sched_id());
+                let mut task = task;
+                task.task.home = Some(Sched(this.make_handle()));
+                this.resume_task_immediately(task);
+                return true;
+            }
+
             Some(Wake) => {
                 rtdebug!("recv Wake message");
                 this.sleepy = false;
@@ -256,8 +321,9 @@ pub impl Scheduler {
             Some(Shutdown) => {
                 rtdebug!("recv Shutdown message");
                 if this.sleepy {
-                    // There may be an outstanding handle on the sleeper list.
-                    // Pop them all to make sure that's not the case.
+                    // There may be an outstanding handle on the
+                    // sleeper list.  Pop them all to make sure that's
+                    // not the case.
                     loop {
                         match this.sleeper_list.pop() {
                             Some(handle) => {
@@ -268,8 +334,8 @@ pub impl Scheduler {
                         }
                     }
                 }
-                // No more sleeping. After there are no outstanding event loop
-                // references we will shut down.
+                // No more sleeping. After there are no outstanding
+                // event loop references we will shut down.
                 this.no_sleep = true;
                 this.sleepy = false;
                 Local::put(this);
@@ -282,23 +348,93 @@ pub impl Scheduler {
         }
     }
 
+    /// Given an input Coroutine sends it back to its home scheduler.
+    fn send_task_home(task: ~Coroutine) {
+        let mut task = task;
+        let mut home = task.task.home.swap_unwrap();
+        match home {
+            Sched(ref mut home_handle) => {
+                home_handle.send(PinnedTask(task));
+            }
+            AnySched => {
+                abort!("error: cannot send anysched task home");
+            }
+        }
+    }
+
+    // Resume a task from the queue - but also take into account that
+    // it might not belong here.
     fn resume_task_from_queue(~self) -> bool {
         assert!(!self.in_task_context());
 
         rtdebug!("looking in work queue for task to schedule");
-
         let mut this = self;
+
+        // The borrow checker imposes the possibly absurd requirement
+        // that we split this into two match expressions. This is due
+        // to the inspection of the internal bits of task, as that
+        // can't be in scope when we act on task.
         match this.work_queue.pop() {
             Some(task) => {
-                rtdebug!("resuming task from work queue");
-                this.resume_task_immediately(task);
-                return true;
+                let action_id = {
+                    let home = &task.task.home;
+                    match home {
+                        &Some(Sched(ref home_handle))
+                        if home_handle.sched_id != this.sched_id() => {
+                            0
+                        }
+                        &Some(AnySched) if this.run_anything => {
+                            1
+                        }
+                        &Some(AnySched) => {
+                            2
+                        }
+                        &Some(Sched(_)) => {
+                            3
+                        }
+                        &None => {
+                            4
+                        }
+                    }
+                };
+
+                match action_id {
+                    0 => {
+                        rtdebug!("sending task home");
+                        Scheduler::send_task_home(task);
+                        Local::put(this);
+                        return false;
+                    }
+                    1 => {
+                        rtdebug!("resuming now");
+                        this.resume_task_immediately(task);
+                        return true;
+                    }
+                    2 => {
+                        rtdebug!("re-queueing")
+                        this.enqueue_task(task);
+                        Local::put(this);
+                        return false;
+                    }
+                    3 => {
+                        rtdebug!("resuming now");
+                        this.resume_task_immediately(task);
+                        return true;
+                    }
+                    4 => {
+                        abort!("task home was None!");
+                    }
+                    _ => {
+                        abort!("literally, you should not be here");
+                    }
+                }
             }
+
             None => {
-                rtdebug!("no tasks in queue");
-                Local::put(this);
-                return false;
-            }
+               rtdebug!("no tasks in queue");
+               Local::put(this);
+               return false;
+           }
         }
     }
 
@@ -306,40 +442,51 @@ pub impl Scheduler {
 
     /// Called by a running task to end execution, after which it will
     /// be recycled by the scheduler for reuse in a new task.
-    fn terminate_current_task(~self) {
+    pub fn terminate_current_task(~self) {
         assert!(self.in_task_context());
 
         rtdebug!("ending running task");
 
         do self.deschedule_running_task_and_then |sched, dead_task| {
-            let dead_task = Cell(dead_task);
+            let dead_task = Cell::new(dead_task);
             dead_task.take().recycle(&mut sched.stack_pool);
         }
 
         abort!("control reached end of task");
     }
 
-    fn schedule_new_task(~self, task: ~Coroutine) {
+    pub fn schedule_task(~self, task: ~Coroutine) {
         assert!(self.in_task_context());
 
-        do self.switch_running_tasks_and_then(task) |sched, last_task| {
-            let last_task = Cell(last_task);
-            sched.enqueue_task(last_task.take());
-        }
-    }
+        // is the task home?
+        let is_home = task.is_home_no_tls(&self);
 
-    fn schedule_task(~self, task: ~Coroutine) {
-        assert!(self.in_task_context());
+        // does the task have a home?
+        let homed = task.homed();
+
+        let mut this = self;
 
-        do self.switch_running_tasks_and_then(task) |sched, last_task| {
-            let last_task = Cell(last_task);
-            sched.enqueue_task(last_task.take());
+        if is_home || (!homed && this.run_anything) {
+            // here we know we are home, execute now OR we know we
+            // aren't homed, and that this sched doesn't care
+            do this.switch_running_tasks_and_then(task) |sched, last_task| {
+                let last_task = Cell::new(last_task);
+                sched.enqueue_task(last_task.take());
+            }
+        } else if !homed && !this.run_anything {
+            // the task isn't homed, but it can't be run here
+            this.enqueue_task(task);
+            Local::put(this);
+        } else {
+            // task isn't home, so don't run it here, send it home
+            Scheduler::send_task_home(task);
+            Local::put(this);
         }
     }
 
     // Core scheduling ops
 
-    fn resume_task_immediately(~self, task: ~Coroutine) {
+    pub fn resume_task_immediately(~self, task: ~Coroutine) {
         let mut this = self;
         assert!(!this.in_task_context());
 
@@ -382,7 +529,7 @@ pub impl Scheduler {
     /// This passes a Scheduler pointer to the fn after the context switch
     /// in order to prevent that fn from performing further scheduling operations.
     /// Doing further scheduling could easily result in infinite recursion.
-    fn deschedule_running_task_and_then(~self, f: &fn(&mut Scheduler, ~Coroutine)) {
+    pub fn deschedule_running_task_and_then(~self, f: &fn(&mut Scheduler, ~Coroutine)) {
         let mut this = self;
         assert!(this.in_task_context());
 
@@ -414,8 +561,8 @@ pub impl Scheduler {
     /// Switch directly to another task, without going through the scheduler.
     /// You would want to think hard about doing this, e.g. if there are
     /// pending I/O events it would be a bad idea.
-    fn switch_running_tasks_and_then(~self, next_task: ~Coroutine,
-                                     f: &fn(&mut Scheduler, ~Coroutine)) {
+    pub fn switch_running_tasks_and_then(~self, next_task: ~Coroutine,
+                                         f: &fn(&mut Scheduler, ~Coroutine)) {
         let mut this = self;
         assert!(this.in_task_context());
 
@@ -450,12 +597,12 @@ pub impl Scheduler {
 
     // * Other stuff
 
-    fn enqueue_cleanup_job(&mut self, job: CleanupJob) {
+    pub fn enqueue_cleanup_job(&mut self, job: CleanupJob) {
         assert!(self.cleanup_job.is_none());
         self.cleanup_job = Some(job);
     }
 
-    fn run_cleanup_job(&mut self) {
+    pub fn run_cleanup_job(&mut self) {
         rtdebug!("running cleanup job");
 
         assert!(self.cleanup_job.is_some());
@@ -476,9 +623,9 @@ pub impl Scheduler {
     /// callers should first arrange for that task to be located in the
     /// Scheduler's current_task slot and set up the
     /// post-context-switch cleanup job.
-    fn get_contexts<'a>(&'a mut self) -> (&'a mut Context,
-                                          Option<&'a mut Context>,
-                                          Option<&'a mut Context>) {
+    pub fn get_contexts<'a>(&'a mut self) -> (&'a mut Context,
+                                              Option<&'a mut Context>,
+                                              Option<&'a mut Context>) {
         let last_task = match self.cleanup_job {
             Some(GiveTask(~ref task, _)) => {
                 Some(task)
@@ -514,31 +661,112 @@ impl SchedHandle {
     }
 }
 
-pub impl Coroutine {
-    fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
-        Coroutine::with_task(stack_pool, ~Task::new(), start)
+impl Coroutine {
+
+    /// This function checks that a coroutine is running "home".
+    pub fn is_home(&self) -> bool {
+        rtdebug!("checking if coroutine is home");
+        do Local::borrow::<Scheduler,bool> |sched| {
+            match self.task.home {
+                Some(AnySched) => { false }
+                Some(Sched(SchedHandle { sched_id: ref id, _ })) => {
+                    *id == sched.sched_id()
+                }
+                None => { abort!("error: homeless task!"); }
+            }
+        }
     }
 
-    fn with_task(stack_pool: &mut StackPool,
-                  task: ~Task,
-                  start: ~fn()) -> Coroutine {
+    /// Without access to self, but with access to the "expected home
+    /// id", see if we are home.
+    fn is_home_using_id(id: uint) -> bool {
+        rtdebug!("checking if coroutine is home using id");
+        do Local::borrow::<Scheduler,bool> |sched| {
+            if sched.sched_id() == id {
+                true
+            } else {
+                false
+            }
+        }
+    }
 
-        static MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack
+    /// Check if this coroutine has a home
+    fn homed(&self) -> bool {
+        rtdebug!("checking if this coroutine has a home");
+        match self.task.home {
+            Some(AnySched) => { false }
+            Some(Sched(_)) => { true }
+            None => { abort!("error: homeless task!");
+                    }
+        }
+    }
+
+    /// A version of is_home that does not need to use TLS, it instead
+    /// takes local scheduler as a parameter.
+    fn is_home_no_tls(&self, sched: &~Scheduler) -> bool {
+        rtdebug!("checking if coroutine is home without tls");
+        match self.task.home {
+            Some(AnySched) => { true }
+            Some(Sched(SchedHandle { sched_id: ref id, _})) => {
+                *id == sched.sched_id()
+            }
+            None => { abort!("error: homeless task!"); }
+        }
+    }
+
+    /// Check TLS for the scheduler to see if we are on a special
+    /// scheduler.
+    pub fn on_special() -> bool {
+        rtdebug!("checking if coroutine is executing on special sched");
+        do Local::borrow::<Scheduler,bool>() |sched| {
+            !sched.run_anything
+        }
+    }
+
+    // Created new variants of "new" that takes a home scheduler
+    // parameter. The original with_task now calls with_task_homed
+    // using the AnySched paramter.
+
+    pub fn new_homed(stack_pool: &mut StackPool, home: SchedHome, start: ~fn()) -> Coroutine {
+        Coroutine::with_task_homed(stack_pool, ~Task::new_root(), start, home)
+    }
+
+    pub fn new_root(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
+        Coroutine::with_task(stack_pool, ~Task::new_root(), start)
+    }
+
+    pub fn with_task_homed(stack_pool: &mut StackPool,
+                           task: ~Task,
+                           start: ~fn(),
+                           home: SchedHome) -> Coroutine {
+
+        static MIN_STACK_SIZE: uint = 1000000; // XXX: Too much stack
 
         let start = Coroutine::build_start_wrapper(start);
         let mut stack = stack_pool.take_segment(MIN_STACK_SIZE);
         // NB: Context holds a pointer to that ~fn
         let initial_context = Context::new(start, &mut stack);
-        return Coroutine {
+        let mut crt = Coroutine {
             current_stack_segment: stack,
             saved_context: initial_context,
-            task: task
+            task: task,
         };
+        crt.task.home = Some(home);
+        return crt;
     }
 
-    priv fn build_start_wrapper(start: ~fn()) -> ~fn() {
+    pub fn with_task(stack_pool: &mut StackPool,
+                 task: ~Task,
+                 start: ~fn()) -> Coroutine {
+        Coroutine::with_task_homed(stack_pool,
+                                   task,
+                                   start,
+                                   AnySched)
+    }
+
+    fn build_start_wrapper(start: ~fn()) -> ~fn() {
         // XXX: The old code didn't have this extra allocation
-        let start_cell = Cell(start);
+        let start_cell = Cell::new(start);
         let wrapper: ~fn() = || {
             // This is the first code to execute after the initial
             // context switch to the task. The previous context may
@@ -549,17 +777,20 @@ pub impl Coroutine {
 
                 let sched = Local::unsafe_borrow::<Scheduler>();
                 let task = (*sched).current_task.get_mut_ref();
-                // FIXME #6141: shouldn't neet to put `start()` in another closure
-                let start_cell = Cell(start_cell.take());
+                // FIXME #6141: shouldn't neet to put `start()` in
+                // another closure
+                let start_cell = Cell::new(start_cell.take());
                 do task.task.run {
-                    // N.B. Removing `start` from the start wrapper closure
-                    // by emptying a cell is critical for correctness. The ~Task
-                    // pointer, and in turn the closure used to initialize the first
-                    // call frame, is destroyed in scheduler context, not task context.
-                    // So any captured closures must not contain user-definable dtors
-                    // that expect to be in task context. By moving `start` out of
-                    // the closure, all the user code goes out of scope while
-                    // the task is still running.
+                    // N.B. Removing `start` from the start wrapper
+                    // closure by emptying a cell is critical for
+                    // correctness. The ~Task pointer, and in turn the
+                    // closure used to initialize the first call
+                    // frame, is destroyed in scheduler context, not
+                    // task context.  So any captured closures must
+                    // not contain user-definable dtors that expect to
+                    // be in task context. By moving `start` out of
+                    // the closure, all the user code goes out of
+                    // scope while the task is still running.
                     let start = start_cell.take();
                     start();
                 };
@@ -572,7 +803,7 @@ pub impl Coroutine {
     }
 
     /// Destroy the task and try to reuse its components
-    fn recycle(~self, stack_pool: &mut StackPool) {
+    pub fn recycle(~self, stack_pool: &mut StackPool) {
         match self {
             ~Coroutine {current_stack_segment, _} => {
                 stack_pool.give_segment(current_stack_segment);
@@ -597,12 +828,312 @@ impl ClosureConverter for UnsafeTaskReceiver {
 mod test {
     use int;
     use cell::Cell;
+    use iterator::IteratorUtil;
     use unstable::run_in_bare_thread;
     use task::spawn;
     use rt::local::Local;
     use rt::test::*;
     use super::*;
     use rt::thread::Thread;
+    use ptr::to_uint;
+    use vec::MutableVector;
+
+    // Confirm that a sched_id actually is the uint form of the
+    // pointer to the scheduler struct.
+
+    #[test]
+    fn simple_sched_id_test() {
+        do run_in_bare_thread {
+            let sched = ~new_test_uv_sched();
+            assert!(to_uint(sched) == sched.sched_id());
+        }
+    }
+
+    // Compare two scheduler ids that are different, this should never
+    // fail but may catch a mistake someday.
+
+    #[test]
+    fn compare_sched_id_test() {
+        do run_in_bare_thread {
+            let sched_one = ~new_test_uv_sched();
+            let sched_two = ~new_test_uv_sched();
+            assert!(sched_one.sched_id() != sched_two.sched_id());
+        }
+    }
+
+    // A simple test to check if a homed task run on a single
+    // scheduler ends up executing while home.
+
+    #[test]
+    fn test_home_sched() {
+        do run_in_bare_thread {
+            let mut task_ran = false;
+            let task_ran_ptr: *mut bool = &mut task_ran;
+            let mut sched = ~new_test_uv_sched();
+
+            let sched_handle = sched.make_handle();
+            let sched_id = sched.sched_id();
+
+            let task = ~do Coroutine::new_homed(&mut sched.stack_pool,
+                                                Sched(sched_handle)) {
+                unsafe { *task_ran_ptr = true };
+                let sched = Local::take::<Scheduler>();
+                assert!(sched.sched_id() == sched_id);
+                Local::put::<Scheduler>(sched);
+            };
+            sched.enqueue_task(task);
+            sched.run();
+            assert!(task_ran);
+        }
+    }
+
+    // A test for each state of schedule_task
+
+    #[test]
+    fn test_schedule_home_states() {
+
+        use rt::uv::uvio::UvEventLoop;
+        use rt::sched::Shutdown;
+        use rt::sleeper_list::SleeperList;
+        use rt::work_queue::WorkQueue;
+
+        do run_in_bare_thread {
+//            let nthreads = 2;
+
+            let sleepers = SleeperList::new();
+            let work_queue = WorkQueue::new();
+
+            // our normal scheduler
+            let mut normal_sched = ~Scheduler::new(
+                ~UvEventLoop::new(),
+                work_queue.clone(),
+                sleepers.clone());
+
+            let normal_handle = Cell::new(normal_sched.make_handle());
+
+            // our special scheduler
+            let mut special_sched = ~Scheduler::new_special(
+                ~UvEventLoop::new(),
+                work_queue.clone(),
+                sleepers.clone(),
+                true);
+
+            let special_handle = Cell::new(special_sched.make_handle());
+            let special_handle2 = Cell::new(special_sched.make_handle());
+            let special_id = special_sched.sched_id();
+            let t1_handle = special_sched.make_handle();
+            let t4_handle = special_sched.make_handle();
+
+            let t1f = ~do Coroutine::new_homed(&mut special_sched.stack_pool,
+                                            Sched(t1_handle)) {
+                let is_home = Coroutine::is_home_using_id(special_id);
+                rtdebug!("t1 should be home: %b", is_home);
+                assert!(is_home);
+            };
+            let t1f = Cell::new(t1f);
+
+            let t2f = ~do Coroutine::new_root(&mut normal_sched.stack_pool) {
+                let on_special = Coroutine::on_special();
+                rtdebug!("t2 should not be on special: %b", on_special);
+                assert!(!on_special);
+            };
+            let t2f = Cell::new(t2f);
+
+            let t3f = ~do Coroutine::new_root(&mut normal_sched.stack_pool) {
+                // not on special
+                let on_special = Coroutine::on_special();
+                rtdebug!("t3 should not be on special: %b", on_special);
+                assert!(!on_special);
+            };
+            let t3f = Cell::new(t3f);
+
+            let t4f = ~do Coroutine::new_homed(&mut special_sched.stack_pool,
+                                            Sched(t4_handle)) {
+                // is home
+                let home = Coroutine::is_home_using_id(special_id);
+                rtdebug!("t4 should be home: %b", home);
+                assert!(home);
+            };
+            let t4f = Cell::new(t4f);
+
+            // we have four tests, make them as closures
+            let t1: ~fn() = || {
+                // task is home on special
+                let task = t1f.take();
+                let sched = Local::take::<Scheduler>();
+                sched.schedule_task(task);
+            };
+            let t2: ~fn() = || {
+                // not homed, task doesn't care
+                let task = t2f.take();
+                let sched = Local::take::<Scheduler>();
+                sched.schedule_task(task);
+            };
+            let t3: ~fn() = || {
+                // task not homed, must leave
+                let task = t3f.take();
+                let sched = Local::take::<Scheduler>();
+                sched.schedule_task(task);
+            };
+            let t4: ~fn() = || {
+                // task not home, send home
+                let task = t4f.take();
+                let sched = Local::take::<Scheduler>();
+                sched.schedule_task(task);
+            };
+
+            let t1 = Cell::new(t1);
+            let t2 = Cell::new(t2);
+            let t3 = Cell::new(t3);
+            let t4 = Cell::new(t4);
+
+            // build a main task that runs our four tests
+            let main_task = ~do Coroutine::new_root(&mut normal_sched.stack_pool) {
+                // the two tasks that require a normal start location
+                t2.take()();
+                t4.take()();
+                normal_handle.take().send(Shutdown);
+                special_handle.take().send(Shutdown);
+            };
+
+            // task to run the two "special start" tests
+            let special_task = ~do Coroutine::new_homed(
+                &mut special_sched.stack_pool,
+                Sched(special_handle2.take())) {
+                t1.take()();
+                t3.take()();
+            };
+
+            // enqueue the main tasks
+            normal_sched.enqueue_task(special_task);
+            normal_sched.enqueue_task(main_task);
+
+            let nsched_cell = Cell::new(normal_sched);
+            let normal_thread = do Thread::start {
+                let sched = nsched_cell.take();
+                sched.run();
+            };
+
+            let ssched_cell = Cell::new(special_sched);
+            let special_thread = do Thread::start {
+                let sched = ssched_cell.take();
+                sched.run();
+            };
+
+            // wait for the end
+            let _thread1 = normal_thread;
+            let _thread2 = special_thread;
+
+        }
+    }
+
+    // The following test is a bit of a mess, but it trys to do
+    // something tricky so I'm not sure how to get around this in the
+    // short term.
+
+    // A number of schedulers are created, and then a task is created
+    // and assigned a home scheduler. It is then "started" on a
+    // different scheduler. The scheduler it is started on should
+    // observe that the task is not home, and send it home.
+
+    // This test is light in that it does very little.
+
+    #[test]
+    fn test_transfer_task_home() {
+
+        use rt::uv::uvio::UvEventLoop;
+        use rt::sched::Shutdown;
+        use rt::sleeper_list::SleeperList;
+        use rt::work_queue::WorkQueue;
+        use uint;
+        use container::Container;
+        use vec::OwnedVector;
+
+        do run_in_bare_thread {
+
+            static N: uint = 8;
+
+            let sleepers = SleeperList::new();
+            let work_queue = WorkQueue::new();
+
+            let mut handles = ~[];
+            let mut scheds = ~[];
+
+            for uint::range(0, N) |_| {
+                let loop_ = ~UvEventLoop::new();
+                let mut sched = ~Scheduler::new(loop_,
+                                                work_queue.clone(),
+                                                sleepers.clone());
+                let handle = sched.make_handle();
+                rtdebug!("sched id: %u", handle.sched_id);
+                handles.push(handle);
+                scheds.push(sched);
+            };
+
+            let handles = Cell::new(handles);
+
+            let home_handle = scheds[6].make_handle();
+            let home_id = home_handle.sched_id;
+            let home = Sched(home_handle);
+
+            let main_task = ~do Coroutine::new_homed(&mut scheds[1].stack_pool, home) {
+
+                // Here we check if the task is running on its home.
+                let sched = Local::take::<Scheduler>();
+                rtdebug!("run location scheduler id: %u, home: %u",
+                         sched.sched_id(),
+                         home_id);
+                assert!(sched.sched_id() == home_id);
+                Local::put::<Scheduler>(sched);
+
+                let mut handles = handles.take();
+                for handles.mut_iter().advance |handle| {
+                    handle.send(Shutdown);
+                }
+            };
+
+            scheds[0].enqueue_task(main_task);
+
+            let mut threads = ~[];
+
+            while !scheds.is_empty() {
+                let sched = scheds.pop();
+                let sched_cell = Cell::new(sched);
+                let thread = do Thread::start {
+                    let sched = sched_cell.take();
+                    sched.run();
+                };
+                threads.push(thread);
+            }
+
+            let _threads = threads;
+        }
+    }
+
+    // Do it a lot
+
+    #[test]
+    fn test_stress_schedule_task_states() {
+        let n = stress_factor() * 120;
+        for int::range(0,n as int) |_| {
+            test_schedule_home_states();
+        }
+    }
+
+    // The goal is that this is the high-stress test for making sure
+    // homing is working. It allocates RUST_RT_STRESS tasks that
+    // do nothing but assert that they are home at execution
+    // time. These tasks are queued to random schedulers, so sometimes
+    // they are home and sometimes not. It also runs RUST_RT_STRESS
+    // times.
+
+    #[test]
+    fn test_stress_homed_tasks() {
+        let n = stress_factor();
+        for int::range(0,n as int) |_| {
+            run_in_mt_newsched_task_random_homed();
+        }
+    }
 
     #[test]
     fn test_simple_scheduling() {
@@ -611,7 +1142,7 @@ mod test {
             let task_ran_ptr: *mut bool = &mut task_ran;
 
             let mut sched = ~new_test_uv_sched();
-            let task = ~do Coroutine::new(&mut sched.stack_pool) {
+            let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
                 unsafe { *task_ran_ptr = true; }
             };
             sched.enqueue_task(task);
@@ -629,7 +1160,7 @@ mod test {
 
             let mut sched = ~new_test_uv_sched();
             for int::range(0, total) |_| {
-                let task = ~do Coroutine::new(&mut sched.stack_pool) {
+                let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
                     unsafe { *task_count_ptr = *task_count_ptr + 1; }
                 };
                 sched.enqueue_task(task);
@@ -646,15 +1177,15 @@ mod test {
             let count_ptr: *mut int = &mut count;
 
             let mut sched = ~new_test_uv_sched();
-            let task1 = ~do Coroutine::new(&mut sched.stack_pool) {
+            let task1 = ~do Coroutine::new_root(&mut sched.stack_pool) {
                 unsafe { *count_ptr = *count_ptr + 1; }
                 let mut sched = Local::take::<Scheduler>();
-                let task2 = ~do Coroutine::new(&mut sched.stack_pool) {
+                let task2 = ~do Coroutine::new_root(&mut sched.stack_pool) {
                     unsafe { *count_ptr = *count_ptr + 1; }
                 };
                 // Context switch directly to the new task
                 do sched.switch_running_tasks_and_then(task2) |sched, task1| {
-                    let task1 = Cell(task1);
+                    let task1 = Cell::new(task1);
                     sched.enqueue_task(task1.take());
                 }
                 unsafe { *count_ptr = *count_ptr + 1; }
@@ -674,7 +1205,7 @@ mod test {
 
             let mut sched = ~new_test_uv_sched();
 
-            let start_task = ~do Coroutine::new(&mut sched.stack_pool) {
+            let start_task = ~do Coroutine::new_root(&mut sched.stack_pool) {
                 run_task(count_ptr);
             };
             sched.enqueue_task(start_task);
@@ -683,8 +1214,8 @@ mod test {
             assert_eq!(count, MAX);
 
             fn run_task(count_ptr: *mut int) {
-                do Local::borrow::<Scheduler> |sched| {
-                    let task = ~do Coroutine::new(&mut sched.stack_pool) {
+                do Local::borrow::<Scheduler, ()> |sched| {
+                    let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
                         unsafe {
                             *count_ptr = *count_ptr + 1;
                             if *count_ptr != MAX {
@@ -702,11 +1233,11 @@ mod test {
     fn test_block_task() {
         do run_in_bare_thread {
             let mut sched = ~new_test_uv_sched();
-            let task = ~do Coroutine::new(&mut sched.stack_pool) {
+            let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
                 let sched = Local::take::<Scheduler>();
                 assert!(sched.in_task_context());
                 do sched.deschedule_running_task_and_then() |sched, task| {
-                    let task = Cell(task);
+                    let task = Cell::new(task);
                     assert!(!sched.in_task_context());
                     sched.enqueue_task(task.take());
                 }
@@ -726,7 +1257,7 @@ mod test {
             do spawn {
                 let sched = Local::take::<Scheduler>();
                 do sched.deschedule_running_task_and_then |sched, task| {
-                    let task = Cell(task);
+                    let task = Cell::new(task);
                     do sched.event_loop.callback_ms(10) {
                         rtdebug!("in callback");
                         let mut sched = Local::take::<Scheduler>();
@@ -744,31 +1275,31 @@ mod test {
 
         do run_in_bare_thread {
             let (port, chan) = oneshot::<()>();
-            let port_cell = Cell(port);
-            let chan_cell = Cell(chan);
+            let port_cell = Cell::new(port);
+            let chan_cell = Cell::new(chan);
             let mut sched1 = ~new_test_uv_sched();
             let handle1 = sched1.make_handle();
-            let handle1_cell = Cell(handle1);
-            let task1 = ~do Coroutine::new(&mut sched1.stack_pool) {
+            let handle1_cell = Cell::new(handle1);
+            let task1 = ~do Coroutine::new_root(&mut sched1.stack_pool) {
                 chan_cell.take().send(());
             };
             sched1.enqueue_task(task1);
 
             let mut sched2 = ~new_test_uv_sched();
-            let task2 = ~do Coroutine::new(&mut sched2.stack_pool) {
+            let task2 = ~do Coroutine::new_root(&mut sched2.stack_pool) {
                 port_cell.take().recv();
                 // Release the other scheduler's handle so it can exit
                 handle1_cell.take();
             };
             sched2.enqueue_task(task2);
 
-            let sched1_cell = Cell(sched1);
+            let sched1_cell = Cell::new(sched1);
             let _thread1 = do Thread::start {
                 let sched1 = sched1_cell.take();
                 sched1.run();
             };
 
-            let sched2_cell = Cell(sched2);
+            let sched2_cell = Cell::new(sched2);
             let _thread2 = do Thread::start {
                 let sched2 = sched2_cell.take();
                 sched2.run();
@@ -787,7 +1318,7 @@ mod test {
             let mut ports = ~[];
             for 10.times {
                 let (port, chan) = oneshot();
-                let chan_cell = Cell(chan);
+                let chan_cell = Cell::new(chan);
                 do spawntask_later {
                     chan_cell.take().send(());
                 }
@@ -859,8 +1390,8 @@ mod test {
     fn start_closure_dtor() {
         use ops::Drop;
 
-        // Regression test that the `start` task entrypoint can contain dtors
-        // that use task resources
+        // Regression test that the `start` task entrypoint can
+        // contain dtors that use task resources
         do run_in_newsched_task {
             struct S { field: () }
 
@@ -875,6 +1406,7 @@ mod test {
             do spawntask {
                 let _ss = &s;
             }
-        }        
+        }
     }
+
 }
diff --git a/src/libstd/rt/sleeper_list.rs b/src/libstd/rt/sleeper_list.rs
index e2873e78d80..3d6e9ef5635 100644
--- a/src/libstd/rt/sleeper_list.rs
+++ b/src/libstd/rt/sleeper_list.rs
@@ -31,16 +31,20 @@ impl SleeperList {
     }
 
     pub fn push(&mut self, handle: SchedHandle) {
-        let handle = Cell(handle);
-        self.stack.with(|s| s.push(handle.take()));
+        let handle = Cell::new(handle);
+        unsafe {
+            self.stack.with(|s| s.push(handle.take()));
+        }
     }
 
     pub fn pop(&mut self) -> Option<SchedHandle> {
-        do self.stack.with |s| {
-            if !s.is_empty() {
-                Some(s.pop())
-            } else {
-                None
+        unsafe {
+            do self.stack.with |s| {
+                if !s.is_empty() {
+                    Some(s.pop())
+                } else {
+                    None
+                }
             }
         }
     }
diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs
index ec56e65931c..b0e87a62c8b 100644
--- a/src/libstd/rt/stack.rs
+++ b/src/libstd/rt/stack.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use container::Container;
-use ptr::Ptr;
+use ptr::RawPtr;
 use vec;
 use ops::Drop;
 use libc::{c_uint, uintptr_t};
@@ -19,8 +19,8 @@ pub struct StackSegment {
     valgrind_id: c_uint
 }
 
-pub impl StackSegment {
-    fn new(size: uint) -> StackSegment {
+impl StackSegment {
+    pub fn new(size: uint) -> StackSegment {
         unsafe {
             // Crate a block of uninitialized values
             let mut stack = vec::with_capacity(size);
@@ -38,12 +38,12 @@ pub impl StackSegment {
     }
 
     /// Point to the low end of the allocated stack
-    fn start(&self) -> *uint {
-      vec::raw::to_ptr(self.buf) as *uint
+    pub fn start(&self) -> *uint {
+        vec::raw::to_ptr(self.buf) as *uint
     }
 
     /// Point one word beyond the high end of the allocated stack
-    fn end(&self) -> *uint {
+    pub fn end(&self) -> *uint {
         vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint
     }
 }
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index cf4967b12b3..e7f87906fe5 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -13,19 +13,27 @@
 //! local storage, and logging. Even a 'freestanding' Rust would likely want
 //! to implement this.
 
-use prelude::*;
-use libc::{c_void, uintptr_t};
+use borrow;
 use cast::transmute;
+use libc::{c_void, uintptr_t};
+use ptr;
+use prelude::*;
+use option::{Option, Some, None};
 use rt::local::Local;
-use super::local_heap::LocalHeap;
 use rt::logging::StdErrLogger;
+use super::local_heap::LocalHeap;
+use rt::sched::{SchedHome, AnySched};
+use rt::join_latch::JoinLatch;
 
 pub struct Task {
     heap: LocalHeap,
     gc: GarbageCollector,
     storage: LocalStorage,
     logger: StdErrLogger,
-    unwinder: Option<Unwinder>,
+    unwinder: Unwinder,
+    home: Option<SchedHome>,
+    join_latch: Option<~JoinLatch>,
+    on_exit: Option<~fn(bool)>,
     destroyed: bool
 }
 
@@ -37,49 +45,63 @@ pub struct Unwinder {
 }
 
 impl Task {
-    pub fn new() -> Task {
+    pub fn new_root() -> Task {
         Task {
             heap: LocalHeap::new(),
             gc: GarbageCollector,
             storage: LocalStorage(ptr::null(), None),
             logger: StdErrLogger,
-            unwinder: Some(Unwinder { unwinding: false }),
+            unwinder: Unwinder { unwinding: false },
+            home: Some(AnySched),
+            join_latch: Some(JoinLatch::new_root()),
+            on_exit: None,
             destroyed: false
         }
     }
 
-    pub fn without_unwinding() -> Task {
+    pub fn new_child(&mut self) -> Task {
         Task {
             heap: LocalHeap::new(),
             gc: GarbageCollector,
             storage: LocalStorage(ptr::null(), None),
             logger: StdErrLogger,
-            unwinder: None,
+            home: Some(AnySched),
+            unwinder: Unwinder { unwinding: false },
+            join_latch: Some(self.join_latch.get_mut_ref().new_child()),
+            on_exit: None,
             destroyed: false
         }
     }
 
+    pub fn give_home(&mut self, new_home: SchedHome) {
+        self.home = Some(new_home);
+    }
+
     pub fn run(&mut self, f: &fn()) {
         // This is just an assertion that `run` was called unsafely
         // and this instance of Task is still accessible.
-        do Local::borrow::<Task> |task| {
-            assert!(ptr::ref_eq(task, self));
+        do Local::borrow::<Task, ()> |task| {
+            assert!(borrow::ref_eq(task, self));
         }
 
-        match self.unwinder {
-            Some(ref mut unwinder) => {
-                // If there's an unwinder then set up the catch block
-                unwinder.try(f);
+        self.unwinder.try(f);
+        self.destroy();
+
+        // Wait for children. Possibly report the exit status.
+        let local_success = !self.unwinder.unwinding;
+        let join_latch = self.join_latch.swap_unwrap();
+        match self.on_exit {
+            Some(ref on_exit) => {
+                let success = join_latch.wait(local_success);
+                (*on_exit)(success);
             }
             None => {
-                // Otherwise, just run the body
-                f()
+                join_latch.release(local_success);
             }
         }
-        self.destroy();
     }
 
-    /// Must be called manually before finalization to clean up
+    /// must be called manually before finalization to clean up
     /// thread-local resources. Some of the routines here expect
     /// Task to be available recursively so this must be
     /// called unsafely, without removing Task from
@@ -87,8 +109,8 @@ impl Task {
     fn destroy(&mut self) {
         // This is just an assertion that `destroy` was called unsafely
         // and this instance of Task is still accessible.
-        do Local::borrow::<Task> |task| {
-            assert!(ptr::ref_eq(task, self));
+        do Local::borrow::<Task, ()> |task| {
+            assert!(borrow::ref_eq(task, self));
         }
         match self.storage {
             LocalStorage(ptr, Some(ref dtor)) => {
@@ -225,5 +247,14 @@ mod test {
             assert!(port.recv() == 10);
         }
     }
-}
 
+    #[test]
+    fn linked_failure() {
+        do run_in_newsched_task() {
+            let res = do spawntask_try {
+                spawntask_random(|| fail!());
+            };
+            assert!(res.is_err());
+        }
+    }
+}
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index c8df3a61203..6e4fb9b1d94 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -13,11 +13,12 @@ use option::{Some, None};
 use cell::Cell;
 use clone::Clone;
 use container::Container;
-use old_iter::MutableIter;
-use vec::OwnedVector;
+use iterator::IteratorUtil;
+use vec::{OwnedVector, MutableVector};
 use result::{Result, Ok, Err};
 use unstable::run_in_bare_thread;
 use super::io::net::ip::{IpAddr, Ipv4};
+use rt::comm::oneshot;
 use rt::task::Task;
 use rt::thread::Thread;
 use rt::local::Local;
@@ -43,12 +44,15 @@ pub fn run_in_newsched_task(f: ~fn()) {
     use super::sched::*;
     use unstable::run_in_bare_thread;
 
-    let f = Cell(f);
+    let f = Cell::new(f);
 
     do run_in_bare_thread {
         let mut sched = ~new_test_uv_sched();
+        let mut new_task = ~Task::new_root();
+        let on_exit: ~fn(bool) = |exit_status| rtassert!(exit_status);
+        new_task.on_exit = Some(on_exit);
         let task = ~Coroutine::with_task(&mut sched.stack_pool,
-                                         ~Task::without_unwinding(),
+                                         new_task,
                                          f.take());
         sched.enqueue_task(task);
         sched.run();
@@ -65,7 +69,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
     use rt::uv::uvio::UvEventLoop;
     use rt::sched::Shutdown;
 
-    let f_cell = Cell(f);
+    let f_cell = Cell::new(f);
 
     do run_in_bare_thread {
         let nthreads = match os::getenv("RUST_TEST_THREADS") {
@@ -88,37 +92,152 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
             let loop_ = ~UvEventLoop::new();
             let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
             let handle = sched.make_handle();
+
             handles.push(handle);
             scheds.push(sched);
         }
 
-        let f_cell = Cell(f_cell.take());
-        let handles = Cell(handles);
-        let main_task = ~do Coroutine::new(&mut scheds[0].stack_pool) {
-            f_cell.take()();
+        let f_cell = Cell::new(f_cell.take());
+        let handles = Cell::new(handles);
+        let mut new_task = ~Task::new_root();
+        let on_exit: ~fn(bool) = |exit_status| {
 
             let mut handles = handles.take();
             // Tell schedulers to exit
-            for handles.each_mut |handle| {
+            for handles.mut_iter().advance |handle| {
                 handle.send(Shutdown);
             }
+
+            rtassert!(exit_status);
+        };
+        new_task.on_exit = Some(on_exit);
+        let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool,
+                                              new_task, f_cell.take());
+        scheds[0].enqueue_task(main_task);
+
+        let mut threads = ~[];
+
+        while !scheds.is_empty() {
+            let sched = scheds.pop();
+            let sched_cell = Cell::new(sched);
+            let thread = do Thread::start {
+                let sched = sched_cell.take();
+                sched.run();
+            };
+
+            threads.push(thread);
+        }
+
+        // Wait for schedulers
+        let _threads = threads;
+    }
+
+    extern {
+        fn rust_get_num_cpus() -> libc::uintptr_t;
+    }
+}
+
+// THIS IS AWFUL. Copy-pasted the above initialization function but
+// with a number of hacks to make it spawn tasks on a variety of
+// schedulers with a variety of homes using the new spawn.
+
+pub fn run_in_mt_newsched_task_random_homed() {
+    use libc;
+    use os;
+    use from_str::FromStr;
+    use rt::uv::uvio::UvEventLoop;
+    use rt::sched::Shutdown;
+
+    do run_in_bare_thread {
+        let nthreads = match os::getenv("RUST_TEST_THREADS") {
+            Some(nstr) => FromStr::from_str(nstr).get(),
+            None => unsafe {
+                // Using more threads than cores in test code to force
+                // the OS to preempt them frequently.  Assuming that
+                // this help stress test concurrent types.
+                rust_get_num_cpus() * 2
+            }
         };
 
+        let sleepers = SleeperList::new();
+        let work_queue = WorkQueue::new();
+
+        let mut handles = ~[];
+        let mut scheds = ~[];
+
+        // create a few special schedulers, those with even indicies
+        // will be pinned-only
+        for uint::range(0, nthreads) |i| {
+            let special = (i % 2) == 0;
+            let loop_ = ~UvEventLoop::new();
+            let mut sched = ~Scheduler::new_special(
+                loop_, work_queue.clone(), sleepers.clone(), special);
+            let handle = sched.make_handle();
+            handles.push(handle);
+            scheds.push(sched);
+        }
+
+        // Schedule a pile o tasks
+        let n = 5*stress_factor();
+        for uint::range(0,n) |_i| {
+                rtdebug!("creating task: %u", _i);
+                let hf: ~fn() = || { assert!(true) };
+                spawntask_homed(&mut scheds, hf);
+            }
+
+        // Now we want another pile o tasks that do not ever run on a
+        // special scheduler, because they are normal tasks. Because
+        // we can we put these in the "main" task.
+
+        let n = 5*stress_factor();
+
+        let f: ~fn() = || {
+            for uint::range(0,n) |_| {
+                let f: ~fn()  = || {
+                    // Borrow the scheduler we run on and check if it is
+                    // privileged.
+                    do Local::borrow::<Scheduler,()> |sched| {
+                        assert!(sched.run_anything);
+                    };
+                };
+                spawntask_random(f);
+            };
+        };
+
+        let f_cell = Cell::new(f);
+        let handles = Cell::new(handles);
+
+        rtdebug!("creating main task");
+
+        let main_task = ~do Coroutine::new_root(&mut scheds[0].stack_pool) {
+            f_cell.take()();
+            let mut handles = handles.take();
+            // Tell schedulers to exit
+            for handles.mut_iter().advance |handle| {
+                handle.send(Shutdown);
+            }
+        };
+
+        rtdebug!("queuing main task")
+
         scheds[0].enqueue_task(main_task);
 
         let mut threads = ~[];
 
         while !scheds.is_empty() {
             let sched = scheds.pop();
-            let sched_cell = Cell(sched);
+            let sched_cell = Cell::new(sched);
             let thread = do Thread::start {
                 let sched = sched_cell.take();
+                rtdebug!("running sched: %u", sched.sched_id());
                 sched.run();
             };
 
             threads.push(thread);
         }
 
+        rtdebug!("waiting on scheduler threads");
+
         // Wait for schedulers
         let _threads = threads;
     }
@@ -128,25 +247,34 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
     }
 }
 
+
 /// Test tasks will abort on failure instead of unwinding
 pub fn spawntask(f: ~fn()) {
     use super::sched::*;
 
+    rtdebug!("spawntask taking the scheduler from TLS")
+    let task = do Local::borrow::<Task, ~Task>() |running_task| {
+        ~running_task.new_child()
+    };
+
     let mut sched = Local::take::<Scheduler>();
     let task = ~Coroutine::with_task(&mut sched.stack_pool,
-                                     ~Task::without_unwinding(),
-                                     f);
-    sched.schedule_new_task(task);
+                                     task, f);
+    rtdebug!("spawntask scheduling the new task");
+    sched.schedule_task(task);
 }
 
 /// Create a new task and run it right now. Aborts on failure
 pub fn spawntask_immediately(f: ~fn()) {
     use super::sched::*;
 
+    let task = do Local::borrow::<Task, ~Task>() |running_task| {
+        ~running_task.new_child()
+    };
+
     let mut sched = Local::take::<Scheduler>();
     let task = ~Coroutine::with_task(&mut sched.stack_pool,
-                                     ~Task::without_unwinding(),
-                                     f);
+                                     task, f);
     do sched.switch_running_tasks_and_then(task) |sched, task| {
         sched.enqueue_task(task);
     }
@@ -156,10 +284,13 @@ pub fn spawntask_immediately(f: ~fn()) {
 pub fn spawntask_later(f: ~fn()) {
     use super::sched::*;
 
+    let task = do Local::borrow::<Task, ~Task>() |running_task| {
+        ~running_task.new_child()
+    };
+
     let mut sched = Local::take::<Scheduler>();
     let task = ~Coroutine::with_task(&mut sched.stack_pool,
-                                     ~Task::without_unwinding(),
-                                     f);
+                                     task, f);
 
     sched.enqueue_task(task);
     Local::put(sched);
@@ -170,13 +301,16 @@ pub fn spawntask_random(f: ~fn()) {
     use super::sched::*;
     use rand::{Rand, rng};
 
-    let mut rng = rng();
-    let run_now: bool = Rand::rand(&mut rng);
+    let task = do Local::borrow::<Task, ~Task>() |running_task| {
+        ~running_task.new_child()
+    };
 
     let mut sched = Local::take::<Scheduler>();
     let task = ~Coroutine::with_task(&mut sched.stack_pool,
-                                     ~Task::without_unwinding(),
-                                     f);
+                                     task, f);
+
+    let mut rng = rng();
+    let run_now: bool = Rand::rand(&mut rng);
 
     if run_now {
         do sched.switch_running_tasks_and_then(task) |sched, task| {
@@ -188,52 +322,75 @@ pub fn spawntask_random(f: ~fn()) {
     }
 }
 
+/// Spawn a task, with the current scheduler as home, and queue it to
+/// run later.
+pub fn spawntask_homed(scheds: &mut ~[~Scheduler], f: ~fn()) {
+    use super::sched::*;
+    use rand::{rng, RngUtil};
+    let mut rng = rng();
+
+    let task = {
+        let sched = &mut scheds[rng.gen_int_range(0,scheds.len() as int)];
+        let handle = sched.make_handle();
+        let home_id = handle.sched_id;
+
+        // now that we know where this is going, build a new function
+        // that can assert it is in the right place
+        let af: ~fn() = || {
+            do Local::borrow::<Scheduler,()>() |sched| {
+                rtdebug!("home_id: %u, runtime loc: %u",
+                         home_id,
+                         sched.sched_id());
+                assert!(home_id == sched.sched_id());
+            };
+            f()
+        };
+
+        ~Coroutine::with_task_homed(&mut sched.stack_pool,
+                                    ~Task::new_root(),
+                                    af,
+                                    Sched(handle))
+    };
+    let dest_sched = &mut scheds[rng.gen_int_range(0,scheds.len() as int)];
+    // enqueue it for future execution
+    dest_sched.enqueue_task(task);
+}
 
 /// Spawn a task and wait for it to finish, returning whether it completed successfully or failed
 pub fn spawntask_try(f: ~fn()) -> Result<(), ()> {
     use cell::Cell;
     use super::sched::*;
-    use task;
-    use unstable::finally::Finally;
-
-    // Our status variables will be filled in from the scheduler context
-    let mut failed = false;
-    let failed_ptr: *mut bool = &mut failed;
-
-    // Switch to the scheduler
-    let f = Cell(Cell(f));
-    let sched = Local::take::<Scheduler>();
-    do sched.deschedule_running_task_and_then() |sched, old_task| {
-        let old_task = Cell(old_task);
-        let f = f.take();
-        let new_task = ~do Coroutine::new(&mut sched.stack_pool) {
-            do (|| {
-                (f.take())()
-            }).finally {
-                // Check for failure then resume the parent task
-                unsafe { *failed_ptr = task::failing(); }
-                let sched = Local::take::<Scheduler>();
-                do sched.switch_running_tasks_and_then(old_task.take()) |sched, new_task| {
-                    sched.enqueue_task(new_task);
-                }
-            }
-        };
 
-        sched.enqueue_task(new_task);
+    let (port, chan) = oneshot();
+    let chan = Cell::new(chan);
+    let mut new_task = ~Task::new_root();
+    let on_exit: ~fn(bool) = |exit_status| chan.take().send(exit_status);
+    new_task.on_exit = Some(on_exit);
+    let mut sched = Local::take::<Scheduler>();
+    let new_task = ~Coroutine::with_task(&mut sched.stack_pool,
+                                         new_task, f);
+    do sched.switch_running_tasks_and_then(new_task) |sched, old_task| {
+        sched.enqueue_task(old_task);
     }
 
-    if !failed { Ok(()) } else { Err(()) }
+    let exit_status = port.recv();
+    if exit_status { Ok(()) } else { Err(()) }
 }
 
 // Spawn a new task in a new scheduler and return a thread handle.
 pub fn spawntask_thread(f: ~fn()) -> Thread {
     use rt::sched::*;
 
-    let f = Cell(f);
+    let task = do Local::borrow::<Task, ~Task>() |running_task| {
+        ~running_task.new_child()
+    };
+
+    let task = Cell::new(task);
+    let f = Cell::new(f);
     let thread = do Thread::start {
         let mut sched = ~new_test_uv_sched();
         let task = ~Coroutine::with_task(&mut sched.stack_pool,
-                                         ~Task::without_unwinding(),
+                                         task.take(),
                                          f.take());
         sched.enqueue_task(task);
         sched.run();
@@ -265,4 +422,3 @@ pub fn stress_factor() -> uint {
         None => 1
     }
 }
-
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index 0f1ae09bd94..bc290191310 100644
--- a/src/libstd/rt/thread.rs
+++ b/src/libstd/rt/thread.rs
@@ -19,8 +19,8 @@ pub struct Thread {
     raw_thread: *raw_thread
 }
 
-pub impl Thread {
-    fn start(main: ~fn()) -> Thread {
+impl Thread {
+    pub fn start(main: ~fn()) -> Thread {
         fn substart(main: &~fn()) -> *raw_thread {
             unsafe { rust_raw_thread_start(main) }
         }
diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs
index 4482a92d916..89f3d10b5e4 100644
--- a/src/libstd/rt/tube.rs
+++ b/src/libstd/rt/tube.rs
@@ -105,7 +105,7 @@ mod test {
         do run_in_newsched_task {
             let mut tube: Tube<int> = Tube::new();
             let tube_clone = tube.clone();
-            let tube_clone_cell = Cell(tube_clone);
+            let tube_clone_cell = Cell::new(tube_clone);
             let sched = Local::take::<Scheduler>();
             do sched.deschedule_running_task_and_then |sched, task| {
                 let mut tube_clone = tube_clone_cell.take();
@@ -122,10 +122,10 @@ mod test {
         do run_in_newsched_task {
             let mut tube: Tube<int> = Tube::new();
             let tube_clone = tube.clone();
-            let tube_clone = Cell(tube_clone);
+            let tube_clone = Cell::new(tube_clone);
             let sched = Local::take::<Scheduler>();
             do sched.deschedule_running_task_and_then |sched, task| {
-                let tube_clone = Cell(tube_clone.take());
+                let tube_clone = Cell::new(tube_clone.take());
                 do sched.event_loop.callback {
                     let mut tube_clone = tube_clone.take();
                     // The task should be blocked on this now and
@@ -146,7 +146,7 @@ mod test {
         do run_in_newsched_task {
             let mut tube: Tube<int> = Tube::new();
             let tube_clone = tube.clone();
-            let tube_clone = Cell(tube_clone);
+            let tube_clone = Cell::new(tube_clone);
             let sched = Local::take::<Scheduler>();
             do sched.deschedule_running_task_and_then |sched, task| {
                 callback_send(tube_clone.take(), 0);
@@ -154,8 +154,8 @@ mod test {
                 fn callback_send(tube: Tube<int>, i: int) {
                     if i == 100 { return; }
 
-                    let tube = Cell(Cell(tube));
-                    do Local::borrow::<Scheduler> |sched| {
+                    let tube = Cell::new(Cell::new(tube));
+                    do Local::borrow::<Scheduler, ()> |sched| {
                         let tube = tube.take();
                         do sched.event_loop.callback {
                             let mut tube = tube.take();
diff --git a/src/libstd/rt/uv/async.rs b/src/libstd/rt/uv/async.rs
index 6ed06cc10b7..f3d1024024f 100644
--- a/src/libstd/rt/uv/async.rs
+++ b/src/libstd/rt/uv/async.rs
@@ -93,7 +93,7 @@ mod test {
         do run_in_bare_thread {
             let mut loop_ = Loop::new();
             let watcher = AsyncWatcher::new(&mut loop_, |w, _| w.close(||()) );
-            let watcher_cell = Cell(watcher);
+            let watcher_cell = Cell::new(watcher);
             let _thread = do Thread::start {
                 let mut watcher = watcher_cell.take();
                 watcher.send();
diff --git a/src/libstd/rt/uv/idle.rs b/src/libstd/rt/uv/idle.rs
index a81ab48696a..a3630c9b9bf 100644
--- a/src/libstd/rt/uv/idle.rs
+++ b/src/libstd/rt/uv/idle.rs
@@ -17,8 +17,8 @@ use rt::uv::status_to_maybe_uv_error;
 pub struct IdleWatcher(*uvll::uv_idle_t);
 impl Watcher for IdleWatcher { }
 
-pub impl IdleWatcher {
-    fn new(loop_: &mut Loop) -> IdleWatcher {
+impl IdleWatcher {
+    pub fn new(loop_: &mut Loop) -> IdleWatcher {
         unsafe {
             let handle = uvll::idle_new();
             assert!(handle.is_not_null());
@@ -29,7 +29,7 @@ pub impl IdleWatcher {
         }
     }
 
-    fn start(&mut self, cb: IdleCallback) {
+    pub fn start(&mut self, cb: IdleCallback) {
         {
             let data = self.get_watcher_data();
             data.idle_cb = Some(cb);
@@ -48,16 +48,17 @@ pub impl IdleWatcher {
         }
     }
 
-    fn stop(&mut self) {
-        // NB: Not resetting the Rust idle_cb to None here because `stop` is likely
-        // called from *within* the idle callback, causing a use after free
+    pub fn stop(&mut self) {
+        // NB: Not resetting the Rust idle_cb to None here because `stop` is
+        // likely called from *within* the idle callback, causing a use after
+        // free
 
         unsafe {
             assert!(0 == uvll::idle_stop(self.native_handle()));
         }
     }
 
-    fn close(self, cb: NullCallback) {
+    pub fn close(self, cb: NullCallback) {
         {
             let mut this = self;
             let data = this.get_watcher_data();
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs
index f7cc5c6cc8b..a6a8edafe60 100644
--- a/src/libstd/rt/uv/mod.rs
+++ b/src/libstd/rt/uv/mod.rs
@@ -38,11 +38,9 @@ use container::Container;
 use option::*;
 use str::raw::from_c_str;
 use to_str::ToStr;
-use ptr::Ptr;
-use libc;
+use ptr::RawPtr;
 use vec;
 use ptr;
-use cast;
 use str;
 use libc::{c_void, c_int, size_t, malloc, free};
 use cast::transmute;
@@ -94,18 +92,18 @@ pub trait NativeHandle<T> {
     pub fn native_handle(&self) -> T;
 }
 
-pub impl Loop {
-    fn new() -> Loop {
+impl Loop {
+    pub fn new() -> Loop {
         let handle = unsafe { uvll::loop_new() };
         assert!(handle.is_not_null());
         NativeHandle::from_native_handle(handle)
     }
 
-    fn run(&mut self) {
+    pub fn run(&mut self) {
         unsafe { uvll::run(self.native_handle()) };
     }
 
-    fn close(&mut self) {
+    pub fn close(&mut self) {
         unsafe { uvll::loop_delete(self.native_handle()) };
     }
 }
@@ -204,9 +202,8 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
 
 pub struct UvError(uvll::uv_err_t);
 
-pub impl UvError {
-
-    fn name(&self) -> ~str {
+impl UvError {
+    pub fn name(&self) -> ~str {
         unsafe {
             let inner = match self { &UvError(ref a) => a };
             let name_str = uvll::err_name(inner);
@@ -215,7 +212,7 @@ pub impl UvError {
         }
     }
 
-    fn desc(&self) -> ~str {
+    pub fn desc(&self) -> ~str {
         unsafe {
             let inner = match self { &UvError(ref a) => a };
             let desc_str = uvll::strerror(inner);
@@ -224,7 +221,7 @@ pub impl UvError {
         }
     }
 
-    fn is_eof(&self) -> bool {
+    pub fn is_eof(&self) -> bool {
         self.code == uvll::EOF
     }
 }
@@ -250,20 +247,6 @@ pub fn last_uv_error<H, W: Watcher + NativeHandle<*H>>(watcher: &W) -> UvError {
 }
 
 pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
-
-    // XXX: Could go in str::raw
-    unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
-        let s = s as *u8;
-        let mut curr = s, len = 0u;
-        while *curr != 0u8 {
-            len += 1u;
-            curr = ptr::offset(s, len);
-        }
-
-        str::raw::buf_as_slice(s, len, |d| cast::transmute(d))
-    }
-
-
     unsafe {
         // Importing error constants
         use rt::uv::uvll::*;
@@ -271,7 +254,7 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
 
         // uv error descriptions are static
         let c_desc = uvll::strerror(&*uverr);
-        let desc = c_str_to_static_slice(c_desc);
+        let desc = str::raw::c_str_to_static_slice(c_desc);
 
         let kind = match uverr.code {
             UNKNOWN => OtherIoError,
diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs
index 0b77bd83958..5491b82b725 100644
--- a/src/libstd/rt/uv/net.rs
+++ b/src/libstd/rt/uv/net.rs
@@ -51,9 +51,8 @@ pub fn uv_ip4_to_ip4(addr: *sockaddr_in) -> IpAddr {
 pub struct StreamWatcher(*uvll::uv_stream_t);
 impl Watcher for StreamWatcher { }
 
-pub impl StreamWatcher {
-
-    fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) {
+impl StreamWatcher {
+    pub fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) {
         {
             let data = self.get_watcher_data();
             data.alloc_cb = Some(alloc);
@@ -81,7 +80,7 @@ pub impl StreamWatcher {
         }
     }
 
-    fn read_stop(&mut self) {
+    pub fn read_stop(&mut self) {
         // It would be nice to drop the alloc and read callbacks here,
         // but read_stop may be called from inside one of them and we
         // would end up freeing the in-use environment
@@ -89,7 +88,7 @@ pub impl StreamWatcher {
         unsafe { uvll::read_stop(handle); }
     }
 
-    fn write(&mut self, buf: Buf, cb: ConnectionCallback) {
+    pub fn write(&mut self, buf: Buf, cb: ConnectionCallback) {
         {
             let data = self.get_watcher_data();
             assert!(data.write_cb.is_none());
@@ -118,7 +117,7 @@ pub impl StreamWatcher {
         }
     }
 
-    fn accept(&mut self, stream: StreamWatcher) {
+    pub fn accept(&mut self, stream: StreamWatcher) {
         let self_handle = self.native_handle() as *c_void;
         let stream_handle = stream.native_handle() as *c_void;
         unsafe {
@@ -126,7 +125,7 @@ pub impl StreamWatcher {
         }
     }
 
-    fn close(self, cb: NullCallback) {
+    pub fn close(self, cb: NullCallback) {
         {
             let mut this = self;
             let data = this.get_watcher_data();
@@ -161,8 +160,8 @@ impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher {
 pub struct TcpWatcher(*uvll::uv_tcp_t);
 impl Watcher for TcpWatcher { }
 
-pub impl TcpWatcher {
-    fn new(loop_: &mut Loop) -> TcpWatcher {
+impl TcpWatcher {
+    pub fn new(loop_: &mut Loop) -> TcpWatcher {
         unsafe {
             let handle = malloc_handle(UV_TCP);
             assert!(handle.is_not_null());
@@ -173,7 +172,7 @@ pub impl TcpWatcher {
         }
     }
 
-    fn bind(&mut self, address: IpAddr) -> Result<(), UvError> {
+    pub fn bind(&mut self, address: IpAddr) -> Result<(), UvError> {
         match address {
             Ipv4(*) => {
                 do ip4_as_uv_ip4(address) |addr| {
@@ -191,7 +190,7 @@ pub impl TcpWatcher {
         }
     }
 
-    fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) {
+    pub fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) {
         unsafe {
             assert!(self.get_watcher_data().connect_cb.is_none());
             self.get_watcher_data().connect_cb = Some(cb);
@@ -224,7 +223,7 @@ pub impl TcpWatcher {
         }
     }
 
-    fn listen(&mut self, cb: ConnectionCallback) {
+    pub fn listen(&mut self, cb: ConnectionCallback) {
         {
             let data = self.get_watcher_data();
             assert!(data.connect_cb.is_none());
@@ -248,7 +247,7 @@ pub impl TcpWatcher {
         }
     }
 
-    fn as_stream(&self) -> StreamWatcher {
+    pub fn as_stream(&self) -> StreamWatcher {
         NativeHandle::from_native_handle(self.native_handle() as *uvll::uv_stream_t)
     }
 }
@@ -439,9 +438,8 @@ pub struct WriteRequest(*uvll::uv_write_t);
 
 impl Request for WriteRequest { }
 
-pub impl WriteRequest {
-
-    fn new() -> WriteRequest {
+impl WriteRequest {
+    pub fn new() -> WriteRequest {
         let write_handle = unsafe {
             malloc_req(UV_WRITE)
         };
@@ -450,14 +448,14 @@ pub impl WriteRequest {
         WriteRequest(write_handle)
     }
 
-    fn stream(&self) -> StreamWatcher {
+    pub fn stream(&self) -> StreamWatcher {
         unsafe {
             let stream_handle = uvll::get_stream_handle_from_write_req(self.native_handle());
             NativeHandle::from_native_handle(stream_handle)
         }
     }
 
-    fn delete(self) {
+    pub fn delete(self) {
         unsafe { free_req(self.native_handle() as *c_void) }
     }
 }
@@ -554,7 +552,7 @@ mod test {
                 let client_tcp_watcher = TcpWatcher::new(&mut loop_);
                 let mut client_tcp_watcher = client_tcp_watcher.as_stream();
                 server_stream_watcher.accept(client_tcp_watcher);
-                let count_cell = Cell(0);
+                let count_cell = Cell::new(0);
                 let server_stream_watcher = server_stream_watcher;
                 rtdebug!("starting read");
                 let alloc: AllocCallback = |size| {
@@ -594,11 +592,11 @@ mod test {
                     let mut stream_watcher = stream_watcher;
                     let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9];
                     let buf = slice_to_uv_buf(msg);
-                    let msg_cell = Cell(msg);
+                    let msg_cell = Cell::new(msg);
                     do stream_watcher.write(buf) |stream_watcher, status| {
                         rtdebug!("writing");
                         assert!(status.is_none());
-                        let msg_cell = Cell(msg_cell.take());
+                        let msg_cell = Cell::new(msg_cell.take());
                         stream_watcher.close(||ignore(msg_cell.take()));
                     }
                 }
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index 1274dbc3220..eba84e537f9 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -11,7 +11,7 @@
 use option::*;
 use result::*;
 use ops::Drop;
-use cell::{Cell, empty_cell};
+use cell::Cell;
 use cast;
 use cast::transmute;
 use clone::Clone;
@@ -35,8 +35,8 @@ pub struct UvEventLoop {
     uvio: UvIoFactory
 }
 
-pub impl UvEventLoop {
-    fn new() -> UvEventLoop {
+impl UvEventLoop {
+    pub fn new() -> UvEventLoop {
         UvEventLoop {
             uvio: UvIoFactory(Loop::new())
         }
@@ -54,7 +54,6 @@ impl Drop for UvEventLoop {
 }
 
 impl EventLoop for UvEventLoop {
-
     fn run(&mut self) {
         self.uvio.uv_loop().run();
     }
@@ -117,9 +116,11 @@ impl UvRemoteCallback {
         let async = do AsyncWatcher::new(loop_) |watcher, status| {
             assert!(status.is_none());
             f();
-            do exit_flag_clone.with_imm |&should_exit| {
-                if should_exit {
-                    watcher.close(||());
+            unsafe {
+                do exit_flag_clone.with_imm |&should_exit| {
+                    if should_exit {
+                        watcher.close(||());
+                    }
                 }
             }
         };
@@ -152,7 +153,6 @@ impl Drop for UvRemoteCallback {
 
 #[cfg(test)]
 mod test_remote {
-    use cell;
     use cell::Cell;
     use rt::test::*;
     use rt::thread::Thread;
@@ -166,10 +166,10 @@ mod test_remote {
         do run_in_newsched_task {
             let mut tube = Tube::new();
             let tube_clone = tube.clone();
-            let remote_cell = cell::empty_cell();
-            do Local::borrow::<Scheduler>() |sched| {
+            let remote_cell = Cell::new_empty();
+            do Local::borrow::<Scheduler, ()>() |sched| {
                 let tube_clone = tube_clone.clone();
-                let tube_clone_cell = Cell(tube_clone);
+                let tube_clone_cell = Cell::new(tube_clone);
                 let remote = do sched.event_loop.remote_callback {
                     tube_clone_cell.take().send(1);
                 };
@@ -186,8 +186,8 @@ mod test_remote {
 
 pub struct UvIoFactory(Loop);
 
-pub impl UvIoFactory {
-    fn uv_loop<'a>(&'a mut self) -> &'a mut Loop {
+impl UvIoFactory {
+    pub fn uv_loop<'a>(&'a mut self) -> &'a mut Loop {
         match self { &UvIoFactory(ref mut ptr) => ptr }
     }
 }
@@ -199,7 +199,7 @@ impl IoFactory for UvIoFactory {
     fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError> {
         // Create a cell in the task to hold the result. We will fill
         // the cell before resuming the task.
-        let result_cell = empty_cell();
+        let result_cell = Cell::new_empty();
         let result_cell_ptr: *Cell<Result<~RtioTcpStreamObject, IoError>> = &result_cell;
 
         let scheduler = Local::take::<Scheduler>();
@@ -211,7 +211,7 @@ impl IoFactory for UvIoFactory {
             rtdebug!("connect: entered scheduler context");
             assert!(!sched.in_task_context());
             let mut tcp_watcher = TcpWatcher::new(self.uv_loop());
-            let task_cell = Cell(task);
+            let task_cell = Cell::new(task);
 
             // Wait for a connection
             do tcp_watcher.connect(addr) |stream_watcher, status| {
@@ -228,7 +228,7 @@ impl IoFactory for UvIoFactory {
                     scheduler.resume_task_immediately(task_cell.take());
                 } else {
                     rtdebug!("status is some");
-                    let task_cell = Cell(task_cell.take());
+                    let task_cell = Cell::new(task_cell.take());
                     do stream_watcher.close {
                         let res = Err(uv_error_to_io_error(status.get()));
                         unsafe { (*result_cell_ptr).put_back(res); }
@@ -250,7 +250,7 @@ impl IoFactory for UvIoFactory {
             Err(uverr) => {
                 let scheduler = Local::take::<Scheduler>();
                 do scheduler.deschedule_running_task_and_then |_, task| {
-                    let task_cell = Cell(task);
+                    let task_cell = Cell::new(task);
                     do watcher.as_stream().close {
                         let scheduler = Local::take::<Scheduler>();
                         scheduler.resume_task_immediately(task_cell.take());
@@ -286,7 +286,7 @@ impl Drop for UvTcpListener {
         let watcher = self.watcher();
         let scheduler = Local::take::<Scheduler>();
         do scheduler.deschedule_running_task_and_then |_, task| {
-            let task_cell = Cell(task);
+            let task_cell = Cell::new(task);
             do watcher.as_stream().close {
                 let scheduler = Local::take::<Scheduler>();
                 scheduler.resume_task_immediately(task_cell.take());
@@ -307,9 +307,9 @@ impl RtioTcpListener for UvTcpListener {
         self.listening = true;
 
         let server_tcp_watcher = self.watcher();
-        let incoming_streams_cell = Cell(self.incoming_streams.clone());
+        let incoming_streams_cell = Cell::new(self.incoming_streams.clone());
 
-        let incoming_streams_cell = Cell(incoming_streams_cell.take());
+        let incoming_streams_cell = Cell::new(incoming_streams_cell.take());
         let mut server_tcp_watcher = server_tcp_watcher;
         do server_tcp_watcher.listen |server_stream_watcher, status| {
             let maybe_stream = if status.is_none() {
@@ -348,7 +348,7 @@ impl Drop for UvTcpStream {
         let watcher = self.watcher();
         let scheduler = Local::take::<Scheduler>();
         do scheduler.deschedule_running_task_and_then |_, task| {
-            let task_cell = Cell(task);
+            let task_cell = Cell::new(task);
             do watcher.close {
                 let scheduler = Local::take::<Scheduler>();
                 scheduler.resume_task_immediately(task_cell.take());
@@ -359,7 +359,7 @@ impl Drop for UvTcpStream {
 
 impl RtioTcpStream for UvTcpStream {
     fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
-        let result_cell = empty_cell();
+        let result_cell = Cell::new_empty();
         let result_cell_ptr: *Cell<Result<uint, IoError>> = &result_cell;
 
         let scheduler = Local::take::<Scheduler>();
@@ -370,7 +370,7 @@ impl RtioTcpStream for UvTcpStream {
             rtdebug!("read: entered scheduler context");
             assert!(!sched.in_task_context());
             let mut watcher = watcher;
-            let task_cell = Cell(task);
+            let task_cell = Cell::new(task);
             // XXX: We shouldn't reallocate these callbacks every
             // call to read
             let alloc: AllocCallback = |_| unsafe {
@@ -404,7 +404,7 @@ impl RtioTcpStream for UvTcpStream {
     }
 
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
-        let result_cell = empty_cell();
+        let result_cell = Cell::new_empty();
         let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
         let scheduler = Local::take::<Scheduler>();
         assert!(scheduler.in_task_context());
@@ -412,7 +412,7 @@ impl RtioTcpStream for UvTcpStream {
         let buf_ptr: *&[u8] = &buf;
         do scheduler.deschedule_running_task_and_then |_, task| {
             let mut watcher = watcher;
-            let task_cell = Cell(task);
+            let task_cell = Cell::new(task);
             let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
             do watcher.write(buf) |_watcher, status| {
                 let result = if status.is_none() {
@@ -585,7 +585,7 @@ fn test_read_and_block() {
                 // will trigger a read callback while we are
                 // not ready for it
                 do scheduler.deschedule_running_task_and_then |sched, task| {
-                    let task = Cell(task);
+                    let task = Cell::new(task);
                     sched.enqueue_task(task.take());
                 }
             }
diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs
index 06315c4cb38..b73db77f3bb 100644
--- a/src/libstd/rt/uv/uvll.rs
+++ b/src/libstd/rt/uv/uvll.rs
@@ -31,7 +31,11 @@
 
 use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
 use libc::{malloc, free};
+use libc;
 use prelude::*;
+use ptr;
+use str;
+use vec;
 
 pub static UNKNOWN: c_int = -1;
 pub static OK: c_int = 0;
diff --git a/src/libstd/rt/work_queue.rs b/src/libstd/rt/work_queue.rs
index e9eb663392b..cfffc55a58c 100644
--- a/src/libstd/rt/work_queue.rs
+++ b/src/libstd/rt/work_queue.rs
@@ -21,40 +21,48 @@ pub struct WorkQueue<T> {
     priv queue: ~Exclusive<~[T]>
 }
 
-pub impl<T: Owned> WorkQueue<T> {
-    fn new() -> WorkQueue<T> {
+impl<T: Owned> WorkQueue<T> {
+    pub fn new() -> WorkQueue<T> {
         WorkQueue {
             queue: ~exclusive(~[])
         }
     }
 
-    fn push(&mut self, value: T) {
-        let value = Cell(value);
-        self.queue.with(|q| q.unshift(value.take()) );
+    pub fn push(&mut self, value: T) {
+        unsafe {
+            let value = Cell::new(value);
+            self.queue.with(|q| q.unshift(value.take()) );
+        }
     }
 
-    fn pop(&mut self) -> Option<T> {
-        do self.queue.with |q| {
-            if !q.is_empty() {
-                Some(q.shift())
-            } else {
-                None
+    pub fn pop(&mut self) -> Option<T> {
+        unsafe {
+            do self.queue.with |q| {
+                if !q.is_empty() {
+                    Some(q.shift())
+                } else {
+                    None
+                }
             }
         }
     }
 
-    fn steal(&mut self) -> Option<T> {
-        do self.queue.with |q| {
-            if !q.is_empty() {
-                Some(q.pop())
-            } else {
-                None
+    pub fn steal(&mut self) -> Option<T> {
+        unsafe {
+            do self.queue.with |q| {
+                if !q.is_empty() {
+                    Some(q.pop())
+                } else {
+                    None
+                }
             }
         }
     }
 
-    fn is_empty(&self) -> bool {
-        self.queue.with_imm(|q| q.is_empty() )
+    pub fn is_empty(&self) -> bool {
+        unsafe {
+            self.queue.with_imm(|q| q.is_empty() )
+        }
     }
 }
 
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 3cdc5dcca07..b204cf6cfb0 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -10,11 +10,15 @@
 
 //! Process spawning.
 
+#[allow(missing_doc)];
+
+use iterator::IteratorUtil;
 use cast;
+use comm::{stream, SharedChan, GenericChan, GenericPort};
+use int;
 use io;
-use libc;
 use libc::{pid_t, c_void, c_int};
-use comm::{stream, SharedChan, GenericChan, GenericPort};
+use libc;
 use option::{Some, None};
 use os;
 use prelude::*;
@@ -133,8 +137,7 @@ pub struct ProcessOutput {
     error: ~[u8],
 }
 
-pub impl Process {
-
+impl Process {
     /**
      * Spawns a new Process.
      *
@@ -145,8 +148,8 @@ pub impl Process {
      * * options - Options to configure the environment of the process,
      *             the working directory and the standard IO streams.
      */
-    pub fn new(prog: &str, args: &[~str], options: ProcessOptions) -> Process {
-
+    pub fn new(prog: &str, args: &[~str], options: ProcessOptions)
+               -> Process {
         let (in_pipe, in_fd) = match options.in_fd {
             None => {
                 let pipe = os::pipe();
@@ -173,9 +176,9 @@ pub impl Process {
                                    in_fd, out_fd, err_fd);
 
         unsafe {
-            for in_pipe.each  |pipe| { libc::close(pipe.in); }
-            for out_pipe.each |pipe| { libc::close(pipe.out); }
-            for err_pipe.each |pipe| { libc::close(pipe.out); }
+            for in_pipe.iter().advance  |pipe| { libc::close(pipe.in); }
+            for out_pipe.iter().advance |pipe| { libc::close(pipe.out); }
+            for err_pipe.iter().advance |pipe| { libc::close(pipe.out); }
         }
 
         Process {
@@ -189,9 +192,9 @@ pub impl Process {
     }
 
     /// Returns the unique id of the process
-    fn get_id(&self) -> pid_t { self.pid }
+    pub fn get_id(&self) -> pid_t { self.pid }
 
-    priv fn input_fd(&mut self) -> c_int {
+    fn input_fd(&mut self) -> c_int {
         match self.input {
             Some(fd) => fd,
             None => fail!("This Process's stdin was redirected to an \
@@ -199,7 +202,7 @@ pub impl Process {
         }
     }
 
-    priv fn output_file(&mut self) -> *libc::FILE {
+    fn output_file(&mut self) -> *libc::FILE {
         match self.output {
             Some(file) => file,
             None => fail!("This Process's stdout was redirected to an \
@@ -207,7 +210,7 @@ pub impl Process {
         }
     }
 
-    priv fn error_file(&mut self) -> *libc::FILE {
+    fn error_file(&mut self) -> *libc::FILE {
         match self.error {
             Some(file) => file,
             None => fail!("This Process's stderr was redirected to an \
@@ -222,7 +225,7 @@ pub impl Process {
      *
      * If this method returns true then self.input() will fail.
      */
-    fn input_redirected(&self) -> bool {
+    pub fn input_redirected(&self) -> bool {
         self.input.is_none()
     }
 
@@ -233,7 +236,7 @@ pub impl Process {
      *
      * If this method returns true then self.output() will fail.
      */
-    fn output_redirected(&self) -> bool {
+    pub fn output_redirected(&self) -> bool {
         self.output.is_none()
     }
 
@@ -244,7 +247,7 @@ pub impl Process {
      *
      * If this method returns true then self.error() will fail.
      */
-    fn error_redirected(&self) -> bool {
+    pub fn error_redirected(&self) -> bool {
         self.error.is_none()
     }
 
@@ -253,7 +256,7 @@ pub impl Process {
      *
      * Fails if this Process's stdin was redirected to an existing file descriptor.
      */
-    fn input(&mut self) -> @io::Writer {
+    pub fn input(&mut self) -> @io::Writer {
         // FIXME: the Writer can still be used after self is destroyed: #2625
        io::fd_writer(self.input_fd(), false)
     }
@@ -263,7 +266,7 @@ pub impl Process {
      *
      * Fails if this Process's stdout was redirected to an existing file descriptor.
      */
-    fn output(&mut self) -> @io::Reader {
+    pub fn output(&mut self) -> @io::Reader {
         // FIXME: the Reader can still be used after self is destroyed: #2625
         io::FILE_reader(self.output_file(), false)
     }
@@ -273,7 +276,7 @@ pub impl Process {
      *
      * Fails if this Process's stderr was redirected to an existing file descriptor.
      */
-    fn error(&mut self) -> @io::Reader {
+    pub fn error(&mut self) -> @io::Reader {
         // FIXME: the Reader can still be used after self is destroyed: #2625
         io::FILE_reader(self.error_file(), false)
     }
@@ -284,7 +287,7 @@ pub impl Process {
      * If this process is reading its stdin from an existing file descriptor, then this
      * method does nothing.
      */
-    fn close_input(&mut self) {
+    pub fn close_input(&mut self) {
         match self.input {
             Some(-1) | None => (),
             Some(fd) => {
@@ -296,7 +299,7 @@ pub impl Process {
         }
     }
 
-    priv fn close_outputs(&mut self) {
+    fn close_outputs(&mut self) {
         fclose_and_null(&mut self.output);
         fclose_and_null(&mut self.error);
 
@@ -319,8 +322,8 @@ pub impl Process {
      *
      * If the child has already been finished then the exit code is returned.
      */
-    fn finish(&mut self) -> int {
-        for self.exit_code.each |&code| {
+    pub fn finish(&mut self) -> int {
+        for self.exit_code.iter().advance |&code| {
             return code;
         }
         self.close_input();
@@ -339,8 +342,7 @@ pub impl Process {
      * This method will fail if the child process's stdout or stderr streams were
      * redirected to existing file descriptors.
      */
-    fn finish_with_output(&mut self) -> ProcessOutput {
-
+    pub fn finish_with_output(&mut self) -> ProcessOutput {
         let output_file = self.output_file();
         let error_file = self.error_file();
 
@@ -375,8 +377,7 @@ pub impl Process {
                               error: errs};
     }
 
-    priv fn destroy_internal(&mut self, force: bool) {
-
+    fn destroy_internal(&mut self, force: bool) {
         // if the process has finished, and therefore had waitpid called,
         // and we kill it, then on unix we might ending up killing a
         // newer process that happens to have the same (re-used) id
@@ -414,7 +415,7 @@ pub impl Process {
      * On Posix OSs SIGTERM will be sent to the process. On Win32
      * TerminateProcess(..) will be called.
      */
-    fn destroy(&mut self) { self.destroy_internal(false); }
+    pub fn destroy(&mut self) { self.destroy_internal(false); }
 
     /**
      * Terminates the process as soon as possible without giving it a
@@ -423,12 +424,12 @@ pub impl Process {
      * On Posix OSs SIGKILL will be sent to the process. On Win32
      * TerminateProcess(..) will be called.
      */
-    fn force_destroy(&mut self) { self.destroy_internal(true); }
+    pub fn force_destroy(&mut self) { self.destroy_internal(true); }
 }
 
 impl Drop for Process {
     fn finalize(&self) {
-        // FIXME #4943: transmute is bad.
+        // FIXME(#4330) Need self by value to get mutability.
         let mut_self: &mut Process = unsafe { cast::transmute(self) };
 
         mut_self.finish();
@@ -463,6 +464,9 @@ fn spawn_process_os(prog: &str, args: &[~str],
     };
     use libc::funcs::extra::msvcrt::get_osfhandle;
 
+    use sys;
+    use uint;
+
     unsafe {
 
         let mut si = zeroed_startupinfo();
@@ -519,7 +523,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
         CloseHandle(si.hStdOutput);
         CloseHandle(si.hStdError);
 
-        for create_err.each |msg| {
+        for create_err.iter().advance |msg| {
             fail!("failure in CreateProcess: %s", *msg);
         }
 
@@ -574,6 +578,8 @@ fn zeroed_process_information() -> libc::types::os::arch::extra::PROCESS_INFORMA
 #[cfg(windows)]
 pub fn make_command_line(prog: &str, args: &[~str]) -> ~str {
 
+    use uint;
+
     let mut cmd = ~"";
     append_arg(&mut cmd, prog);
     for args.each |arg| {
@@ -583,7 +589,7 @@ pub fn make_command_line(prog: &str, args: &[~str]) -> ~str {
     return cmd;
 
     fn append_arg(cmd: &mut ~str, arg: &str) {
-        let quote = arg.any(|c| c == ' ' || c == '\t');
+        let quote = arg.iter().any_(|c| c == ' ' || c == '\t');
         if quote {
             cmd.push_char('"');
         }
@@ -735,8 +741,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
         let mut blk = ~[];
         for es.each |&(k, v)| {
             let kv = fmt!("%s=%s", k, v);
-            blk.push_all(str::as_bytes_slice(kv));
-            blk.push(0);
+            blk.push_all(kv.as_bytes_with_null_consume());
         }
         blk.push(0);
         vec::as_imm_buf(blk, |p, _len|
@@ -1095,28 +1100,34 @@ mod tests {
 
     #[test]
     fn test_keep_current_working_dir() {
-
         let mut prog = run_pwd(None);
 
         let output = str::from_bytes(prog.finish_with_output().output);
         let parent_dir = os::getcwd().normalize();
         let child_dir = Path(output.trim()).normalize();
 
-        assert_eq!(child_dir.to_str(), parent_dir.to_str());
+        let parent_stat = parent_dir.stat().unwrap();
+        let child_stat = child_dir.stat().unwrap();
+
+        assert_eq!(parent_stat.st_dev, child_stat.st_dev);
+        assert_eq!(parent_stat.st_ino, child_stat.st_ino);
     }
 
     #[test]
     fn test_change_working_directory() {
-
         // test changing to the parent of os::getcwd() because we know
         // the path exists (and os::getcwd() is not expected to be root)
-        let parent_path = os::getcwd().dir_path().normalize();
-        let mut prog = run_pwd(Some(&parent_path));
+        let parent_dir = os::getcwd().dir_path().normalize();
+        let mut prog = run_pwd(Some(&parent_dir));
 
         let output = str::from_bytes(prog.finish_with_output().output);
         let child_dir = Path(output.trim()).normalize();
 
-        assert_eq!(child_dir.to_str(), parent_path.to_str());
+        let parent_stat = parent_dir.stat().unwrap();
+        let child_stat = child_dir.stat().unwrap();
+
+        assert_eq!(parent_stat.st_dev, child_stat.st_dev);
+        assert_eq!(parent_stat.st_ino, child_stat.st_ino);
     }
 
     #[cfg(unix)]
diff --git a/src/libstd/stackwalk.rs b/src/libstd/stackwalk.rs
index a22599e9fc6..c3e3ca57a8e 100644
--- a/src/libstd/stackwalk.rs
+++ b/src/libstd/stackwalk.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(missing_doc)];
+
 use cast::transmute;
 use unstable::intrinsics;
 
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 349a848e2c7..1086fcaa75c 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -21,25 +21,32 @@ use at_vec;
 use cast::transmute;
 use cast;
 use char;
+use char::Char;
 use clone::Clone;
 use cmp::{TotalOrd, Ordering, Less, Equal, Greater};
 use container::Container;
 use iter::Times;
-use iterator::Iterator;
+use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator};
 use libc;
 use option::{None, Option, Some};
 use old_iter::{BaseIter, EqIter};
 use ptr;
-use ptr::Ptr;
-use str;
+use ptr::RawPtr;
 use to_str::ToStr;
 use uint;
 use vec;
-use vec::{OwnedVector, OwnedCopyableVector};
+use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector};
 
 #[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq};
 
 /*
+Section: Conditions
+*/
+condition! {
+    not_utf8: (~str) -> ~str;
+}
+
+/*
 Section: Creating a string
 */
 
@@ -48,11 +55,20 @@ Section: Creating a string
  *
  * # Failure
  *
- * Fails if invalid UTF-8
+ * Raises the `not_utf8` condition if invalid UTF-8
  */
-pub fn from_bytes(vv: &const [u8]) -> ~str {
-    assert!(is_utf8(vv));
-    return unsafe { raw::from_bytes(vv) };
+
+pub fn from_bytes(vv: &[u8]) -> ~str {
+    use str::not_utf8::cond;
+
+    if !is_utf8(vv) {
+        let first_bad_byte = vec::find(vv, |b| !is_utf8([*b])).get();
+        cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
+                        first_bad_byte as uint))
+    }
+    else {
+        return unsafe { raw::from_bytes(vv) }
+    }
 }
 
 /**
@@ -72,6 +88,16 @@ pub fn from_bytes_with_null<'a>(vv: &'a [u8]) -> &'a str {
     return unsafe { raw::from_bytes_with_null(vv) };
 }
 
+/**
+ * Converts a vector to a string slice without performing any allocations.
+ *
+ * Once the slice has been validated as utf-8, it is transmuted in-place and
+ * returned as a '&str' instead of a '&[u8]'
+ *
+ * # Failure
+ *
+ * Fails if invalid UTF-8
+ */
 pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
     unsafe {
         assert!(is_utf8(vector));
@@ -84,7 +110,7 @@ pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
 /// Copy a slice into a new unique str
 #[inline(always)]
 pub fn to_owned(s: &str) -> ~str {
-    unsafe { raw::slice_bytes_owned(s, 0, len(s)) }
+    unsafe { raw::slice_bytes_owned(s, 0, s.len()) }
 }
 
 impl ToStr for ~str {
@@ -112,644 +138,266 @@ pub fn from_byte(b: u8) -> ~str {
     unsafe { ::cast::transmute(~[b, 0u8]) }
 }
 
-/// Appends a character at the end of a string
-pub fn push_char(s: &mut ~str, ch: char) {
-    unsafe {
-        let code = ch as uint;
-        let nb = if code < max_one_b { 1u }
-        else if code < max_two_b { 2u }
-        else if code < max_three_b { 3u }
-        else if code < max_four_b { 4u }
-        else if code < max_five_b { 5u }
-        else { 6u };
-        let len = len(*s);
-        let new_len = len + nb;
-        reserve_at_least(&mut *s, new_len);
-        let off = len;
-        do as_buf(*s) |buf, _len| {
-            let buf: *mut u8 = ::cast::transmute(buf);
-            match nb {
-                1u => {
-                    *ptr::mut_offset(buf, off) = code as u8;
-                }
-                2u => {
-                    *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8;
-                    *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8;
-                }
-                3u => {
-                    *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8;
-                    *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8;
-                }
-                4u => {
-                    *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8;
-                    *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8;
-                }
-                5u => {
-                    *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8;
-                    *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8;
-                }
-                6u => {
-                    *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8;
-                    *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8;
-                    *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8;
-                }
-                _ => {}
-            }
-        }
-        raw::set_len(s, new_len);
-    }
-}
-
 /// Convert a char to a string
 pub fn from_char(ch: char) -> ~str {
     let mut buf = ~"";
-    push_char(&mut buf, ch);
+    buf.push_char(ch);
     buf
 }
 
 /// Convert a vector of chars to a string
 pub fn from_chars(chs: &[char]) -> ~str {
     let mut buf = ~"";
-    reserve(&mut buf, chs.len());
+    buf.reserve(chs.len());
     for chs.each |ch| {
-        push_char(&mut buf, *ch);
+        buf.push_char(*ch)
     }
     buf
 }
 
-/// Appends a string slice to the back of a string, without overallocating
-#[inline(always)]
-pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) {
-    unsafe {
-        let llen = lhs.len();
-        let rlen = rhs.len();
-        reserve(&mut *lhs, llen + rlen);
-        do as_buf(*lhs) |lbuf, _llen| {
-            do as_buf(rhs) |rbuf, _rlen| {
-                let dst = ptr::offset(lbuf, llen);
-                let dst = ::cast::transmute_mut_unsafe(dst);
-                ptr::copy_memory(dst, rbuf, rlen);
-            }
-        }
-        raw::set_len(lhs, llen + rlen);
-    }
-}
-
-/// Appends a string slice to the back of a string
-#[inline(always)]
+#[doc(hidden)]
 pub fn push_str(lhs: &mut ~str, rhs: &str) {
-    unsafe {
-        let llen = lhs.len();
-        let rlen = rhs.len();
-        reserve_at_least(&mut *lhs, llen + rlen);
-        do as_buf(*lhs) |lbuf, _llen| {
-            do as_buf(rhs) |rbuf, _rlen| {
-                let dst = ptr::offset(lbuf, llen);
-                let dst = ::cast::transmute_mut_unsafe(dst);
-                ptr::copy_memory(dst, rbuf, rlen);
-            }
-        }
-        raw::set_len(lhs, llen + rlen);
-    }
+    lhs.push_str(rhs)
 }
 
-/// Concatenate two strings together
-#[inline(always)]
-pub fn append(lhs: ~str, rhs: &str) -> ~str {
-    let mut v = lhs;
-    push_str_no_overallocate(&mut v, rhs);
-    v
+#[allow(missing_doc)]
+pub trait StrVector {
+    pub fn concat(&self) -> ~str;
+    pub fn connect(&self, sep: &str) -> ~str;
 }
 
-/// Concatenate a vector of strings
-pub fn concat(v: &[~str]) -> ~str {
-    if v.is_empty() { return ~""; }
+impl<'self, S: Str> StrVector for &'self [S] {
+    /// Concatenate a vector of strings.
+    pub fn concat(&self) -> ~str {
+        if self.is_empty() { return ~""; }
 
-    let mut len = 0;
-    for v.each |ss| {
-        len += ss.len();
-    }
-    let mut s = ~"";
+        let len = self.iter().transform(|s| s.as_slice().len()).sum();
 
-    reserve(&mut s, len);
+        let mut s = ~"";
 
-    unsafe {
-        do as_buf(s) |buf, _len| {
-            let mut buf = ::cast::transmute_mut_unsafe(buf);
-            for v.each |ss| {
-                do as_buf(*ss) |ssbuf, sslen| {
-                    let sslen = sslen - 1;
-                    ptr::copy_memory(buf, ssbuf, sslen);
-                    buf = buf.offset(sslen);
-                }
-            }
-        }
-        raw::set_len(&mut s, len);
-    }
-    s
-}
-
-/// Concatenate a vector of strings, placing a given separator between each
-pub fn connect(v: &[~str], sep: &str) -> ~str {
-    if v.is_empty() { return ~""; }
-
-    // concat is faster
-    if sep.is_empty() { return concat(v); }
-
-    // this is wrong without the guarantee that v is non-empty
-    let mut len = sep.len() * (v.len() - 1);
-    for v.each |ss| {
-        len += ss.len();
-    }
-    let mut s = ~"", first = true;
+        s.reserve(len);
 
-    reserve(&mut s, len);
-
-    unsafe {
-        do as_buf(s) |buf, _len| {
-            do as_buf(sep) |sepbuf, seplen| {
-                let seplen = seplen - 1;
+        unsafe {
+            do as_buf(s) |buf, _| {
                 let mut buf = ::cast::transmute_mut_unsafe(buf);
-                for v.each |ss| {
-                    do as_buf(*ss) |ssbuf, sslen| {
+                for self.iter().advance |ss| {
+                    do as_buf(ss.as_slice()) |ssbuf, sslen| {
                         let sslen = sslen - 1;
-                        if first {
-                            first = false;
-                        } else {
-                            ptr::copy_memory(buf, sepbuf, seplen);
-                            buf = buf.offset(seplen);
-                        }
                         ptr::copy_memory(buf, ssbuf, sslen);
                         buf = buf.offset(sslen);
                     }
                 }
             }
+            raw::set_len(&mut s, len);
         }
-        raw::set_len(&mut s, len);
+        s
     }
-    s
-}
 
-/// Concatenate a vector of strings, placing a given separator between each
-pub fn connect_slices(v: &[&str], sep: &str) -> ~str {
-    if v.is_empty() { return ~""; }
+    /// Concatenate a vector of strings, placing a given separator between each.
+    pub fn connect(&self, sep: &str) -> ~str {
+        if self.is_empty() { return ~""; }
 
-    // this is wrong without the guarantee that v is non-empty
-    let mut len = sep.len() * (v.len() - 1);
-    for v.each |ss| {
-        len += ss.len();
-    }
-    let mut s = ~"", first = true;
+        // concat is faster
+        if sep.is_empty() { return self.concat(); }
 
-    reserve(&mut s, len);
+        // this is wrong without the guarantee that `self` is non-empty
+        let len = sep.len() * (self.len() - 1)
+            + self.iter().transform(|s| s.as_slice().len()).sum();
+        let mut s = ~"";
+        let mut first = true;
 
-    unsafe {
-        do as_buf(s) |buf, _len| {
-            do as_buf(sep) |sepbuf, seplen| {
-                let seplen = seplen - 1;
-                let mut buf = ::cast::transmute_mut_unsafe(buf);
-                for v.each |ss| {
-                    do as_buf(*ss) |ssbuf, sslen| {
-                        let sslen = sslen - 1;
-                        if first {
-                            first = false;
-                        } else if seplen > 0 {
-                            ptr::copy_memory(buf, sepbuf, seplen);
-                            buf = buf.offset(seplen);
+        s.reserve(len);
+
+        unsafe {
+            do as_buf(s) |buf, _| {
+                do as_buf(sep) |sepbuf, seplen| {
+                    let seplen = seplen - 1;
+                    let mut buf = ::cast::transmute_mut_unsafe(buf);
+                    for self.iter().advance |ss| {
+                        do as_buf(ss.as_slice()) |ssbuf, sslen| {
+                            let sslen = sslen - 1;
+                            if first {
+                                first = false;
+                            } else {
+                                ptr::copy_memory(buf, sepbuf, seplen);
+                                buf = buf.offset(seplen);
+                            }
+                            ptr::copy_memory(buf, ssbuf, sslen);
+                            buf = buf.offset(sslen);
                         }
-                        ptr::copy_memory(buf, ssbuf, sslen);
-                        buf = buf.offset(sslen);
                     }
                 }
             }
+            raw::set_len(&mut s, len);
         }
-        raw::set_len(&mut s, len);
+        s
     }
-    s
 }
 
-/// Given a string, make a new string with repeated copies of it
-pub fn repeat(ss: &str, nn: uint) -> ~str {
-    do as_buf(ss) |buf, len| {
-        let mut ret = ~"";
-        // ignore the NULL terminator
-        let len = len - 1;
-        reserve(&mut ret, nn * len);
-
-        unsafe {
-            do as_buf(ret) |rbuf, _len| {
-                let mut rbuf = ::cast::transmute_mut_unsafe(rbuf);
-
-                for nn.times {
-                    ptr::copy_memory(rbuf, buf, len);
-                    rbuf = rbuf.offset(len);
-                }
-            }
-            raw::set_len(&mut ret, nn * len);
-        }
-        ret
-    }
-}
-
-/*
-Section: Adding to and removing from a string
-*/
-
-/**
- * Remove the final character from a string and return it
- *
- * # Failure
- *
- * If the string does not contain any characters
- */
-pub fn pop_char(s: &mut ~str) -> char {
-    let end = len(*s);
-    assert!(end > 0u);
-    let CharRange {ch, next} = char_range_at_reverse(*s, end);
-    unsafe { raw::set_len(s, next); }
-    return ch;
-}
-
-/**
- * Remove the first character from a string and return it
- *
- * # Failure
- *
- * If the string does not contain any characters
- */
-pub fn shift_char(s: &mut ~str) -> char {
-    let CharRange {ch, next} = char_range_at(*s, 0u);
-    *s = unsafe { raw::slice_bytes_owned(*s, next, len(*s)) };
-    return ch;
-}
-
-/**
- * Removes the first character from a string slice and returns it. This does
- * not allocate a new string; instead, it mutates a slice to point one
- * character beyond the character that was shifted.
- *
- * # Failure
- *
- * If the string does not contain any characters
- */
-#[inline]
-pub fn slice_shift_char<'a>(s: &'a str) -> (char, &'a str) {
-    let CharRange {ch, next} = char_range_at(s, 0u);
-    let next_s = unsafe { raw::slice_bytes(s, next, len(s)) };
-    return (ch, next_s);
-}
-
-/// Prepend a char to a string
-pub fn unshift_char(s: &mut ~str, ch: char) {
-    // This could be more efficient.
-    let mut new_str = ~"";
-    new_str.push_char(ch);
-    new_str.push_str(*s);
-    *s = new_str;
-}
-
-/**
- * Returns a string with leading `chars_to_trim` removed.
- *
- * # Arguments
- *
- * * s - A string
- * * chars_to_trim - A vector of chars
- *
- */
-pub fn trim_left_chars<'a>(s: &'a str, chars_to_trim: &[char]) -> &'a str {
-    if chars_to_trim.is_empty() { return s; }
-
-    match find(s, |c| !chars_to_trim.contains(&c)) {
-      None => "",
-      Some(first) => unsafe { raw::slice_bytes(s, first, s.len()) }
-    }
-}
-
-/**
- * Returns a string with trailing `chars_to_trim` removed.
- *
- * # Arguments
- *
- * * s - A string
- * * chars_to_trim - A vector of chars
- *
- */
-pub fn trim_right_chars<'a>(s: &'a str, chars_to_trim: &[char]) -> &'a str {
-    if chars_to_trim.is_empty() { return s; }
-
-    match rfind(s, |c| !chars_to_trim.contains(&c)) {
-      None => "",
-      Some(last) => {
-        let next = char_range_at(s, last).next;
-        unsafe { raw::slice_bytes(s, 0u, next) }
-      }
-    }
-}
-
-/**
- * Returns a string with leading and trailing `chars_to_trim` removed.
- *
- * # Arguments
- *
- * * s - A string
- * * chars_to_trim - A vector of chars
- *
- */
-pub fn trim_chars<'a>(s: &'a str, chars_to_trim: &[char]) -> &'a str {
-    trim_left_chars(trim_right_chars(s, chars_to_trim), chars_to_trim)
+/// Something that can be used to compare against a character
+pub trait CharEq {
+    /// Determine if the splitter should split at the given character
+    fn matches(&self, char) -> bool;
+    /// Indicate if this is only concerned about ASCII characters,
+    /// which can allow for a faster implementation.
+    fn only_ascii(&self) -> bool;
 }
+impl CharEq for char {
+    #[inline(always)]
+    fn matches(&self, c: char) -> bool { *self == c }
 
-/// Returns a string with leading whitespace removed
-pub fn trim_left<'a>(s: &'a str) -> &'a str {
-    match find(s, |c| !char::is_whitespace(c)) {
-      None => "",
-      Some(first) => unsafe { raw::slice_bytes(s, first, len(s)) }
-    }
+    fn only_ascii(&self) -> bool { (*self as uint) < 128 }
 }
+impl<'self> CharEq for &'self fn(char) -> bool {
+    #[inline(always)]
+    fn matches(&self, c: char) -> bool { (*self)(c) }
 
-/// Returns a string with trailing whitespace removed
-pub fn trim_right<'a>(s: &'a str) -> &'a str {
-    match rfind(s, |c| !char::is_whitespace(c)) {
-      None => "",
-      Some(last) => {
-        let next = char_range_at(s, last).next;
-        unsafe { raw::slice_bytes(s, 0u, next) }
-      }
-    }
+    fn only_ascii(&self) -> bool { false }
 }
+impl CharEq for extern "Rust" fn(char) -> bool {
+    #[inline(always)]
+    fn matches(&self, c: char) -> bool { (*self)(c) }
 
-/// Returns a string with leading and trailing whitespace removed
-pub fn trim<'a>(s: &'a str) -> &'a str { trim_left(trim_right(s)) }
-
-/*
-Section: Transforming strings
-*/
-
-/**
- * Converts a string to a unique vector of bytes
- *
- * The result vector is not null-terminated.
- */
-pub fn to_bytes(s: &str) -> ~[u8] {
-    unsafe {
-        let mut v: ~[u8] = ::cast::transmute(to_owned(s));
-        vec::raw::set_len(&mut v, len(s));
-        v
-    }
+    fn only_ascii(&self) -> bool { false }
 }
 
-/// Work with the string as a byte slice, not including trailing null.
-#[inline(always)]
-pub fn byte_slice<T>(s: &str, f: &fn(v: &[u8]) -> T) -> T {
-    do as_buf(s) |p,n| {
-        unsafe { vec::raw::buf_as_slice(p, n-1u, f) }
+impl<'self, C: CharEq> CharEq for &'self [C] {
+    #[inline(always)]
+    fn matches(&self, c: char) -> bool {
+        self.iter().any_(|m| m.matches(c))
     }
-}
 
-/// Work with the string as a byte slice, not including trailing null, without
-/// a callback.
-#[inline(always)]
-pub fn byte_slice_no_callback<'a>(s: &'a str) -> &'a [u8] {
-    unsafe {
-        cast::transmute(s)
+    fn only_ascii(&self) -> bool {
+        self.iter().all(|m| m.only_ascii())
     }
 }
 
-/// Convert a string to a unique vector of characters
-pub fn to_chars(s: &str) -> ~[char] {
-    let mut buf = ~[];
-    for each_char(s) |c| {
-        buf.push(c);
-    }
-    buf
-}
 
-/**
- * Take a substring of another.
- *
- * Returns a slice pointing at `n` characters starting from byte offset
- * `begin`.
- */
-pub fn substr<'a>(s: &'a str, begin: uint, n: uint) -> &'a str {
-    slice(s, begin, begin + count_bytes(s, begin, n))
-}
-
-/**
- * Returns a slice of the given string from the byte range [`begin`..`end`)
- *
- * Fails when `begin` and `end` do not point to valid characters or beyond
- * the last character of the string
- */
-pub fn slice<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
-    assert!(is_char_boundary(s, begin));
-    assert!(is_char_boundary(s, end));
-    unsafe { raw::slice_bytes(s, begin, end) }
-}
-
-/// Splits a string into substrings at each occurrence of a given character
-pub fn each_split_char<'a>(s: &'a str, sep: char,
-                           it: &fn(&'a str) -> bool) -> bool {
-    each_split_char_inner(s, sep, len(s), true, true, it)
-}
-
-/// Like `each_split_char`, but a trailing empty string is omitted
-pub fn each_split_char_no_trailing<'a>(s: &'a str,
-                                       sep: char,
-                                       it: &fn(&'a str) -> bool) -> bool {
-    each_split_char_inner(s, sep, len(s), true, false, it)
-}
-
-/**
- * Splits a string into substrings at each occurrence of a given
- * character up to 'count' times.
- *
- * The character must be a valid UTF-8/ASCII character
- */
-pub fn each_splitn_char<'a>(s: &'a str,
-                            sep: char,
-                            count: uint,
-                            it: &fn(&'a str) -> bool) -> bool {
-    each_split_char_inner(s, sep, count, true, true, it)
-}
-
-/// Like `each_split_char`, but omits empty strings
-pub fn each_split_char_nonempty<'a>(s: &'a str,
-                                    sep: char,
-                                    it: &fn(&'a str) -> bool) -> bool {
-    each_split_char_inner(s, sep, len(s), false, false, it)
-}
-
-fn each_split_char_inner<'a>(s: &'a str,
-                             sep: char,
-                             count: uint,
-                             allow_empty: bool,
-                             allow_trailing_empty: bool,
-                             it: &fn(&'a str) -> bool) -> bool {
-    if sep < 128u as char {
-        let b = sep as u8, l = len(s);
-        let mut done = 0u;
-        let mut i = 0u, start = 0u;
-        while i < l && done < count {
-            if s[i] == b {
-                if allow_empty || start < i {
-                    if !it( unsafe{ raw::slice_bytes(s, start, i) } ) {
-                        return false;
-                    }
+/// An iterator over the substrings of a string, separated by `sep`.
+pub struct StrCharSplitIterator<'self,Sep> {
+    priv string: &'self str,
+    priv position: uint,
+    priv sep: Sep,
+    /// The number of splits remaining
+    priv count: uint,
+    /// Whether an empty string at the end is allowed
+    priv allow_trailing_empty: bool,
+    priv finished: bool,
+    priv only_ascii: bool
+}
+
+/// An iterator over the words of a string, separated by an sequence of whitespace
+pub type WordIterator<'self> =
+    FilterIterator<'self, &'self str,
+             StrCharSplitIterator<'self, extern "Rust" fn(char) -> bool>>;
+
+impl<'self, Sep: CharEq> Iterator<&'self str> for StrCharSplitIterator<'self, Sep> {
+    #[inline]
+    fn next(&mut self) -> Option<&'self str> {
+        if self.finished { return None }
+
+        let l = self.string.len();
+        let start = self.position;
+
+        if self.only_ascii {
+            // this gives a *huge* speed up for splitting on ASCII
+            // characters (e.g. '\n' or ' ')
+            while self.position < l && self.count > 0 {
+                let byte = self.string[self.position];
+
+                if self.sep.matches(byte as char) {
+                    let slice = unsafe { raw::slice_bytes(self.string, start, self.position) };
+                    self.position += 1;
+                    self.count -= 1;
+                    return Some(slice);
                 }
-                start = i + 1u;
-                done += 1u;
+                self.position += 1;
+            }
+        } else {
+            while self.position < l && self.count > 0 {
+                let CharRange {ch, next} = self.string.char_range_at(self.position);
+
+                if self.sep.matches(ch) {
+                    let slice = unsafe { raw::slice_bytes(self.string, start, self.position) };
+                    self.position = next;
+                    self.count -= 1;
+                    return Some(slice);
+                }
+                self.position = next;
             }
-            i += 1u;
         }
-        // only slice a non-empty trailing substring
-        if allow_trailing_empty || start < l {
-            if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return false; }
+        self.finished = true;
+        if self.allow_trailing_empty || start < l {
+            Some(unsafe { raw::slice_bytes(self.string, start, l) })
+        } else {
+            None
         }
-        return true;
     }
-    return each_split_inner(s, |cur| cur == sep, count,
-                            allow_empty, allow_trailing_empty, it)
 }
 
-/// Splits a string into substrings using a character function
-pub fn each_split<'a>(s: &'a str,
-                      sepfn: &fn(char) -> bool,
-                      it: &fn(&'a str) -> bool) -> bool {
-    each_split_inner(s, sepfn, len(s), true, true, it)
+/// An iterator over the start and end indicies of the matches of a
+/// substring within a larger string
+pub struct StrMatchesIndexIterator<'self> {
+    priv haystack: &'self str,
+    priv needle: &'self str,
+    priv position: uint,
 }
 
-/// Like `each_split`, but a trailing empty string is omitted
-pub fn each_split_no_trailing<'a>(s: &'a str,
-                                  sepfn: &fn(char) -> bool,
-                                  it: &fn(&'a str) -> bool) -> bool {
-    each_split_inner(s, sepfn, len(s), true, false, it)
+/// An iterator over the substrings of a string separated by a given
+/// search string
+pub struct StrStrSplitIterator<'self> {
+    priv it: StrMatchesIndexIterator<'self>,
+    priv last_end: uint,
+    priv finished: bool
 }
 
-/**
- * Splits a string into substrings using a character function, cutting at
- * most `count` times.
- */
-pub fn each_splitn<'a>(s: &'a str,
-                       sepfn: &fn(char) -> bool,
-                       count: uint,
-                       it: &fn(&'a str) -> bool) -> bool {
-    each_split_inner(s, sepfn, count, true, true, it)
-}
-
-/// Like `each_split`, but omits empty strings
-pub fn each_split_nonempty<'a>(s: &'a str,
-                               sepfn: &fn(char) -> bool,
-                               it: &fn(&'a str) -> bool) -> bool {
-    each_split_inner(s, sepfn, len(s), false, false, it)
-}
-
-fn each_split_inner<'a>(s: &'a str,
-                        sepfn: &fn(cc: char) -> bool,
-                        count: uint,
-                        allow_empty: bool,
-                        allow_trailing_empty: bool,
-                        it: &fn(&'a str) -> bool) -> bool {
-    let l = len(s);
-    let mut i = 0u, start = 0u, done = 0u;
-    while i < l && done < count {
-        let CharRange {ch, next} = char_range_at(s, i);
-        if sepfn(ch) {
-            if allow_empty || start < i {
-                if !it( unsafe{ raw::slice_bytes(s, start, i) } ) {
-                    return false;
+impl<'self> Iterator<(uint, uint)> for StrMatchesIndexIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<(uint, uint)> {
+        // See Issue #1932 for why this is a naive search
+        let (h_len, n_len) = (self.haystack.len(), self.needle.len());
+        let mut (match_start, match_i) = (0, 0);
+
+        while self.position < h_len {
+            if self.haystack[self.position] == self.needle[match_i] {
+                if match_i == 0 { match_start = self.position; }
+                match_i += 1;
+                self.position += 1;
+
+                if match_i == n_len {
+                    // found a match!
+                    return Some((match_start, self.position));
+                }
+            } else {
+                // failed match, backtrack
+                if match_i > 0 {
+                    match_i = 0;
+                    self.position = match_start;
                 }
+                self.position += 1;
             }
-            start = next;
-            done += 1u;
         }
-        i = next;
+        None
     }
-    if allow_trailing_empty || start < l {
-        if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return false; }
-    }
-    return true;
 }
 
-// See Issue #1932 for why this is a naive search
-fn iter_matches<'a,'b>(s: &'a str, sep: &'b str,
-                       f: &fn(uint, uint) -> bool) -> bool {
-    let sep_len = len(sep), l = len(s);
-    assert!(sep_len > 0u);
-    let mut i = 0u, match_start = 0u, match_i = 0u;
-
-    while i < l {
-        if s[i] == sep[match_i] {
-            if match_i == 0u { match_start = i; }
-            match_i += 1u;
-            // Found a match
-            if match_i == sep_len {
-                if !f(match_start, i + 1u) { return false; }
-                match_i = 0u;
+impl<'self> Iterator<&'self str> for StrStrSplitIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<&'self str> {
+        if self.finished { return None; }
+
+        match self.it.next() {
+            Some((from, to)) => {
+                let ret = Some(self.it.haystack.slice(self.last_end, from));
+                self.last_end = to;
+                ret
             }
-            i += 1u;
-        } else {
-            // Failed match, backtrack
-            if match_i > 0u {
-                match_i = 0u;
-                i = match_start + 1u;
-            } else {
-                i += 1u;
+            None => {
+                self.finished = true;
+                Some(self.it.haystack.slice(self.last_end, self.it.haystack.len()))
             }
         }
     }
-    return true;
-}
-
-fn iter_between_matches<'a,'b>(s: &'a str,
-                               sep: &'b str,
-                               f: &fn(uint, uint) -> bool) -> bool {
-    let mut last_end = 0u;
-    for iter_matches(s, sep) |from, to| {
-        if !f(last_end, from) { return false; }
-        last_end = to;
-    }
-    return f(last_end, len(s));
-}
-
-/**
- * Splits a string into a vector of the substrings separated by a given string
- *
- * # Example
- *
- * ~~~ {.rust}
- * let mut v = ~[];
- * for each_split_str(".XXX.YYY.", ".") |subs| { v.push(subs); }
- * assert!(v == ["", "XXX", "YYY", ""]);
- * ~~~
- */
-pub fn each_split_str<'a,'b>(s: &'a str,
-                             sep: &'b str,
-                             it: &fn(&'a str) -> bool) -> bool {
-    for iter_between_matches(s, sep) |from, to| {
-        if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return false; }
-    }
-    return true;
-}
-
-pub fn each_split_str_nonempty<'a,'b>(s: &'a str,
-                                      sep: &'b str,
-                                      it: &fn(&'a str) -> bool) -> bool {
-    for iter_between_matches(s, sep) |from, to| {
-        if to > from {
-            if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return false; }
-        }
-    }
-    return true;
 }
 
 /// Levenshtein Distance between two strings
@@ -763,12 +411,12 @@ pub fn levdistance(s: &str, t: &str) -> uint {
 
     let mut dcol = vec::from_fn(tlen + 1, |x| x);
 
-    for s.each_chari |i, sc| {
+    for s.iter().enumerate().advance |(i, sc)| {
 
         let mut current = i;
         dcol[0] = current + 1;
 
-        for t.each_chari |j, tc| {
+        for t.iter().enumerate().advance |(j, tc)| {
 
             let next = dcol[j + 1];
 
@@ -787,18 +435,11 @@ pub fn levdistance(s: &str, t: &str) -> uint {
 }
 
 /**
- * Splits a string into substrings separated by LF ('\n').
- */
-pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
-    each_split_char_no_trailing(s, '\n', it)
-}
-
-/**
  * Splits a string into substrings separated by LF ('\n')
  * and/or CR LF ("\r\n")
  */
 pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
-    for each_line(s) |s| {
+    for s.line_iter().advance |s| {
         let l = s.len();
         if l > 0u && s[l - 1u] == '\r' as u8 {
             if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return false; }
@@ -809,11 +450,6 @@ pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
     return true;
 }
 
-/// Splits a string into substrings separated by whitespace
-pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
-    each_split_nonempty(s, char::is_whitespace, it)
-}
-
 /** Splits a string into substrings with possibly internal whitespace,
  *  each of them at most `lim` bytes long. The substrings have leading and trailing
  *  whitespace removed, and are only cut at whitespace boundaries.
@@ -823,7 +459,7 @@ pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
  *  Fails during iteration if the string contains a non-whitespace
  *  sequence longer than the limit.
  */
-pub fn _each_split_within<'a>(ss: &'a str,
+pub fn each_split_within<'a>(ss: &'a str,
                               lim: uint,
                               it: &fn(&'a str) -> bool) -> bool {
     // Just for fun, let's write this as an state machine:
@@ -848,9 +484,9 @@ pub fn _each_split_within<'a>(ss: &'a str,
     let mut state = A;
 
     let mut cont = true;
-    let slice: &fn() = || { cont = it(slice(ss, slice_start, last_end)) };
+    let slice: &fn() = || { cont = it(ss.slice(slice_start, last_end)) };
 
-    let machine: &fn(uint, char) -> bool = |i, c| {
+    let machine: &fn((uint, char)) -> bool = |(i, c)| {
         let whitespace = if char::is_whitespace(c)       { Ws }       else { Cr };
         let limit      = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };
 
@@ -861,7 +497,7 @@ pub fn _each_split_within<'a>(ss: &'a str,
             (B, Cr, UnderLim) => { B }
             (B, Cr, OverLim)  if (i - last_start + 1) > lim
                               => fail!("word starting with %? longer than limit!",
-                                       self::slice(ss, last_start, i + 1)),
+                                       ss.slice(last_start, i + 1)),
             (B, Cr, OverLim)  => { slice(); slice_start = last_start; B }
             (B, Ws, UnderLim) => { last_end = i; C }
             (B, Ws, OverLim)  => { last_end = i; slice(); A }
@@ -875,49 +511,17 @@ pub fn _each_split_within<'a>(ss: &'a str,
         cont
     };
 
-    str::each_chari(ss, machine);
+    ss.iter().enumerate().advance(machine);
 
     // Let the automaton 'run out' by supplying trailing whitespace
     let mut fake_i = ss.len();
     while cont && match state { B | C => true, A => false } {
-        machine(fake_i, ' ');
+        machine((fake_i, ' '));
         fake_i += 1;
     }
     return cont;
 }
 
-pub fn each_split_within<'a>(ss: &'a str,
-                             lim: uint,
-                             it: &fn(&'a str) -> bool) -> bool {
-    _each_split_within(ss, lim, it)
-}
-
-/**
- * Replace all occurrences of one string with another
- *
- * # Arguments
- *
- * * s - The string containing substrings to replace
- * * from - The string to replace
- * * to - The replacement string
- *
- * # Return value
- *
- * The original string with all occurances of `from` replaced with `to`
- */
-pub fn replace(s: &str, from: &str, to: &str) -> ~str {
-    let mut result = ~"", first = true;
-    for iter_between_matches(s, from) |start, end| {
-        if first {
-            first = false;
-        } else {
-            push_str(&mut result, to);
-        }
-        push_str(&mut result, unsafe{raw::slice_bytes(s, start, end)});
-    }
-    result
-}
-
 /*
 Section: Comparing strings
 */
@@ -1131,622 +735,48 @@ impl Ord for @str {
 }
 
 #[cfg(not(test))]
-impl<'self> Equiv<~str> for &'self str {
+impl<'self, S: Str> Equiv<S> for &'self str {
+    #[inline(always)]
+    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+}
+#[cfg(not(test))]
+impl<'self, S: Str> Equiv<S> for @str {
+    #[inline(always)]
+    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+}
+
+#[cfg(not(test))]
+impl<'self, S: Str> Equiv<S> for ~str {
     #[inline(always)]
-    fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) }
+    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
 }
 
+
 /*
 Section: Iterating through strings
 */
 
-/**
- * Return true if a predicate matches all characters or if the string
- * contains no characters
- */
-pub fn all(s: &str, it: &fn(char) -> bool) -> bool {
-    all_between(s, 0u, len(s), it)
-}
-
-/**
- * Return true if a predicate matches any character (and false if it
- * matches none or there are no characters)
- */
-pub fn any(ss: &str, pred: &fn(char) -> bool) -> bool {
-    !all(ss, |cc| !pred(cc))
-}
-
 /// Apply a function to each character
 pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str {
     let mut result = ~"";
-    reserve(&mut result, len(ss));
-    for ss.each_char |cc| {
-        str::push_char(&mut result, ff(cc));
+    result.reserve(ss.len());
+    for ss.iter().advance |cc| {
+        result.push_char(ff(cc));
     }
     result
 }
 
-/// Iterate over the bytes in a string
-#[inline(always)]
-pub fn each(s: &str, it: &fn(u8) -> bool) -> bool {
-    eachi(s, |_i, b| it(b))
-}
-
-/// Iterate over the bytes in a string, with indices
-#[inline(always)]
-pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) -> bool {
-    let mut pos = 0;
-    let len = s.len();
-
-    while pos < len {
-        if !it(pos, s[pos]) { return false; }
-        pos += 1;
-    }
-    return true;
-}
-
-/// Iterate over the bytes in a string in reverse
-#[inline(always)]
-pub fn each_reverse(s: &str, it: &fn(u8) -> bool) -> bool {
-    eachi_reverse(s, |_i, b| it(b) )
-}
-
-/// Iterate over the bytes in a string in reverse, with indices
-#[inline(always)]
-pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) -> bool {
-    let mut pos = s.len();
-    while pos > 0 {
-        pos -= 1;
-        if !it(pos, s[pos]) { return false; }
-    }
-    return true;
-}
-
-/// Iterate over each char of a string, without allocating
-#[inline(always)]
-pub fn each_char(s: &str, it: &fn(char) -> bool) -> bool {
-    let mut i = 0;
-    let len = len(s);
-    while i < len {
-        let CharRange {ch, next} = char_range_at(s, i);
-        if !it(ch) { return false; }
-        i = next;
-    }
-    return true;
-}
-
-/// Iterates over the chars in a string, with indices
-#[inline(always)]
-pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) -> bool {
-    let mut pos = 0;
-    let mut ch_pos = 0u;
-    let len = s.len();
-    while pos < len {
-        let CharRange {ch, next} = char_range_at(s, pos);
-        pos = next;
-        if !it(ch_pos, ch) { return false; }
-        ch_pos += 1u;
-    }
-    return true;
-}
-
-/// Iterates over the chars in a string in reverse
-#[inline(always)]
-pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) -> bool {
-    each_chari_reverse(s, |_, c| it(c))
-}
-
-// Iterates over the chars in a string in reverse, with indices
-#[inline(always)]
-pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) -> bool {
-    let mut pos = s.len();
-    let mut ch_pos = s.char_len();
-    while pos > 0 {
-        let CharRange {ch, next} = char_range_at_reverse(s, pos);
-        pos = next;
-        ch_pos -= 1;
-
-        if !it(ch_pos, ch) { return false; }
-    }
-    return true;
-}
-
 /*
 Section: Searching
 */
 
-/**
- * Returns the byte index of the first matching character
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `c` - The character to search for
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching character
- * or `none` if there is no match
- */
-pub fn find_char(s: &str, c: char) -> Option<uint> {
-    find_char_between(s, c, 0u, len(s))
-}
-
-/**
- * Returns the byte index of the first matching character beginning
- * from a given byte offset
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `c` - The character to search for
- * * `start` - The byte index to begin searching at, inclusive
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `len(s)`. `start` must be the
- * index of a character boundary, as defined by `is_char_boundary`.
- */
-pub fn find_char_from(s: &str, c: char, start: uint) -> Option<uint> {
-    find_char_between(s, c, start, len(s))
-}
-
-/**
- * Returns the byte index of the first matching character within a given range
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `c` - The character to search for
- * * `start` - The byte index to begin searching at, inclusive
- * * `end` - The byte index to end searching at, exclusive
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `end` and `end` must be less than
- * or equal to `len(s)`. `start` must be the index of a character boundary,
- * as defined by `is_char_boundary`.
- */
-pub fn find_char_between(s: &str, c: char, start: uint, end: uint)
-    -> Option<uint> {
-    if c < 128u as char {
-        assert!(start <= end);
-        assert!(end <= len(s));
-        let mut i = start;
-        let b = c as u8;
-        while i < end {
-            if s[i] == b { return Some(i); }
-            i += 1u;
-        }
-        return None;
-    } else {
-        find_between(s, start, end, |x| x == c)
-    }
-}
-
-/**
- * Returns the byte index of the last matching character
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `c` - The character to search for
- *
- * # Return value
- *
- * An `option` containing the byte index of the last matching character
- * or `none` if there is no match
- */
-pub fn rfind_char(s: &str, c: char) -> Option<uint> {
-    rfind_char_between(s, c, len(s), 0u)
-}
-
-/**
- * Returns the byte index of the last matching character beginning
- * from a given byte offset
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `c` - The character to search for
- * * `start` - The byte index to begin searching at, exclusive
- *
- * # Return value
- *
- * An `option` containing the byte index of the last matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `len(s)`. `start` must be
- * the index of a character boundary, as defined by `is_char_boundary`.
- */
-pub fn rfind_char_from(s: &str, c: char, start: uint) -> Option<uint> {
-    rfind_char_between(s, c, start, 0u)
-}
-
-/**
- * Returns the byte index of the last matching character within a given range
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `c` - The character to search for
- * * `start` - The byte index to begin searching at, exclusive
- * * `end` - The byte index to end searching at, inclusive
- *
- * # Return value
- *
- * An `option` containing the byte index of the last matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `end` must be less than or equal to `start` and `start` must be less than
- * or equal to `len(s)`. `start` must be the index of a character boundary,
- * as defined by `is_char_boundary`.
- */
-pub fn rfind_char_between(s: &str, c: char, start: uint, end: uint) -> Option<uint> {
-    if c < 128u as char {
-        assert!(start >= end);
-        assert!(start <= len(s));
-        let mut i = start;
-        let b = c as u8;
-        while i > end {
-            i -= 1u;
-            if s[i] == b { return Some(i); }
-        }
-        return None;
-    } else {
-        rfind_between(s, start, end, |x| x == c)
-    }
-}
-
-/**
- * Returns the byte index of the first character that satisfies
- * the given predicate
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `f` - The predicate to satisfy
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching character
- * or `none` if there is no match
- */
-pub fn find(s: &str, f: &fn(char) -> bool) -> Option<uint> {
-    find_between(s, 0u, len(s), f)
-}
-
-/**
- * Returns the byte index of the first character that satisfies
- * the given predicate, beginning from a given byte offset
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `start` - The byte index to begin searching at, inclusive
- * * `f` - The predicate to satisfy
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching charactor
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `len(s)`. `start` must be the
- * index of a character boundary, as defined by `is_char_boundary`.
- */
-pub fn find_from(s: &str, start: uint, f: &fn(char)
-    -> bool) -> Option<uint> {
-    find_between(s, start, len(s), f)
-}
-
-/**
- * Returns the byte index of the first character that satisfies
- * the given predicate, within a given range
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `start` - The byte index to begin searching at, inclusive
- * * `end` - The byte index to end searching at, exclusive
- * * `f` - The predicate to satisfy
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `end` and `end` must be less than
- * or equal to `len(s)`. `start` must be the index of a character
- * boundary, as defined by `is_char_boundary`.
- */
-pub fn find_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) -> Option<uint> {
-    assert!(start <= end);
-    assert!(end <= len(s));
-    assert!(is_char_boundary(s, start));
-    let mut i = start;
-    while i < end {
-        let CharRange {ch, next} = char_range_at(s, i);
-        if f(ch) { return Some(i); }
-        i = next;
-    }
-    return None;
-}
-
-/**
- * Returns the byte index of the last character that satisfies
- * the given predicate
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `f` - The predicate to satisfy
- *
- * # Return value
- *
- * An option containing the byte index of the last matching character
- * or `none` if there is no match
- */
-pub fn rfind(s: &str, f: &fn(char) -> bool) -> Option<uint> {
-    rfind_between(s, len(s), 0u, f)
-}
-
-/**
- * Returns the byte index of the last character that satisfies
- * the given predicate, beginning from a given byte offset
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `start` - The byte index to begin searching at, exclusive
- * * `f` - The predicate to satisfy
- *
- * # Return value
- *
- * An `option` containing the byte index of the last matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `len(s)', `start` must be the
- * index of a character boundary, as defined by `is_char_boundary`
- */
-pub fn rfind_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option<uint> {
-    rfind_between(s, start, 0u, f)
-}
-
-/**
- * Returns the byte index of the last character that satisfies
- * the given predicate, within a given range
- *
- * # Arguments
- *
- * * `s` - The string to search
- * * `start` - The byte index to begin searching at, exclusive
- * * `end` - The byte index to end searching at, inclusive
- * * `f` - The predicate to satisfy
- *
- * # Return value
- *
- * An `option` containing the byte index of the last matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `end` must be less than or equal to `start` and `start` must be less
- * than or equal to `len(s)`. `start` must be the index of a character
- * boundary, as defined by `is_char_boundary`
- */
-pub fn rfind_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) -> Option<uint> {
-    assert!(start >= end);
-    assert!(start <= len(s));
-    assert!(is_char_boundary(s, start));
-    let mut i = start;
-    while i > end {
-        let CharRange {ch, next: prev} = char_range_at_reverse(s, i);
-        if f(ch) { return Some(prev); }
-        i = prev;
-    }
-    return None;
-}
-
 // Utility used by various searching functions
 fn match_at<'a,'b>(haystack: &'a str, needle: &'b str, at: uint) -> bool {
     let mut i = at;
-    for each(needle) |c| { if haystack[i] != c { return false; } i += 1u; }
+    for needle.bytes_iter().advance |c| { if haystack[i] != c { return false; } i += 1u; }
     return true;
 }
 
-/**
- * Returns the byte index of the first matching substring
- *
- * # Arguments
- *
- * * `haystack` - The string to search
- * * `needle` - The string to search for
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching substring
- * or `none` if there is no match
- */
-pub fn find_str<'a,'b>(haystack: &'a str, needle: &'b str) -> Option<uint> {
-    find_str_between(haystack, needle, 0u, len(haystack))
-}
-
-/**
- * Returns the byte index of the first matching substring beginning
- * from a given byte offset
- *
- * # Arguments
- *
- * * `haystack` - The string to search
- * * `needle` - The string to search for
- * * `start` - The byte index to begin searching at, inclusive
- *
- * # Return value
- *
- * An `option` containing the byte index of the last matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `len(s)`
- */
-pub fn find_str_from<'a,'b>(haystack: &'a str,
-                            needle: &'b str,
-                            start: uint)
-                         -> Option<uint> {
-    find_str_between(haystack, needle, start, len(haystack))
-}
-
-/**
- * Returns the byte index of the first matching substring within a given range
- *
- * # Arguments
- *
- * * `haystack` - The string to search
- * * `needle` - The string to search for
- * * `start` - The byte index to begin searching at, inclusive
- * * `end` - The byte index to end searching at, exclusive
- *
- * # Return value
- *
- * An `option` containing the byte index of the first matching character
- * or `none` if there is no match
- *
- * # Failure
- *
- * `start` must be less than or equal to `end` and `end` must be less than
- * or equal to `len(s)`.
- */
-pub fn find_str_between<'a,'b>(haystack: &'a str,
-                               needle: &'b str,
-                               start: uint,
-                               end:uint)
-                            -> Option<uint> {
-    // See Issue #1932 for why this is a naive search
-    assert!(end <= len(haystack));
-    let needle_len = len(needle);
-    if needle_len == 0u { return Some(start); }
-    if needle_len > end { return None; }
-
-    let mut i = start;
-    let e = end - needle_len;
-    while i <= e {
-        if match_at(haystack, needle, i) { return Some(i); }
-        i += 1u;
-    }
-    return None;
-}
-
-/**
- * Returns true if one string contains another
- *
- * # Arguments
- *
- * * haystack - The string to look in
- * * needle - The string to look for
- */
-pub fn contains<'a,'b>(haystack: &'a str, needle: &'b str) -> bool {
-    find_str(haystack, needle).is_some()
-}
-
-/**
- * Returns true if a string contains a char.
- *
- * # Arguments
- *
- * * haystack - The string to look in
- * * needle - The char to look for
- */
-pub fn contains_char(haystack: &str, needle: char) -> bool {
-    find_char(haystack, needle).is_some()
-}
-
-/**
- * Returns true if one string starts with another
- *
- * # Arguments
- *
- * * haystack - The string to look in
- * * needle - The string to look for
- */
-pub fn starts_with<'a,'b>(haystack: &'a str, needle: &'b str) -> bool {
-    let haystack_len = len(haystack), needle_len = len(needle);
-    if needle_len == 0u { true }
-    else if needle_len > haystack_len { false }
-    else { match_at(haystack, needle, 0u) }
-}
-
-/**
- * Returns true if one string ends with another
- *
- * # Arguments
- *
- * * haystack - The string to look in
- * * needle - The string to look for
- */
-pub fn ends_with<'a,'b>(haystack: &'a str, needle: &'b str) -> bool {
-    let haystack_len = len(haystack), needle_len = len(needle);
-    if needle_len == 0u { true }
-    else if needle_len > haystack_len { false }
-    else { match_at(haystack, needle, haystack_len - needle_len) }
-}
-
-/*
-Section: String properties
-*/
-
-/// Returns true if the string has length 0
-#[inline(always)]
-pub fn is_empty(s: &str) -> bool { len(s) == 0u }
-
-/**
- * Returns true if the string contains only whitespace
- *
- * Whitespace characters are determined by `char::is_whitespace`
- */
-pub fn is_whitespace(s: &str) -> bool {
-    return all(s, char::is_whitespace);
-}
-
-/**
- * Returns true if the string contains only alphanumerics
- *
- * Alphanumeric characters are determined by `char::is_alphanumeric`
- */
-fn is_alphanumeric(s: &str) -> bool {
-    return all(s, char::is_alphanumeric);
-}
-
-/// Returns the string length/size in bytes not counting the null terminator
-#[inline(always)]
-pub fn len(s: &str) -> uint {
-    do as_buf(s) |_p, n| { n - 1u }
-}
-
-/// Returns the number of characters that a string holds
-#[inline(always)]
-pub fn char_len(s: &str) -> uint { count_chars(s, 0u, len(s)) }
-
 /*
 Section: Misc
 */
@@ -1754,7 +784,7 @@ Section: Misc
 /// Determines if a vector of bytes contains valid UTF-8
 pub fn is_utf8(v: &const [u8]) -> bool {
     let mut i = 0u;
-    let total = vec::len::<u8>(v);
+    let total = v.len();
     while i < total {
         let mut chsize = utf8_char_width(v[i]);
         if chsize == 0u { return false; }
@@ -1793,7 +823,7 @@ pub fn is_utf16(v: &[u16]) -> bool {
 /// Converts to a vector of `u16` encoded as UTF-16
 pub fn to_utf16(s: &str) -> ~[u16] {
     let mut u = ~[];
-    for s.each_char |ch| {
+    for s.iter().advance |ch| {
         // Arithmetic with u32 literals is easier on the eyes than chars.
         let mut ch = ch as u32;
 
@@ -1814,6 +844,12 @@ pub fn to_utf16(s: &str) -> ~[u16] {
     u
 }
 
+/// Iterates over the utf-16 characters in the specified slice, yielding each
+/// decoded unicode character to the function provided.
+///
+/// # Failures
+///
+/// * Fails on invalid utf-16 data
 pub fn utf16_chars(v: &[u16], f: &fn(char)) {
     let len = v.len();
     let mut i = 0u;
@@ -1838,59 +874,26 @@ pub fn utf16_chars(v: &[u16], f: &fn(char)) {
     }
 }
 
+/**
+ * Allocates a new string from the utf-16 slice provided
+ */
 pub fn from_utf16(v: &[u16]) -> ~str {
     let mut buf = ~"";
-    reserve(&mut buf, v.len());
-    utf16_chars(v, |ch| push_char(&mut buf, ch));
+    buf.reserve(v.len());
+    utf16_chars(v, |ch| buf.push_char(ch));
     buf
 }
 
+/**
+ * Allocates a new string with the specified capacity. The string returned is
+ * the empty string, but has capacity for much more.
+ */
 pub fn with_capacity(capacity: uint) -> ~str {
     let mut buf = ~"";
-    reserve(&mut buf, capacity);
+    buf.reserve(capacity);
     buf
 }
 
-/**
- * As char_len but for a slice of a string
- *
- * # Arguments
- *
- * * s - A valid string
- * * start - The position inside `s` where to start counting in bytes
- * * end - The position where to stop counting
- *
- * # Return value
- *
- * The number of Unicode characters in `s` between the given indices.
- */
-pub fn count_chars(s: &str, start: uint, end: uint) -> uint {
-    assert!(is_char_boundary(s, start));
-    assert!(is_char_boundary(s, end));
-    let mut i = start, len = 0u;
-    while i < end {
-        let next = char_range_at(s, i).next;
-        len += 1u;
-        i = next;
-    }
-    return len;
-}
-
-/// Counts the number of bytes taken by the first `n` chars in `s`
-/// starting from `start`.
-pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint {
-    assert!(is_char_boundary(s, start));
-    let mut end = start, cnt = n;
-    let l = len(s);
-    while cnt > 0u {
-        assert!(end < l);
-        let next = char_range_at(s, end).next;
-        cnt -= 1u;
-        end = next;
-    }
-    end - start
-}
-
 /// Given a first byte, determine how many bytes are in this UTF-8 character
 pub fn utf8_char_width(b: u8) -> uint {
     let byte: uint = b as uint;
@@ -1904,189 +907,12 @@ pub fn utf8_char_width(b: u8) -> uint {
     return 6u;
 }
 
-/**
- * Returns false if the index points into the middle of a multi-byte
- * character sequence.
- */
-pub fn is_char_boundary(s: &str, index: uint) -> bool {
-    if index == len(s) { return true; }
-    let b = s[index];
-    return b < 128u8 || b >= 192u8;
-}
-
-/**
- * Pluck a character out of a string and return the index of the next
- * character.
- *
- * This function can be used to iterate over the unicode characters of a
- * string.
- *
- * # Example
- *
- * ~~~ {.rust}
- * let s = "中华Việt Nam";
- * let i = 0u;
- * while i < str::len(s) {
- *     let CharRange {ch, next} = str::char_range_at(s, i);
- *     std::io::println(fmt!("%u: %c",i,ch));
- *     i = next;
- * }
- * ~~~
- *
- * # Example output
- *
- * ~~~
- * 0: 中
- * 3: 华
- * 6: V
- * 7: i
- * 8: ệ
- * 11: t
- * 12:
- * 13: N
- * 14: a
- * 15: m
- * ~~~
- *
- * # Arguments
- *
- * * s - The string
- * * i - The byte offset of the char to extract
- *
- * # Return value
- *
- * A record {ch: char, next: uint} containing the char value and the byte
- * index of the next unicode character.
- *
- * # Failure
- *
- * If `i` is greater than or equal to the length of the string.
- * If `i` is not the index of the beginning of a valid UTF-8 character.
- */
-pub fn char_range_at(s: &str, i: uint) -> CharRange {
-    let b0 = s[i];
-    let w = utf8_char_width(b0);
-    assert!((w != 0u));
-    if w == 1u { return CharRange {ch: b0 as char, next: i + 1u}; }
-    let mut val = 0u;
-    let end = i + w;
-    let mut i = i + 1u;
-    while i < end {
-        let byte = s[i];
-        assert_eq!(byte & 192u8, tag_cont_u8);
-        val <<= 6u;
-        val += (byte & 63u8) as uint;
-        i += 1u;
-    }
-    // Clunky way to get the right bits from the first byte. Uses two shifts,
-    // the first to clip off the marker bits at the left of the byte, and then
-    // a second (as uint) to get it to the right position.
-    val += ((b0 << ((w + 1u) as u8)) as uint) << ((w - 1u) * 6u - w - 1u);
-    return CharRange {ch: val as char, next: i};
-}
-
-/// Plucks the character starting at the `i`th byte of a string
-pub fn char_at(s: &str, i: uint) -> char {
-    return char_range_at(s, i).ch;
-}
-
+#[allow(missing_doc)]
 pub struct CharRange {
     ch: char,
     next: uint
 }
 
-/**
- * Given a byte position and a str, return the previous char and its position.
- *
- * This function can be used to iterate over a unicode string in reverse.
- *
- * Returns 0 for next index if called on start index 0.
- */
-pub fn char_range_at_reverse(ss: &str, start: uint) -> CharRange {
-    let mut prev = start;
-
-    // while there is a previous byte == 10......
-    while prev > 0u && ss[prev - 1u] & 192u8 == tag_cont_u8 {
-        prev -= 1u;
-    }
-
-    // now refer to the initial byte of previous char
-    if prev > 0u {
-        prev -= 1u;
-    } else {
-        prev = 0u;
-    }
-
-
-    let ch = char_at(ss, prev);
-    return CharRange {ch:ch, next:prev};
-}
-
-/// Plucks the character ending at the `i`th byte of a string
-pub fn char_at_reverse(s: &str, i: uint) -> char {
-    char_range_at_reverse(s, i).ch
-}
-
-/**
- * Loop through a substring, char by char
- *
- * # Safety note
- *
- * * This function does not check whether the substring is valid.
- * * This function fails if `start` or `end` do not
- *   represent valid positions inside `s`
- *
- * # Arguments
- *
- * * s - A string to traverse. It may be empty.
- * * start - The byte offset at which to start in the string.
- * * end - The end of the range to traverse
- * * it - A block to execute with each consecutive character of `s`.
- *        Return `true` to continue, `false` to stop.
- *
- * # Return value
- *
- * `true` If execution proceeded correctly, `false` if it was interrupted,
- * that is if `it` returned `false` at any point.
- */
-pub fn all_between(s: &str, start: uint, end: uint,
-                    it: &fn(char) -> bool) -> bool {
-    assert!(is_char_boundary(s, start));
-    let mut i = start;
-    while i < end {
-        let CharRange {ch, next} = char_range_at(s, i);
-        if !it(ch) { return false; }
-        i = next;
-    }
-    return true;
-}
-
-/**
- * Loop through a substring, char by char
- *
- * # Safety note
- *
- * * This function does not check whether the substring is valid.
- * * This function fails if `start` or `end` do not
- *   represent valid positions inside `s`
- *
- * # Arguments
- *
- * * s - A string to traverse. It may be empty.
- * * start - The byte offset at which to start in the string.
- * * end - The end of the range to traverse
- * * it - A block to execute with each consecutive character of `s`.
- *        Return `true` to continue, `false` to stop.
- *
- * # Return value
- *
- * `true` if `it` returns `true` for any character
- */
-pub fn any_between(s: &str, start: uint, end: uint,
-                    it: &fn(char) -> bool) -> bool {
-    !all_between(s, start, end, |c| !it(c))
-}
-
 // UTF-8 tags and ranges
 static tag_cont_u8: u8 = 128u8;
 static tag_cont: uint = 128u;
@@ -2102,64 +928,48 @@ static max_five_b: uint = 67108864u;
 static tag_six_b: uint = 252u;
 
 /**
- * Work with the byte buffer of a string.
- *
- * Allows for unsafe manipulation of strings, which is useful for foreign
- * interop.
- *
- * # Example
- *
- * ~~~ {.rust}
- * let i = str::as_bytes("Hello World") { |bytes| bytes.len() };
- * ~~~
+ * A dummy trait to hold all the utility methods that we implement on strings.
  */
-#[inline]
-pub fn as_bytes<T>(s: &const ~str, f: &fn(&~[u8]) -> T) -> T {
-    unsafe {
-        let v: *~[u8] = cast::transmute(copy s);
-        f(&*v)
-    }
+pub trait StrUtil {
+    /**
+     * Work with the byte buffer of a string as a null-terminated C string.
+     *
+     * Allows for unsafe manipulation of strings, which is useful for foreign
+     * interop. This is similar to `str::as_buf`, but guarantees null-termination.
+     * If the given slice is not already null-terminated, this function will
+     * allocate a temporary, copy the slice, null terminate it, and pass
+     * that instead.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     * let s = "PATH".as_c_str(|path| libc::getenv(path));
+     * ~~~
+     */
+    fn as_c_str<T>(self, f: &fn(*libc::c_char) -> T) -> T;
 }
 
-/**
- * Work with the byte buffer of a string as a byte slice.
- *
- * The byte slice does not include the null terminator.
- */
-pub fn as_bytes_slice<'a>(s: &'a str) -> &'a [u8] {
-    unsafe {
-        let (ptr, len): (*u8, uint) = ::cast::transmute(s);
-        let outgoing_tuple: (*u8, uint) = (ptr, len - 1);
-        return ::cast::transmute(outgoing_tuple);
+impl<'self> StrUtil for &'self str {
+    #[inline]
+    fn as_c_str<T>(self, f: &fn(*libc::c_char) -> T) -> T {
+        do as_buf(self) |buf, len| {
+            // NB: len includes the trailing null.
+            assert!(len > 0);
+            if unsafe { *(ptr::offset(buf,len-1)) != 0 } {
+                to_owned(self).as_c_str(f)
+            } else {
+                f(buf as *libc::c_char)
+            }
+        }
     }
 }
 
 /**
- * Work with the byte buffer of a string as a null-terminated C string.
- *
- * Allows for unsafe manipulation of strings, which is useful for foreign
- * interop. This is similar to `str::as_buf`, but guarantees null-termination.
- * If the given slice is not already null-terminated, this function will
- * allocate a temporary, copy the slice, null terminate it, and pass
- * that instead.
- *
- * # Example
- *
- * ~~~ {.rust}
- * let s = str::as_c_str("PATH", { |path| libc::getenv(path) });
- * ~~~
+ * Deprecated. Use the `as_c_str` method on strings instead.
  */
-#[inline]
+#[inline(always)]
 pub fn as_c_str<T>(s: &str, f: &fn(*libc::c_char) -> T) -> T {
-    do as_buf(s) |buf, len| {
-        // NB: len includes the trailing null.
-        assert!(len > 0);
-        if unsafe { *(ptr::offset(buf,len-1)) != 0 } {
-            as_c_str(to_owned(s), f)
-        } else {
-            f(buf as *libc::c_char)
-        }
-    }
+    s.as_c_str(f)
 }
 
 /**
@@ -2187,7 +997,7 @@ pub fn as_buf<T>(s: &str, f: &fn(*u8, uint) -> T) -> T {
  * ~~~ {.rust}
  * let string = "a\nb\nc";
  * let mut lines = ~[];
- * for each_line(string) |line| { lines.push(line) }
+ * for string.line_iter().advance |line| { lines.push(line) }
  *
  * assert!(subslice_offset(string, lines[0]) == 0); // &"a"
  * assert!(subslice_offset(string, lines[1]) == 2); // &"b"
@@ -2198,7 +1008,10 @@ pub fn as_buf<T>(s: &str, f: &fn(*u8, uint) -> T) -> T {
 pub fn subslice_offset(outer: &str, inner: &str) -> uint {
     do as_buf(outer) |a, a_len| {
         do as_buf(inner) |b, b_len| {
-            let a_start: uint, a_end: uint, b_start: uint, b_end: uint;
+            let a_start: uint;
+            let a_end: uint;
+            let b_start: uint;
+            let b_end: uint;
             unsafe {
                 a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
                 b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
@@ -2210,99 +1023,18 @@ pub fn subslice_offset(outer: &str, inner: &str) -> uint {
     }
 }
 
-/**
- * Reserves capacity for exactly `n` bytes in the given string, not including
- * the null terminator.
- *
- * Assuming single-byte characters, the resulting string will be large
- * enough to hold a string of length `n`. To account for the null terminator,
- * the underlying buffer will have the size `n` + 1.
- *
- * If the capacity for `s` is already equal to or greater than the requested
- * capacity, then no action is taken.
- *
- * # Arguments
- *
- * * s - A string
- * * n - The number of bytes to reserve space for
- */
-#[inline(always)]
-pub fn reserve(s: &mut ~str, n: uint) {
-    unsafe {
-        let v: *mut ~[u8] = cast::transmute(s);
-        vec::reserve(&mut *v, n + 1);
-    }
-}
-
-/**
- * Reserves capacity for at least `n` bytes in the given string, not including
- * the null terminator.
- *
- * Assuming single-byte characters, the resulting string will be large
- * enough to hold a string of length `n`. To account for the null terminator,
- * the underlying buffer will have the size `n` + 1.
- *
- * This function will over-allocate in order to amortize the allocation costs
- * in scenarios where the caller may need to repeatedly reserve additional
- * space.
- *
- * If the capacity for `s` is already equal to or greater than the requested
- * capacity, then no action is taken.
- *
- * # Arguments
- *
- * * s - A string
- * * n - The number of bytes to reserve space for
- */
-#[inline(always)]
-pub fn reserve_at_least(s: &mut ~str, n: uint) {
-    reserve(s, uint::next_power_of_two(n + 1u) - 1u)
-}
-
-/**
- * Returns the number of single-byte characters the string can hold without
- * reallocating
- */
-pub fn capacity(s: &const ~str) -> uint {
-    do as_bytes(s) |buf| {
-        let vcap = vec::capacity(buf);
-        assert!(vcap > 0u);
-        vcap - 1u
-    }
-}
-
-/// Escape each char in `s` with char::escape_default.
-pub fn escape_default(s: &str) -> ~str {
-    let mut out: ~str = ~"";
-    reserve_at_least(&mut out, str::len(s));
-    for s.each_char |c| {
-        push_str(&mut out, char::escape_default(c));
-    }
-    out
-}
-
-/// Escape each char in `s` with char::escape_unicode.
-pub fn escape_unicode(s: &str) -> ~str {
-    let mut out: ~str = ~"";
-    reserve_at_least(&mut out, str::len(s));
-    for s.each_char |c| {
-        push_str(&mut out, char::escape_unicode(c));
-    }
-    out
-}
-
 /// Unsafe operations
 pub mod raw {
     use cast;
     use libc;
     use ptr;
     use str::raw;
-    use str::{as_buf, is_utf8, len, reserve_at_least};
+    use str::{as_buf, is_utf8};
     use vec;
 
     /// Create a Rust string from a null-terminated *u8 buffer
     pub unsafe fn from_buf(buf: *u8) -> ~str {
-        let mut curr = buf, i = 0u;
+        let mut (curr, i) = (buf, 0u);
         while *curr != 0u8 {
             i += 1u;
             curr = ptr::offset(buf, i);
@@ -2350,12 +1082,19 @@ pub mod raw {
     /// Converts a byte to a string.
     pub unsafe fn from_byte(u: u8) -> ~str { raw::from_bytes([u]) }
 
-    /// Form a slice from a *u8 buffer of the given length without copying.
-    pub unsafe fn buf_as_slice<T>(buf: *u8, len: uint,
-                              f: &fn(v: &str) -> T) -> T {
-        let v = (buf, len + 1);
+    /// Form a slice from a C string. Unsafe because the caller must ensure the
+    /// C string has the static lifetime, or else the return value may be
+    /// invalidated later.
+    pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
+        let s = s as *u8;
+        let mut (curr, len) = (s, 0u);
+        while *curr != 0u8 {
+            len += 1u;
+            curr = ptr::offset(s, len);
+        }
+        let v = (s, len + 1);
         assert!(is_utf8(::cast::transmute(v)));
-        f(::cast::transmute(v))
+        ::cast::transmute(v)
     }
 
     /**
@@ -2409,7 +1148,7 @@ pub mod raw {
     /// Appends a byte to a string. (Not UTF-8 safe).
     pub unsafe fn push_byte(s: &mut ~str, b: u8) {
         let new_len = s.len() + 1;
-        reserve_at_least(&mut *s, new_len);
+        s.reserve_at_least(new_len);
         do as_buf(*s) |buf, len| {
             let buf: *mut u8 = ::cast::transmute(buf);
             *ptr::mut_offset(buf, len) = b;
@@ -2420,13 +1159,13 @@ pub mod raw {
     /// Appends a vector of bytes to a string. (Not UTF-8 safe).
     unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
         let new_len = s.len() + bytes.len();
-        reserve_at_least(&mut *s, new_len);
+        s.reserve_at_least(new_len);
         for bytes.each |byte| { push_byte(&mut *s, *byte); }
     }
 
     /// Removes the last byte from a string and returns it. (Not UTF-8 safe).
     pub unsafe fn pop_byte(s: &mut ~str) -> u8 {
-        let len = len(*s);
+        let len = s.len();
         assert!((len > 0u));
         let b = s[len - 1u];
         set_len(s, len - 1u);
@@ -2435,7 +1174,7 @@ pub mod raw {
 
     /// Removes the first byte from a string and returns it. (Not UTF-8 safe).
     pub unsafe fn shift_byte(s: &mut ~str) -> u8 {
-        let len = len(*s);
+        let len = s.len();
         assert!((len > 0u));
         let b = s[0];
         *s = raw::slice_bytes_owned(*s, 1u, len);
@@ -2468,12 +1207,10 @@ pub mod raw {
 #[cfg(not(test))]
 pub mod traits {
     use ops::Add;
-    use str::append;
-
     impl<'self> Add<&'self str,~str> for ~str {
         #[inline(always)]
         fn add(&self, rhs: & &'self str) -> ~str {
-            append(copy *self, (*rhs))
+            self.append((*rhs))
         }
     }
 }
@@ -2481,141 +1218,258 @@ pub mod traits {
 #[cfg(test)]
 pub mod traits {}
 
+/// Any string that can be represented as a slice
+pub trait Str {
+    /// Work with `self` as a slice.
+    fn as_slice<'a>(&'a self) -> &'a str;
+}
+
+impl<'self> Str for &'self str {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a str { *self }
+}
+impl<'self> Str for ~str {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a str {
+        let s: &'a str = *self; s
+    }
+}
+impl<'self> Str for @str {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a str {
+        let s: &'a str = *self; s
+    }
+}
+
+#[allow(missing_doc)]
 pub trait StrSlice<'self> {
-    fn all(&self, it: &fn(char) -> bool) -> bool;
-    fn any(&self, it: &fn(char) -> bool) -> bool;
     fn contains<'a>(&self, needle: &'a str) -> bool;
     fn contains_char(&self, needle: char) -> bool;
-    fn char_iter(&self) -> StrCharIterator<'self>;
-    fn each(&self, it: &fn(u8) -> bool) -> bool;
-    fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool;
-    fn each_reverse(&self, it: &fn(u8) -> bool) -> bool;
-    fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool;
-    fn each_char(&self, it: &fn(char) -> bool) -> bool;
-    fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool;
-    fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool;
-    fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool;
+    fn iter(&self) -> StrCharIterator<'self>;
+    fn rev_iter(&self) -> StrCharRevIterator<'self>;
+    fn bytes_iter(&self) -> StrBytesIterator<'self>;
+    fn bytes_rev_iter(&self) -> StrBytesRevIterator<'self>;
+    fn split_iter<Sep: CharEq>(&self, sep: Sep) -> StrCharSplitIterator<'self, Sep>;
+    fn splitn_iter<Sep: CharEq>(&self, sep: Sep, count: uint) -> StrCharSplitIterator<'self, Sep>;
+    fn split_options_iter<Sep: CharEq>(&self, sep: Sep, count: uint, allow_trailing_empty: bool)
+        -> StrCharSplitIterator<'self, Sep>;
+    fn matches_index_iter(&self, sep: &'self str) -> StrMatchesIndexIterator<'self>;
+    fn split_str_iter(&self, &'self str) -> StrStrSplitIterator<'self>;
+    fn line_iter(&self) -> StrCharSplitIterator<'self, char>;
+    fn word_iter(&self) -> WordIterator<'self>;
     fn ends_with(&self, needle: &str) -> bool;
     fn is_empty(&self) -> bool;
     fn is_whitespace(&self) -> bool;
     fn is_alphanumeric(&self) -> bool;
     fn len(&self) -> uint;
     fn char_len(&self) -> uint;
+
     fn slice(&self, begin: uint, end: uint) -> &'self str;
-    fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) -> bool;
-    fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) -> bool;
-    fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) -> bool;
-    fn starts_with<'a>(&self, needle: &'a str) -> bool;
-    fn substr(&self, begin: uint, n: uint) -> &'self str;
+    fn slice_from(&self, begin: uint) -> &'self str;
+    fn slice_to(&self, end: uint) -> &'self str;
+
+    fn slice_chars(&self, begin: uint, end: uint) -> &'self str;
+
+    fn starts_with(&self, needle: &str) -> bool;
     fn escape_default(&self) -> ~str;
     fn escape_unicode(&self) -> ~str;
     fn trim(&self) -> &'self str;
     fn trim_left(&self) -> &'self str;
     fn trim_right(&self) -> &'self str;
-    fn trim_chars(&self, chars_to_trim: &[char]) -> &'self str;
-    fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str;
-    fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str;
+    fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
+    fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
+    fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
+    fn replace(&self, from: &str, to: &str) -> ~str;
     fn to_owned(&self) -> ~str;
     fn to_managed(&self) -> @str;
+    fn is_char_boundary(&self, index: uint) -> bool;
+    fn char_range_at(&self, start: uint) -> CharRange;
     fn char_at(&self, i: uint) -> char;
+    fn char_range_at_reverse(&self, start: uint) -> CharRange;
     fn char_at_reverse(&self, i: uint) -> char;
-    fn to_bytes(&self) -> ~[u8];
+    fn as_bytes(&self) -> &'self [u8];
+
+    fn find<C: CharEq>(&self, search: C) -> Option<uint>;
+    fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
+    fn find_str(&self, &str) -> Option<uint>;
+
+    fn repeat(&self, nn: uint) -> ~str;
+
+    fn slice_shift_char(&self) -> (char, &'self str);
 }
 
 /// Extension methods for strings
 impl<'self> StrSlice<'self> for &'self str {
     /**
-     * Return true if a predicate matches all characters or if the string
-     * contains no characters
-     */
-    #[inline]
-    fn all(&self, it: &fn(char) -> bool) -> bool { all(*self, it) }
-    /**
-     * Return true if a predicate matches any character (and false if it
-     * matches none or there are no characters)
+     * Returns true if one string contains another
+     *
+     * # Arguments
+     *
+     * * needle - The string to look for
      */
     #[inline]
-    fn any(&self, it: &fn(char) -> bool) -> bool { any(*self, it) }
-    /// Returns true if one string contains another
-    #[inline]
     fn contains<'a>(&self, needle: &'a str) -> bool {
-        contains(*self, needle)
+        self.find_str(needle).is_some()
     }
-    /// Returns true if a string contains a char
+    /**
+     * Returns true if a string contains a char.
+     *
+     * # Arguments
+     *
+     * * needle - The char to look for
+     */
     #[inline]
     fn contains_char(&self, needle: char) -> bool {
-        contains_char(*self, needle)
-    }
-
+        self.find(needle).is_some()
+    }
+    /// An iterator over the characters of `self`. Note, this iterates
+    /// over unicode code-points, not unicode graphemes.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let v: ~[char] = "abc åäö".iter().collect();
+    /// assert_eq!(v, ~['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
+    /// ~~~
     #[inline]
-    fn char_iter(&self) -> StrCharIterator<'self> {
+    fn iter(&self) -> StrCharIterator<'self> {
         StrCharIterator {
             index: 0,
             string: *self
         }
     }
+    /// An iterator over the characters of `self`, in reverse order.
+    #[inline]
+    fn rev_iter(&self) -> StrCharRevIterator<'self> {
+        StrCharRevIterator {
+            index: self.len(),
+            string: *self
+        }
+    }
 
-    /// Iterate over the bytes in a string
+    /// An iterator over the bytes of `self`
     #[inline]
-    fn each(&self, it: &fn(u8) -> bool) -> bool { each(*self, it) }
-    /// Iterate over the bytes in a string, with indices
+    fn bytes_iter(&self) -> StrBytesIterator<'self> {
+        StrBytesIterator { it: self.as_bytes().iter() }
+    }
+    /// An iterator over the bytes of `self`, in reverse order
     #[inline]
-    fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool { eachi(*self, it) }
-    /// Iterate over the bytes in a string
+    fn bytes_rev_iter(&self) -> StrBytesRevIterator<'self> {
+        StrBytesRevIterator { it: self.as_bytes().rev_iter() }
+    }
+
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by `sep`.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let v: ~[&str] = "Mary had a little lamb".split_iter(' ').collect();
+    /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
+    ///
+    /// let v: ~[&str] = "abc1def2ghi".split_iter(|c: char| c.is_digit()).collect();
+    /// assert_eq!(v, ~["abc", "def", "ghi"]);
+    /// ~~~
     #[inline]
-    fn each_reverse(&self, it: &fn(u8) -> bool) -> bool { each_reverse(*self, it) }
-    /// Iterate over the bytes in a string, with indices
+    fn split_iter<Sep: CharEq>(&self, sep: Sep) -> StrCharSplitIterator<'self, Sep> {
+        self.split_options_iter(sep, self.len(), true)
+    }
+
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by `sep`, restricted to splitting at most `count`
+    /// times.
     #[inline]
-    fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool {
-        eachi_reverse(*self, it)
+    fn splitn_iter<Sep: CharEq>(&self, sep: Sep, count: uint) -> StrCharSplitIterator<'self, Sep> {
+        self.split_options_iter(sep, count, true)
     }
-    /// Iterate over the chars in a string
+
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by `sep`, splitting at most `count` times, and
+    /// possibly not including the trailing empty substring, if it
+    /// exists.
     #[inline]
-    fn each_char(&self, it: &fn(char) -> bool) -> bool { each_char(*self, it) }
-    /// Iterate over the chars in a string, with indices
+    fn split_options_iter<Sep: CharEq>(&self, sep: Sep, count: uint, allow_trailing_empty: bool)
+        -> StrCharSplitIterator<'self, Sep> {
+        let only_ascii = sep.only_ascii();
+        StrCharSplitIterator {
+            string: *self,
+            position: 0,
+            sep: sep,
+            count: count,
+            allow_trailing_empty: allow_trailing_empty,
+            finished: false,
+            only_ascii: only_ascii
+        }
+    }
+    /// An iterator over the start and end indices of each match of
+    /// `sep` within `self`.
     #[inline]
-    fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool {
-        each_chari(*self, it)
+    fn matches_index_iter(&self, sep: &'self str) -> StrMatchesIndexIterator<'self> {
+        assert!(!sep.is_empty())
+        StrMatchesIndexIterator {
+            haystack: *self,
+            needle: sep,
+            position: 0
+        }
     }
-    /// Iterate over the chars in a string in reverse
+    /**
+     * An iterator over the substrings of `self` separated by `sep`.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     * let v: ~[&str] = "abcXXXabcYYYabc".split_str_iter("abc").collect()
+     * assert_eq!(v, ["", "XXX", "YYY", ""]);
+     * ~~~
+     */
     #[inline]
-    fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool {
-        each_char_reverse(*self, it)
+    fn split_str_iter(&self, sep: &'self str) -> StrStrSplitIterator<'self> {
+        StrStrSplitIterator {
+            it: self.matches_index_iter(sep),
+            last_end: 0,
+            finished: false
+        }
     }
-    /// Iterate over the chars in a string in reverse, with indices from the
-    /// end
+
+    /// An iterator over the lines of a string (subsequences separated
+    /// by `\n`).
     #[inline]
-    fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool {
-        each_chari_reverse(*self, it)
+    fn line_iter(&self) -> StrCharSplitIterator<'self, char> {
+        self.split_options_iter('\n', self.len(), false)
     }
-    /// Returns true if one string ends with another
+    /// An iterator over the words of a string (subsequences separated
+    /// by any sequence of whitespace).
     #[inline]
-    fn ends_with(&self, needle: &str) -> bool {
-        ends_with(*self, needle)
+    fn word_iter(&self) -> WordIterator<'self> {
+        self.split_iter(char::is_whitespace).filter(|s| !s.is_empty())
     }
+
     /// Returns true if the string has length 0
     #[inline]
-    fn is_empty(&self) -> bool { is_empty(*self) }
+    fn is_empty(&self) -> bool { self.len() == 0 }
     /**
      * Returns true if the string contains only whitespace
      *
      * Whitespace characters are determined by `char::is_whitespace`
      */
     #[inline]
-    fn is_whitespace(&self) -> bool { is_whitespace(*self) }
+    fn is_whitespace(&self) -> bool { self.iter().all(char::is_whitespace) }
     /**
      * Returns true if the string contains only alphanumerics
      *
      * Alphanumeric characters are determined by `char::is_alphanumeric`
      */
     #[inline]
-    fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
+    fn is_alphanumeric(&self) -> bool { self.iter().all(char::is_alphanumeric) }
     /// Returns the size in bytes not counting the null terminator
     #[inline(always)]
-    fn len(&self) -> uint { len(*self) }
+    fn len(&self) -> uint {
+        do as_buf(*self) |_p, n| { n - 1u }
+    }
     /// Returns the number of characters that a string holds
     #[inline]
-    fn char_len(&self) -> uint { char_len(*self) }
+    fn char_len(&self) -> uint { self.iter().count() }
+
     /**
      * Returns a slice of the given string from the byte range
      * [`begin`..`end`)
@@ -2625,74 +1479,195 @@ impl<'self> StrSlice<'self> for &'self str {
      */
     #[inline]
     fn slice(&self, begin: uint, end: uint) -> &'self str {
-        slice(*self, begin, end)
-    }
-    /// Splits a string into substrings using a character function
+        assert!(self.is_char_boundary(begin));
+        assert!(self.is_char_boundary(end));
+        unsafe { raw::slice_bytes(*self, begin, end) }
+    }
+    /// Returns a slice of the string from `begin` to its end.
+    ///
+    /// Fails when `begin` does not point to a valid character, or is
+    /// out of bounds.
     #[inline]
-    fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) -> bool {
-        each_split(*self, sepfn, it)
-    }
-    /**
-     * Splits a string into substrings at each occurrence of a given character
-     */
+    fn slice_from(&self, begin: uint) -> &'self str {
+        self.slice(begin, self.len())
+    }
+    /// Returns a slice of the string from the beginning to byte
+    /// `end`.
+    ///
+    /// Fails when `end` does not point to a valid character, or is
+    /// out of bounds.
     #[inline]
-    fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) -> bool {
-        each_split_char(*self, sep, it)
+    fn slice_to(&self, end: uint) -> &'self str {
+        self.slice(0, end)
     }
-    /**
-     * Splits a string into a vector of the substrings separated by a given
-     * string
-     */
-    #[inline]
-    fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) -> bool {
-        each_split_str(*self, sep, it)
+
+    /// Returns a slice of the string from the char range
+    /// [`begin`..`end`).
+    ///
+    /// Fails if `begin` > `end` or the either `begin` or `end` are
+    /// beyond the last character of the string.
+    fn slice_chars(&self, begin: uint, end: uint) -> &'self str {
+        assert!(begin <= end);
+        // not sure how to use the iterators for this nicely.
+        let mut (position, count) = (0, 0);
+        let l = self.len();
+        while count < begin && position < l {
+            position = self.char_range_at(position).next;
+            count += 1;
+        }
+        if count < begin { fail!("Attempted to begin slice_chars beyond end of string") }
+        let start_byte = position;
+        while count < end && position < l {
+            position = self.char_range_at(position).next;
+            count += 1;
+        }
+        if count < end { fail!("Attempted to end slice_chars beyond end of string") }
+
+        self.slice(start_byte, position)
     }
-    /// Returns true if one string starts with another
-    #[inline]
+
+    /// Returns true if `needle` is a prefix of the string.
     fn starts_with<'a>(&self, needle: &'a str) -> bool {
-        starts_with(*self, needle)
+        let (self_len, needle_len) = (self.len(), needle.len());
+        if needle_len == 0u { true }
+        else if needle_len > self_len { false }
+        else { match_at(*self, needle, 0u) }
     }
-    /**
-     * Take a substring of another.
-     *
-     * Returns a string containing `n` characters starting at byte offset
-     * `begin`.
-     */
-    #[inline]
-    fn substr(&self, begin: uint, n: uint) -> &'self str {
-        substr(*self, begin, n)
+    /// Returns true if `needle` is a suffix of the string.
+    fn ends_with(&self, needle: &str) -> bool {
+        let (self_len, needle_len) = (self.len(), needle.len());
+        if needle_len == 0u { true }
+        else if needle_len > self_len { false }
+        else { match_at(*self, needle, self_len - needle_len) }
     }
+
     /// Escape each char in `s` with char::escape_default.
-    #[inline]
-    fn escape_default(&self) -> ~str { escape_default(*self) }
+    fn escape_default(&self) -> ~str {
+        let mut out: ~str = ~"";
+        out.reserve_at_least(self.len());
+        for self.iter().advance |c| {
+            out.push_str(char::escape_default(c));
+        }
+        out
+    }
+
     /// Escape each char in `s` with char::escape_unicode.
-    #[inline]
-    fn escape_unicode(&self) -> ~str { escape_unicode(*self) }
+    fn escape_unicode(&self) -> ~str {
+        let mut out: ~str = ~"";
+        out.reserve_at_least(self.len());
+        for self.iter().advance |c| {
+            out.push_str(char::escape_unicode(c));
+        }
+        out
+    }
 
     /// Returns a string with leading and trailing whitespace removed
     #[inline]
-    fn trim(&self) -> &'self str { trim(*self) }
+    fn trim(&self) -> &'self str {
+        self.trim_left().trim_right()
+    }
     /// Returns a string with leading whitespace removed
     #[inline]
-    fn trim_left(&self) -> &'self str { trim_left(*self) }
+    fn trim_left(&self) -> &'self str {
+        self.trim_left_chars(&char::is_whitespace)
+    }
     /// Returns a string with trailing whitespace removed
     #[inline]
-    fn trim_right(&self) -> &'self str { trim_right(*self) }
+    fn trim_right(&self) -> &'self str {
+        self.trim_right_chars(&char::is_whitespace)
+    }
 
+    /**
+     * Returns a string with characters that match `to_trim` removed.
+     *
+     * # Arguments
+     *
+     * * to_trim - a character matcher
+     *
+     * # Example
+     *
+     * ~~~
+     * assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
+     * assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
+     * assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
+     * ~~~
+     */
     #[inline]
-    fn trim_chars(&self, chars_to_trim: &[char]) -> &'self str {
-        trim_chars(*self, chars_to_trim)
+    fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
+        self.trim_left_chars(to_trim).trim_right_chars(to_trim)
     }
+    /**
+     * Returns a string with leading `chars_to_trim` removed.
+     *
+     * # Arguments
+     *
+     * * to_trim - a character matcher
+     *
+     * # Example
+     *
+     * ~~~
+     * assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
+     * assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
+     * assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
+     * ~~~
+     */
     #[inline]
-    fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str {
-        trim_left_chars(*self, chars_to_trim)
+    fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
+        match self.find(|c: char| !to_trim.matches(c)) {
+            None => "",
+            Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
+        }
     }
+    /**
+     * Returns a string with trailing `chars_to_trim` removed.
+     *
+     * # Arguments
+     *
+     * * to_trim - a character matcher
+     *
+     * # Example
+     *
+     * ~~~
+     * assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
+     * assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
+     * assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
+     * ~~~
+     */
     #[inline]
-    fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str {
-        trim_right_chars(*self, chars_to_trim)
+    fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
+        match self.rfind(|c: char| !to_trim.matches(c)) {
+            None => "",
+            Some(last) => {
+                let next = self.char_range_at(last).next;
+                unsafe { raw::slice_bytes(*self, 0u, next) }
+            }
+        }
     }
 
+    /**
+     * Replace all occurrences of one string with another
+     *
+     * # Arguments
+     *
+     * * from - The string to replace
+     * * to - The replacement string
+     *
+     * # Return value
+     *
+     * The original string with all occurances of `from` replaced with `to`
+     */
+    pub fn replace(&self, from: &str, to: &str) -> ~str {
+        let mut (result, last_end) = (~"", 0);
+        for self.matches_index_iter(from).advance |(start, end)| {
+            result.push_str(unsafe{raw::slice_bytes(*self, last_end, start)});
+            result.push_str(to);
+            last_end = end;
+        }
+        result.push_str(unsafe{raw::slice_bytes(*self, last_end, self.len())});
+        result
+    }
 
+    /// Copy a slice into a new unique str
     #[inline]
     fn to_owned(&self) -> ~str { to_owned(*self) }
 
@@ -2704,30 +1679,502 @@ impl<'self> StrSlice<'self> for &'self str {
         unsafe { ::cast::transmute(v) }
     }
 
+    /**
+     * Returns false if the index points into the middle of a multi-byte
+     * character sequence.
+     */
+    fn is_char_boundary(&self, index: uint) -> bool {
+        if index == self.len() { return true; }
+        let b = self[index];
+        return b < 128u8 || b >= 192u8;
+    }
+
+    /**
+     * Pluck a character out of a string and return the index of the next
+     * character.
+     *
+     * This function can be used to iterate over the unicode characters of a
+     * string.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     * let s = "中华Việt Nam";
+     * let i = 0u;
+     * while i < s.len() {
+     *     let CharRange {ch, next} = s.char_range_at(i);
+     *     std::io::println(fmt!("%u: %c",i,ch));
+     *     i = next;
+     * }
+     * ~~~
+     *
+     * # Example output
+     *
+     * ~~~
+     * 0: 中
+     * 3: 华
+     * 6: V
+     * 7: i
+     * 8: ệ
+     * 11: t
+     * 12:
+     * 13: N
+     * 14: a
+     * 15: m
+     * ~~~
+     *
+     * # Arguments
+     *
+     * * s - The string
+     * * i - The byte offset of the char to extract
+     *
+     * # Return value
+     *
+     * A record {ch: char, next: uint} containing the char value and the byte
+     * index of the next unicode character.
+     *
+     * # Failure
+     *
+     * If `i` is greater than or equal to the length of the string.
+     * If `i` is not the index of the beginning of a valid UTF-8 character.
+     */
+    fn char_range_at(&self, i: uint) -> CharRange {
+        let b0 = self[i];
+        let w = utf8_char_width(b0);
+        assert!((w != 0u));
+        if w == 1u { return CharRange {ch: b0 as char, next: i + 1u}; }
+        let mut val = 0u;
+        let end = i + w;
+        let mut i = i + 1u;
+        while i < end {
+            let byte = self[i];
+            assert_eq!(byte & 192u8, tag_cont_u8);
+            val <<= 6u;
+            val += (byte & 63u8) as uint;
+            i += 1u;
+        }
+        // Clunky way to get the right bits from the first byte. Uses two shifts,
+        // the first to clip off the marker bits at the left of the byte, and then
+        // a second (as uint) to get it to the right position.
+        val += ((b0 << ((w + 1u) as u8)) as uint) << ((w - 1u) * 6u - w - 1u);
+        return CharRange {ch: val as char, next: i};
+    }
+
+    /// Plucks the character starting at the `i`th byte of a string
     #[inline]
-    fn char_at(&self, i: uint) -> char { char_at(*self, i) }
+    fn char_at(&self, i: uint) -> char { self.char_range_at(i).ch }
+
+    /**
+     * Given a byte position and a str, return the previous char and its position.
+     *
+     * This function can be used to iterate over a unicode string in reverse.
+     *
+     * Returns 0 for next index if called on start index 0.
+     */
+    fn char_range_at_reverse(&self, start: uint) -> CharRange {
+        let mut prev = start;
+
+        // while there is a previous byte == 10......
+        while prev > 0u && self[prev - 1u] & 192u8 == tag_cont_u8 {
+            prev -= 1u;
+        }
+
+        // now refer to the initial byte of previous char
+        if prev > 0u {
+            prev -= 1u;
+        } else {
+            prev = 0u;
+        }
+
+
+        let ch = self.char_at(prev);
+        return CharRange {ch:ch, next:prev};
+    }
 
+    /// Plucks the character ending at the `i`th byte of a string
     #[inline]
     fn char_at_reverse(&self, i: uint) -> char {
-        char_at_reverse(*self, i)
+        self.char_range_at_reverse(i).ch
+    }
+
+    /**
+     * Work with the byte buffer of a string as a byte slice.
+     *
+     * The byte slice does not include the null terminator.
+     */
+    fn as_bytes(&self) -> &'self [u8] {
+        unsafe {
+            let (ptr, len): (*u8, uint) = ::cast::transmute(*self);
+            let outgoing_tuple: (*u8, uint) = (ptr, len - 1);
+            ::cast::transmute(outgoing_tuple)
+        }
+    }
+
+    /**
+     * Returns the byte index of the first character of `self` that matches `search`
+     *
+     * # Return value
+     *
+     * `Some` containing the byte index of the last matching character
+     * or `None` if there is no match
+     */
+    fn find<C: CharEq>(&self, search: C) -> Option<uint> {
+        if search.only_ascii() {
+            for self.bytes_iter().enumerate().advance |(i, b)| {
+                if search.matches(b as char) { return Some(i) }
+            }
+        } else {
+            let mut index = 0;
+            for self.iter().advance |c| {
+                if search.matches(c) { return Some(index); }
+                index += c.len_utf8_bytes();
+            }
+        }
+
+        None
     }
+    /**
+     * Returns the byte index of the last character of `self` that matches `search`
+     *
+     * # Return value
+     *
+     * `Some` containing the byte index of the last matching character
+     * or `None` if there is no match
+     */
+    fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
+        let mut index = self.len();
+        if search.only_ascii() {
+            for self.bytes_rev_iter().advance |b| {
+                index -= 1;
+                if search.matches(b as char) { return Some(index); }
+            }
+        } else {
+            for self.rev_iter().advance |c| {
+                index -= c.len_utf8_bytes();
+                if search.matches(c) { return Some(index); }
+            }
+        }
+
+        None
+    }
+
+    /**
+     * Returns the byte index of the first matching substring
+     *
+     * # Arguments
+     *
+     * * `needle` - The string to search for
+     *
+     * # Return value
+     *
+     * `Some` containing the byte index of the first matching substring
+     * or `None` if there is no match
+     */
+    fn find_str(&self, needle: &str) -> Option<uint> {
+        if needle.is_empty() {
+            Some(0)
+        } else {
+            self.matches_index_iter(needle)
+                .next()
+                .map_consume(|(start, _end)| start)
+        }
+    }
+
+    /// Given a string, make a new string with repeated copies of it.
+    fn repeat(&self, nn: uint) -> ~str {
+        do as_buf(*self) |buf, len| {
+            let mut ret = ~"";
+            // ignore the NULL terminator
+            let len = len - 1;
+            ret.reserve(nn * len);
+
+            unsafe {
+                do as_buf(ret) |rbuf, _len| {
+                    let mut rbuf = ::cast::transmute_mut_unsafe(rbuf);
+
+                    for nn.times {
+                        ptr::copy_memory(rbuf, buf, len);
+                        rbuf = rbuf.offset(len);
+                    }
+                }
+                raw::set_len(&mut ret, nn * len);
+            }
+            ret
+        }
+    }
+
+    /**
+     * Retrieves the first character from a string slice and returns
+     * it. This does not allocate a new string; instead, it returns a
+     * slice that point one character beyond the character that was
+     * shifted.
+     *
+     * # Failure
+     *
+     * If the string does not contain any characters
+     */
+    #[inline]
+    fn slice_shift_char(&self) -> (char, &'self str) {
+        let CharRange {ch, next} = self.char_range_at(0u);
+        let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
+        return (ch, next_s);
+    }
+
 
-    fn to_bytes(&self) -> ~[u8] { to_bytes(*self) }
 }
 
+#[allow(missing_doc)]
+pub trait NullTerminatedStr {
+    fn as_bytes_with_null<'a>(&'a self) -> &'a [u8];
+}
+
+impl NullTerminatedStr for ~str {
+    /**
+     * Work with the byte buffer of a string as a byte slice.
+     *
+     * The byte slice does include the null terminator.
+     */
+    #[inline]
+    fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
+        let ptr: &'a ~[u8] = unsafe { ::cast::transmute(self) };
+        let slice: &'a [u8] = *ptr;
+        slice
+    }
+}
+impl NullTerminatedStr for @str {
+    /**
+     * Work with the byte buffer of a string as a byte slice.
+     *
+     * The byte slice does include the null terminator.
+     */
+    #[inline]
+    fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
+        let ptr: &'a ~[u8] = unsafe { ::cast::transmute(self) };
+        let slice: &'a [u8] = *ptr;
+        slice
+    }
+}
+
+#[allow(missing_doc)]
 pub trait OwnedStr {
-    fn push_str(&mut self, v: &str);
+    fn push_str_no_overallocate(&mut self, rhs: &str);
+    fn push_str(&mut self, rhs: &str);
     fn push_char(&mut self, c: char);
+    fn pop_char(&mut self) -> char;
+    fn shift_char(&mut self) -> char;
+    fn unshift_char(&mut self, ch: char);
+    fn append(&self, rhs: &str) -> ~str; // FIXME #4850: this should consume self.
+    fn reserve(&mut self, n: uint);
+    fn reserve_at_least(&mut self, n: uint);
+    fn capacity(&self) -> uint;
+
+    fn as_bytes_with_null_consume(self) -> ~[u8];
 }
 
 impl OwnedStr for ~str {
+    /// Appends a string slice to the back of a string, without overallocating
+    #[inline(always)]
+    fn push_str_no_overallocate(&mut self, rhs: &str) {
+        unsafe {
+            let llen = self.len();
+            let rlen = rhs.len();
+            self.reserve(llen + rlen);
+            do as_buf(*self) |lbuf, _llen| {
+                do as_buf(rhs) |rbuf, _rlen| {
+                    let dst = ptr::offset(lbuf, llen);
+                    let dst = ::cast::transmute_mut_unsafe(dst);
+                    ptr::copy_memory(dst, rbuf, rlen);
+                }
+            }
+            raw::set_len(self, llen + rlen);
+        }
+    }
+
+    /// Appends a string slice to the back of a string
     #[inline]
-    fn push_str(&mut self, v: &str) {
-        push_str(self, v);
+    fn push_str(&mut self, rhs: &str) {
+        unsafe {
+            let llen = self.len();
+            let rlen = rhs.len();
+            self.reserve_at_least(llen + rlen);
+            do as_buf(*self) |lbuf, _llen| {
+                do as_buf(rhs) |rbuf, _rlen| {
+                    let dst = ptr::offset(lbuf, llen);
+                    let dst = ::cast::transmute_mut_unsafe(dst);
+                    ptr::copy_memory(dst, rbuf, rlen);
+                }
+            }
+            raw::set_len(self, llen + rlen);
+        }
     }
+    /// Appends a character to the back of a string
     #[inline]
     fn push_char(&mut self, c: char) {
-        push_char(self, c);
+        unsafe {
+            let code = c as uint;
+            let nb = if code < max_one_b { 1u }
+            else if code < max_two_b { 2u }
+            else if code < max_three_b { 3u }
+            else if code < max_four_b { 4u }
+            else if code < max_five_b { 5u }
+            else { 6u };
+            let len = self.len();
+            let new_len = len + nb;
+            self.reserve_at_least(new_len);
+            let off = len;
+            do as_buf(*self) |buf, _len| {
+                let buf: *mut u8 = ::cast::transmute(buf);
+                match nb {
+                    1u => {
+                        *ptr::mut_offset(buf, off) = code as u8;
+                    }
+                    2u => {
+                        *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8;
+                        *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8;
+                    }
+                    3u => {
+                        *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8;
+                        *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8;
+                    }
+                    4u => {
+                        *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8;
+                        *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8;
+                    }
+                    5u => {
+                        *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8;
+                        *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8;
+                    }
+                    6u => {
+                        *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8;
+                        *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8;
+                        *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8;
+                    }
+                    _ => {}
+                }
+            }
+            raw::set_len(self, new_len);
+        }
+    }
+    /**
+     * Remove the final character from a string and return it
+     *
+     * # Failure
+     *
+     * If the string does not contain any characters
+     */
+    fn pop_char(&mut self) -> char {
+        let end = self.len();
+        assert!(end > 0u);
+        let CharRange {ch, next} = self.char_range_at_reverse(end);
+        unsafe { raw::set_len(self, next); }
+        return ch;
+    }
+
+    /**
+     * Remove the first character from a string and return it
+     *
+     * # Failure
+     *
+     * If the string does not contain any characters
+     */
+    fn shift_char(&mut self) -> char {
+        let CharRange {ch, next} = self.char_range_at(0u);
+        *self = unsafe { raw::slice_bytes_owned(*self, next, self.len()) };
+        return ch;
+    }
+
+    /// Prepend a char to a string
+    fn unshift_char(&mut self, ch: char) {
+        // This could be more efficient.
+        let mut new_str = ~"";
+        new_str.push_char(ch);
+        new_str.push_str(*self);
+        *self = new_str;
+    }
+
+    /// Concatenate two strings together.
+    #[inline]
+    fn append(&self, rhs: &str) -> ~str {
+        // FIXME #4850: this should consume self, but that causes segfaults
+        let mut v = self.clone();
+        v.push_str_no_overallocate(rhs);
+        v
+    }
+
+    /**
+     * Reserves capacity for exactly `n` bytes in the given string, not including
+     * the null terminator.
+     *
+     * Assuming single-byte characters, the resulting string will be large
+     * enough to hold a string of length `n`. To account for the null terminator,
+     * the underlying buffer will have the size `n` + 1.
+     *
+     * If the capacity for `s` is already equal to or greater than the requested
+     * capacity, then no action is taken.
+     *
+     * # Arguments
+     *
+     * * s - A string
+     * * n - The number of bytes to reserve space for
+     */
+    #[inline(always)]
+    pub fn reserve(&mut self, n: uint) {
+        unsafe {
+            let v: *mut ~[u8] = cast::transmute(self);
+            vec::reserve(&mut *v, n + 1);
+        }
+    }
+
+    /**
+     * Reserves capacity for at least `n` bytes in the given string, not including
+     * the null terminator.
+     *
+     * Assuming single-byte characters, the resulting string will be large
+     * enough to hold a string of length `n`. To account for the null terminator,
+     * the underlying buffer will have the size `n` + 1.
+     *
+     * This function will over-allocate in order to amortize the allocation costs
+     * in scenarios where the caller may need to repeatedly reserve additional
+     * space.
+     *
+     * If the capacity for `s` is already equal to or greater than the requested
+     * capacity, then no action is taken.
+     *
+     * # Arguments
+     *
+     * * s - A string
+     * * n - The number of bytes to reserve space for
+     */
+    #[inline(always)]
+    fn reserve_at_least(&mut self, n: uint) {
+        self.reserve(uint::next_power_of_two(n + 1u) - 1u)
+    }
+
+    /**
+     * Returns the number of single-byte characters the string can hold without
+     * reallocating
+     */
+    fn capacity(&self) -> uint {
+        let buf: &const ~[u8] = unsafe { cast::transmute(self) };
+        let vcap = vec::capacity(buf);
+        assert!(vcap > 0u);
+        vcap - 1u
+    }
+
+    /// Convert to a vector of bytes. This does not allocate a new
+    /// string, and includes the null terminator.
+    #[inline]
+    fn as_bytes_with_null_consume(self) -> ~[u8] {
+        unsafe { ::cast::transmute(self) }
     }
 }
 
@@ -2738,6 +2185,8 @@ impl Clone for ~str {
     }
 }
 
+/// External iterator for a string's characters. Use with the `std::iterator`
+/// module.
 pub struct StrCharIterator<'self> {
     priv index: uint,
     priv string: &'self str,
@@ -2747,7 +2196,26 @@ impl<'self> Iterator<char> for StrCharIterator<'self> {
     #[inline]
     fn next(&mut self) -> Option<char> {
         if self.index < self.string.len() {
-            let CharRange {ch, next} = char_range_at(self.string, self.index);
+            let CharRange {ch, next} = self.string.char_range_at(self.index);
+            self.index = next;
+            Some(ch)
+        } else {
+            None
+        }
+    }
+}
+/// External iterator for a string's characters in reverse order. Use
+/// with the `std::iterator` module.
+pub struct StrCharRevIterator<'self> {
+    priv index: uint,
+    priv string: &'self str,
+}
+
+impl<'self> Iterator<char> for StrCharRevIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<char> {
+        if self.index > 0 {
+            let CharRange {ch, next} = self.string.char_range_at_reverse(self.index);
             self.index = next;
             Some(ch)
         } else {
@@ -2756,10 +2224,36 @@ impl<'self> Iterator<char> for StrCharIterator<'self> {
     }
 }
 
+/// External iterator for a string's bytes. Use with the `std::iterator`
+/// module.
+pub struct StrBytesIterator<'self> {
+    priv it: vec::VecIterator<'self, u8>
+}
+
+impl<'self> Iterator<u8> for StrBytesIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<u8> {
+        self.it.next().map_consume(|&x| x)
+    }
+}
+
+/// External iterator for a string's bytes in reverse order. Use with
+/// the `std::iterator` module.
+pub struct StrBytesRevIterator<'self> {
+    priv it: vec::VecRevIterator<'self, u8>
+}
+
+impl<'self> Iterator<u8> for StrBytesRevIterator<'self> {
+    #[inline]
+    fn next(&mut self) -> Option<u8> {
+        self.it.next().map_consume(|&x| x)
+    }
+}
+
 #[cfg(test)]
 mod tests {
+    use iterator::IteratorUtil;
     use container::Container;
-    use char;
     use option::Some;
     use libc::c_char;
     use libc;
@@ -2767,7 +2261,7 @@ mod tests {
     use ptr;
     use str::*;
     use vec;
-    use vec::ImmutableVector;
+    use vec::{ImmutableVector, CopyableVector};
     use cmp::{TotalOrd, Less, Equal, Greater};
 
     #[test]
@@ -2779,8 +2273,8 @@ mod tests {
 
     #[test]
     fn test_eq_slice() {
-        assert!((eq_slice(slice("foobar", 0, 3), "foo")));
-        assert!((eq_slice(slice("barfoo", 3, 6), "foo")));
+        assert!((eq_slice("foobar".slice(0, 3), "foo")));
+        assert!((eq_slice("barfoo".slice(3, 6), "foo")));
         assert!((!eq_slice("foo1", "foo2")));
     }
 
@@ -2794,37 +2288,69 @@ mod tests {
 
     #[test]
     fn test_len() {
-        assert_eq!(len(""), 0u);
-        assert_eq!(len("hello world"), 11u);
-        assert_eq!(len("\x63"), 1u);
-        assert_eq!(len("\xa2"), 2u);
-        assert_eq!(len("\u03c0"), 2u);
-        assert_eq!(len("\u2620"), 3u);
-        assert_eq!(len("\U0001d11e"), 4u);
+        assert_eq!("".len(), 0u);
+        assert_eq!("hello world".len(), 11u);
+        assert_eq!("\x63".len(), 1u);
+        assert_eq!("\xa2".len(), 2u);
+        assert_eq!("\u03c0".len(), 2u);
+        assert_eq!("\u2620".len(), 3u);
+        assert_eq!("\U0001d11e".len(), 4u);
+
+        assert_eq!("".char_len(), 0u);
+        assert_eq!("hello world".char_len(), 11u);
+        assert_eq!("\x63".char_len(), 1u);
+        assert_eq!("\xa2".char_len(), 1u);
+        assert_eq!("\u03c0".char_len(), 1u);
+        assert_eq!("\u2620".char_len(), 1u);
+        assert_eq!("\U0001d11e".char_len(), 1u);
+        assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
+    }
 
-        assert_eq!(char_len(""), 0u);
-        assert_eq!(char_len("hello world"), 11u);
-        assert_eq!(char_len("\x63"), 1u);
-        assert_eq!(char_len("\xa2"), 1u);
-        assert_eq!(char_len("\u03c0"), 1u);
-        assert_eq!(char_len("\u2620"), 1u);
-        assert_eq!(char_len("\U0001d11e"), 1u);
-        assert_eq!(char_len("ประเทศไทย中华Việt Nam"), 19u);
+    #[test]
+    fn test_find() {
+        assert_eq!("hello".find('l'), Some(2u));
+        assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
+        assert!("hello".find('x').is_none());
+        assert!("hello".find(|c:char| c == 'x').is_none());
+        assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
+        assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
     }
 
     #[test]
-    fn test_rfind_char() {
-        assert_eq!(rfind_char("hello", 'l'), Some(3u));
-        assert_eq!(rfind_char("hello", 'o'), Some(4u));
-        assert_eq!(rfind_char("hello", 'h'), Some(0u));
-        assert!(rfind_char("hello", 'z').is_none());
-        assert_eq!(rfind_char("ประเทศไทย中华Việt Nam", '华'), Some(30u));
+    fn test_rfind() {
+        assert_eq!("hello".rfind('l'), Some(3u));
+        assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
+        assert!("hello".rfind('x').is_none());
+        assert!("hello".rfind(|c:char| c == 'x').is_none());
+        assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
+        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
+    }
+
+    #[test]
+    fn test_push_str() {
+        let mut s = ~"";
+        s.push_str("");
+        assert_eq!(s.slice_from(0), "");
+        s.push_str("abc");
+        assert_eq!(s.slice_from(0), "abc");
+        s.push_str("ประเทศไทย中华Việt Nam");
+        assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
+    }
+    #[test]
+    fn test_append() {
+        let mut s = ~"";
+        s = s.append("");
+        assert_eq!(s.slice_from(0), "");
+        s = s.append("abc");
+        assert_eq!(s.slice_from(0), "abc");
+        s = s.append("ประเทศไทย中华Việt Nam");
+        assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
     }
 
     #[test]
     fn test_pop_char() {
         let mut data = ~"ประเทศไทย中华";
-        let cc = pop_char(&mut data);
+        let cc = data.pop_char();
         assert_eq!(~"ประเทศไทย中", data);
         assert_eq!('华', cc);
     }
@@ -2832,7 +2358,7 @@ mod tests {
     #[test]
     fn test_pop_char_2() {
         let mut data2 = ~"华";
-        let cc2 = pop_char(&mut data2);
+        let cc2 = data2.pop_char();
         assert_eq!(~"", data2);
         assert_eq!('华', cc2);
     }
@@ -2842,225 +2368,29 @@ mod tests {
     #[ignore(cfg(windows))]
     fn test_pop_char_fail() {
         let mut data = ~"";
-        let _cc3 = pop_char(&mut data);
-    }
-
-    #[test]
-    fn test_split_char() {
-        fn t(s: &str, c: char, u: &[~str]) {
-            debug!("split_byte: %?", s);
-            let mut v = ~[];
-            for each_split_char(s, c) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        t("abc.hello.there", '.', [~"abc", ~"hello", ~"there"]);
-        t(".hello.there", '.', [~"", ~"hello", ~"there"]);
-        t("...hello.there.", '.', [~"", ~"", ~"", ~"hello", ~"there", ~""]);
-
-        t("", 'z', [~""]);
-        t("z", 'z', [~"",~""]);
-        t("ok", 'z', [~"ok"]);
-    }
-
-    #[test]
-    fn test_split_char_2() {
-        fn t(s: &str, c: char, u: &[~str]) {
-            debug!("split_byte: %?", s);
-            let mut v = ~[];
-            for each_split_char(s, c) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        let data = "ประเทศไทย中华Việt Nam";
-        t(data, 'V', [~"ประเทศไทย中华", ~"iệt Nam"]);
-        t(data, 'ท', [~"ประเ", ~"ศไ", ~"ย中华Việt Nam"]);
-    }
-
-    #[test]
-    fn test_splitn_char() {
-        fn t(s: &str, c: char, n: uint, u: &[~str]) {
-            debug!("splitn_byte: %?", s);
-            let mut v = ~[];
-            for each_splitn_char(s, c, n) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            debug!("comparing vs. %?", u);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        t("abc.hello.there", '.', 0u, [~"abc.hello.there"]);
-        t("abc.hello.there", '.', 1u, [~"abc", ~"hello.there"]);
-        t("abc.hello.there", '.', 2u, [~"abc", ~"hello", ~"there"]);
-        t("abc.hello.there", '.', 3u, [~"abc", ~"hello", ~"there"]);
-        t(".hello.there", '.', 0u, [~".hello.there"]);
-        t(".hello.there", '.', 1u, [~"", ~"hello.there"]);
-        t("...hello.there.", '.', 3u, [~"", ~"", ~"", ~"hello.there."]);
-        t("...hello.there.", '.', 5u, [~"", ~"", ~"", ~"hello", ~"there", ~""]);
-
-        t("", 'z', 5u, [~""]);
-        t("z", 'z', 5u, [~"",~""]);
-        t("ok", 'z', 5u, [~"ok"]);
-        t("z", 'z', 0u, [~"z"]);
-        t("w.x.y", '.', 0u, [~"w.x.y"]);
-        t("w.x.y", '.', 1u, [~"w",~"x.y"]);
-    }
-
-    #[test]
-    fn test_splitn_char_2() {
-        fn t(s: &str, c: char, n: uint, u: &[~str]) {
-            debug!("splitn_byte: %?", s);
-            let mut v = ~[];
-            for each_splitn_char(s, c, n) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            debug!("comparing vs. %?", u);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-
-        t("ประเทศไทย中华Việt Nam", '华', 1u, [~"ประเทศไทย中", ~"Việt Nam"]);
-        t("zzXXXzYYYzWWWz", 'z', 3u, [~"", ~"", ~"XXX", ~"YYYzWWWz"]);
-        t("z", 'z', 5u, [~"",~""]);
-        t("", 'z', 5u, [~""]);
-        t("ok", 'z', 5u, [~"ok"]);
-    }
-
-    #[test]
-    fn test_splitn_char_3() {
-        fn t(s: &str, c: char, n: uint, u: &[~str]) {
-            debug!("splitn_byte: %?", s);
-            let mut v = ~[];
-            for each_splitn_char(s, c, n) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            debug!("comparing vs. %?", u);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        let data = "ประเทศไทย中华Việt Nam";
-        t(data, 'V', 1u, [~"ประเทศไทย中华", ~"iệt Nam"]);
-        t(data, 'ท', 1u, [~"ประเ", ~"ศไทย中华Việt Nam"]);
-    }
-
-    #[test]
-    fn test_split_char_no_trailing() {
-        fn t(s: &str, c: char, u: &[~str]) {
-            debug!("split_byte: %?", s);
-            let mut v = ~[];
-            for each_split_char_no_trailing(s, c) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        t("abc.hello.there", '.', [~"abc", ~"hello", ~"there"]);
-        t(".hello.there", '.', [~"", ~"hello", ~"there"]);
-        t("...hello.there.", '.', [~"", ~"", ~"", ~"hello", ~"there"]);
-
-        t("...hello.there.", '.', [~"", ~"", ~"", ~"hello", ~"there"]);
-        t("", 'z', []);
-        t("z", 'z', [~""]);
-        t("ok", 'z', [~"ok"]);
-    }
-
-    #[test]
-    fn test_split_char_no_trailing_2() {
-        fn t(s: &str, c: char, u: &[~str]) {
-            debug!("split_byte: %?", s);
-            let mut v = ~[];
-            for each_split_char_no_trailing(s, c) |s| { v.push(s.to_owned()) }
-            debug!("split_byte to: %?", v);
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        let data = "ประเทศไทย中华Việt Nam";
-        t(data, 'V', [~"ประเทศไทย中华", ~"iệt Nam"]);
-        t(data, 'ท', [~"ประเ", ~"ศไ", ~"ย中华Việt Nam"]);
+        let _cc3 = data.pop_char();
     }
 
     #[test]
-    fn test_split_str() {
-        fn t<'a>(s: &str, sep: &'a str, u: &[~str]) {
-            let mut v = ~[];
-            for each_split_str(s, sep) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        t("--1233345--", "12345", [~"--1233345--"]);
-        t("abc::hello::there", "::", [~"abc", ~"hello", ~"there"]);
-        t("::hello::there", "::", [~"", ~"hello", ~"there"]);
-        t("hello::there::", "::", [~"hello", ~"there", ~""]);
-        t("::hello::there::", "::", [~"", ~"hello", ~"there", ~""]);
-        t("ประเทศไทย中华Việt Nam", "中华", [~"ประเทศไทย", ~"Việt Nam"]);
-        t("zzXXXzzYYYzz", "zz", [~"", ~"XXX", ~"YYY", ~""]);
-        t("zzXXXzYYYz", "XXX", [~"zz", ~"zYYYz"]);
-        t(".XXX.YYY.", ".", [~"", ~"XXX", ~"YYY", ~""]);
-        t("", ".", [~""]);
-        t("zz", "zz", [~"",~""]);
-        t("ok", "z", [~"ok"]);
-        t("zzz", "zz", [~"",~"z"]);
-        t("zzzzz", "zz", [~"",~"",~"z"]);
+    fn test_push_char() {
+        let mut data = ~"ประเทศไทย中";
+        data.push_char('华');
+        assert_eq!(~"ประเทศไทย中华", data);
     }
 
-
     #[test]
-    fn test_split() {
-        fn t(s: &str, sepf: &fn(char) -> bool, u: &[~str]) {
-            let mut v = ~[];
-            for each_split(s, sepf) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-
-        t("ประเทศไทย中华Việt Nam", |cc| cc == '华', [~"ประเทศไทย中", ~"Việt Nam"]);
-        t("zzXXXzYYYz", char::is_lowercase, [~"", ~"", ~"XXX", ~"YYY", ~""]);
-        t("zzXXXzYYYz", char::is_uppercase, [~"zz", ~"", ~"", ~"z", ~"", ~"", ~"z"]);
-        t("z", |cc| cc == 'z', [~"",~""]);
-        t("", |cc| cc == 'z', [~""]);
-        t("ok", |cc| cc == 'z', [~"ok"]);
-    }
-
-    #[test]
-    fn test_split_no_trailing() {
-        fn t(s: &str, sepf: &fn(char) -> bool, u: &[~str]) {
-            let mut v = ~[];
-            for each_split_no_trailing(s, sepf) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-
-        t("ประเทศไทย中华Việt Nam", |cc| cc == '华', [~"ประเทศไทย中", ~"Việt Nam"]);
-        t("zzXXXzYYYz", char::is_lowercase, [~"", ~"", ~"XXX", ~"YYY"]);
-        t("zzXXXzYYYz", char::is_uppercase, [~"zz", ~"", ~"", ~"z", ~"", ~"", ~"z"]);
-        t("z", |cc| cc == 'z', [~""]);
-        t("", |cc| cc == 'z', []);
-        t("ok", |cc| cc == 'z', [~"ok"]);
-    }
-
-    #[test]
-    fn test_lines() {
-        let lf = "\nMary had a little lamb\nLittle lamb\n";
-        let crlf = "\r\nMary had a little lamb\r\nLittle lamb\r\n";
-
-        fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) {
-            let mut v = ~[];
-            for f(s) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-
-        t(lf, each_line, [~"", ~"Mary had a little lamb", ~"Little lamb"]);
-        t(lf, each_line_any, [~"", ~"Mary had a little lamb", ~"Little lamb"]);
-        t(crlf, each_line, [~"\r", ~"Mary had a little lamb\r", ~"Little lamb\r"]);
-        t(crlf, each_line_any, [~"", ~"Mary had a little lamb", ~"Little lamb"]);
-        t("", each_line, []);
-        t("", each_line_any, []);
-        t("\n", each_line, [~""]);
-        t("\n", each_line_any, [~""]);
-        t("banana", each_line, [~"banana"]);
-        t("banana", each_line_any, [~"banana"]);
+    fn test_shift_char() {
+        let mut data = ~"ประเทศไทย中";
+        let cc = data.shift_char();
+        assert_eq!(~"ระเทศไทย中", data);
+        assert_eq!('ป', cc);
     }
 
     #[test]
-    fn test_words() {
-        fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) {
-            let mut v = ~[];
-            for f(s) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
-        }
-        let data = "\nMary had a little lamb\nLittle lamb\n";
-
-        t(data, each_word, [~"Mary",~"had",~"a",~"little",~"lamb",~"Little",~"lamb"]);
-        t("ok", each_word, [~"ok"]);
-        t("", each_word, []);
+    fn test_unshift_char() {
+        let mut data = ~"ประเทศไทย中";
+        data.unshift_char('华');
+        assert_eq!(~"华ประเทศไทย中", data);
     }
 
     #[test]
@@ -3068,7 +2398,7 @@ mod tests {
         fn t(s: &str, i: uint, u: &[~str]) {
             let mut v = ~[];
             for each_split_within(s, i) |s| { v.push(s.to_owned()) }
-            assert!(vec::all2(v, u, |a,b| a == b));
+            assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
         }
         t("", 0, []);
         t("", 15, []);
@@ -3080,59 +2410,47 @@ mod tests {
     #[test]
     fn test_find_str() {
         // byte positions
-        assert!(find_str("banana", "apple pie").is_none());
-        assert_eq!(find_str("", ""), Some(0u));
-
-        let data = "ประเทศไทย中华Việt Nam";
-        assert_eq!(find_str(data, ""), Some(0u));
-        assert_eq!(find_str(data, "ประเ"), Some( 0u));
-        assert_eq!(find_str(data, "ะเ"), Some( 6u));
-        assert_eq!(find_str(data, "中华"), Some(27u));
-        assert!(find_str(data, "ไท华").is_none());
-    }
-
-    #[test]
-    fn test_find_str_between() {
-        // byte positions
-        assert_eq!(find_str_between("", "", 0u, 0u), Some(0u));
+        assert_eq!("".find_str(""), Some(0u));
+        assert!("banana".find_str("apple pie").is_none());
 
         let data = "abcabc";
-        assert_eq!(find_str_between(data, "ab", 0u, 6u), Some(0u));
-        assert_eq!(find_str_between(data, "ab", 2u, 6u), Some(3u));
-        assert!(find_str_between(data, "ab", 2u, 4u).is_none());
+        assert_eq!(data.slice(0u, 6u).find_str("ab"), Some(0u));
+        assert_eq!(data.slice(2u, 6u).find_str("ab"), Some(3u - 2u));
+        assert!(data.slice(2u, 4u).find_str("ab").is_none());
 
         let mut data = ~"ประเทศไทย中华Việt Nam";
         data = data + data;
-        assert_eq!(find_str_between(data, "", 0u, 43u), Some(0u));
-        assert_eq!(find_str_between(data, "", 6u, 43u), Some(6u));
+        assert!(data.find_str("ไท华").is_none());
+        assert_eq!(data.slice(0u, 43u).find_str(""), Some(0u));
+        assert_eq!(data.slice(6u, 43u).find_str(""), Some(6u - 6u));
 
-        assert_eq!(find_str_between(data, "ประ", 0u, 43u), Some( 0u));
-        assert_eq!(find_str_between(data, "ทศไ", 0u, 43u), Some(12u));
-        assert_eq!(find_str_between(data, "ย中", 0u, 43u), Some(24u));
-        assert_eq!(find_str_between(data, "iệt", 0u, 43u), Some(34u));
-        assert_eq!(find_str_between(data, "Nam", 0u, 43u), Some(40u));
+        assert_eq!(data.slice(0u, 43u).find_str("ประ"), Some( 0u));
+        assert_eq!(data.slice(0u, 43u).find_str("ทศไ"), Some(12u));
+        assert_eq!(data.slice(0u, 43u).find_str("ย中"), Some(24u));
+        assert_eq!(data.slice(0u, 43u).find_str("iệt"), Some(34u));
+        assert_eq!(data.slice(0u, 43u).find_str("Nam"), Some(40u));
 
-        assert_eq!(find_str_between(data, "ประ", 43u, 86u), Some(43u));
-        assert_eq!(find_str_between(data, "ทศไ", 43u, 86u), Some(55u));
-        assert_eq!(find_str_between(data, "ย中", 43u, 86u), Some(67u));
-        assert_eq!(find_str_between(data, "iệt", 43u, 86u), Some(77u));
-        assert_eq!(find_str_between(data, "Nam", 43u, 86u), Some(83u));
+        assert_eq!(data.slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
     }
 
     #[test]
-    fn test_substr() {
-        fn t(a: &str, b: &str, start: int) {
-            assert_eq!(substr(a, start as uint, len(b)), b);
+    fn test_slice_chars() {
+        fn t(a: &str, b: &str, start: uint) {
+            assert_eq!(a.slice_chars(start, start + b.char_len()), b);
         }
         t("hello", "llo", 2);
         t("hello", "el", 1);
-        assert_eq!("ะเทศไท", substr("ประเทศไทย中华Việt Nam", 6u, 6u));
+        assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
     }
 
     #[test]
     fn test_concat() {
         fn t(v: &[~str], s: &str) {
-            assert_eq!(concat(v), s.to_str());
+            assert_eq!(v.concat(), s.to_str());
         }
         t([~"you", ~"know", ~"I'm", ~"no", ~"good"], "youknowI'mnogood");
         let v: &[~str] = [];
@@ -3143,7 +2461,7 @@ mod tests {
     #[test]
     fn test_connect() {
         fn t(v: &[~str], sep: &str, s: &str) {
-            assert_eq!(connect(v, sep), s.to_str());
+            assert_eq!(v.connect(sep), s.to_str());
         }
         t([~"you", ~"know", ~"I'm", ~"no", ~"good"],
           " ", "you know I'm no good");
@@ -3153,9 +2471,20 @@ mod tests {
     }
 
     #[test]
+    fn test_concat_slices() {
+        fn t(v: &[&str], s: &str) {
+            assert_eq!(v.concat(), s.to_str());
+        }
+        t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
+        let v: &[&str] = [];
+        t(v, "");
+        t(["hi"], "hi");
+    }
+
+    #[test]
     fn test_connect_slices() {
         fn t(v: &[&str], sep: &str, s: &str) {
-            assert_eq!(connect_slices(v, sep), s.to_str());
+            assert_eq!(v.connect(sep), s.to_str());
         }
         t(["you", "know", "I'm", "no", "good"],
           " ", "you know I'm no good");
@@ -3165,11 +2494,11 @@ mod tests {
 
     #[test]
     fn test_repeat() {
-        assert_eq!(repeat("x", 4), ~"xxxx");
-        assert_eq!(repeat("hi", 4), ~"hihihihi");
-        assert_eq!(repeat("ไท华", 3), ~"ไท华ไท华ไท华");
-        assert_eq!(repeat("", 4), ~"");
-        assert_eq!(repeat("hi", 0), ~"");
+        assert_eq!("x".repeat(4), ~"xxxx");
+        assert_eq!("hi".repeat(4), ~"hihihihi");
+        assert_eq!("ไท华".repeat(3), ~"ไท华ไท华ไท华");
+        assert_eq!("".repeat(4), ~"");
+        assert_eq!("hi".repeat(0), ~"");
     }
 
     #[test]
@@ -3180,13 +2509,13 @@ mod tests {
         fn a_million_letter_a() -> ~str {
             let mut i = 0;
             let mut rs = ~"";
-            while i < 100000 { push_str(&mut rs, "aaaaaaaaaa"); i += 1; }
+            while i < 100000 { rs.push_str("aaaaaaaaaa"); i += 1; }
             rs
         }
         fn half_a_million_letter_a() -> ~str {
             let mut i = 0;
             let mut rs = ~"";
-            while i < 100000 { push_str(&mut rs, "aaaaa"); i += 1; }
+            while i < 100000 { rs.push_str("aaaaa"); i += 1; }
             rs
         }
         let letters = a_million_letter_a();
@@ -3196,38 +2525,38 @@ mod tests {
 
     #[test]
     fn test_starts_with() {
-        assert!((starts_with("", "")));
-        assert!((starts_with("abc", "")));
-        assert!((starts_with("abc", "a")));
-        assert!((!starts_with("a", "abc")));
-        assert!((!starts_with("", "abc")));
+        assert!(("".starts_with("")));
+        assert!(("abc".starts_with("")));
+        assert!(("abc".starts_with("a")));
+        assert!((!"a".starts_with("abc")));
+        assert!((!"".starts_with("abc")));
     }
 
     #[test]
     fn test_ends_with() {
-        assert!((ends_with("", "")));
-        assert!((ends_with("abc", "")));
-        assert!((ends_with("abc", "c")));
-        assert!((!ends_with("a", "abc")));
-        assert!((!ends_with("", "abc")));
+        assert!(("".ends_with("")));
+        assert!(("abc".ends_with("")));
+        assert!(("abc".ends_with("c")));
+        assert!((!"a".ends_with("abc")));
+        assert!((!"".ends_with("abc")));
     }
 
     #[test]
     fn test_is_empty() {
-        assert!((is_empty("")));
-        assert!((!is_empty("a")));
+        assert!("".is_empty());
+        assert!(!"a".is_empty());
     }
 
     #[test]
     fn test_replace() {
         let a = "a";
-        assert_eq!(replace("", a, "b"), ~"");
-        assert_eq!(replace("a", a, "b"), ~"b");
-        assert_eq!(replace("ab", a, "b"), ~"bb");
+        assert_eq!("".replace(a, "b"), ~"");
+        assert_eq!("a".replace(a, "b"), ~"b");
+        assert_eq!("ab".replace(a, "b"), ~"bb");
         let test = "test";
-        assert!(replace(" test test ", test, "toast") ==
+        assert!(" test test ".replace(test, "toast") ==
             ~" toast toast ");
-        assert_eq!(replace(" test test ", test, ""), ~"   ");
+        assert_eq!(" test test ".replace(test, ""), ~"   ");
     }
 
     #[test]
@@ -3237,7 +2566,7 @@ mod tests {
 
         let a = ~"ประเ";
         let A = ~"دولة الكويتทศไทย中华";
-        assert_eq!(replace(data, a, repl), A);
+        assert_eq!(data.replace(a, repl), A);
     }
 
     #[test]
@@ -3247,7 +2576,7 @@ mod tests {
 
         let b = ~"ะเ";
         let B = ~"ปรدولة الكويتทศไทย中华";
-        assert_eq!(replace(data, b,   repl), B);
+        assert_eq!(data.replace(b,   repl), B);
     }
 
     #[test]
@@ -3257,7 +2586,7 @@ mod tests {
 
         let c = ~"中华";
         let C = ~"ประเทศไทยدولة الكويت";
-        assert_eq!(replace(data, c, repl), C);
+        assert_eq!(data.replace(c, repl), C);
     }
 
     #[test]
@@ -3266,21 +2595,21 @@ mod tests {
         let repl = ~"دولة الكويت";
 
         let d = ~"ไท华";
-        assert_eq!(replace(data, d, repl), data);
+        assert_eq!(data.replace(d, repl), data);
     }
 
     #[test]
     fn test_slice() {
-        assert_eq!("ab", slice("abc", 0, 2));
-        assert_eq!("bc", slice("abc", 1, 3));
-        assert_eq!("", slice("abc", 1, 1));
-        assert_eq!("\u65e5", slice("\u65e5\u672c", 0, 3));
+        assert_eq!("ab", "abc".slice(0, 2));
+        assert_eq!("bc", "abc".slice(1, 3));
+        assert_eq!("", "abc".slice(1, 1));
+        assert_eq!("\u65e5", "\u65e5\u672c".slice(0, 3));
 
         let data = "ประเทศไทย中华";
-        assert_eq!("ป", slice(data, 0, 3));
-        assert_eq!("ร", slice(data, 3, 6));
-        assert_eq!("", slice(data, 3, 3));
-        assert_eq!("华", slice(data, 30, 33));
+        assert_eq!("ป", data.slice(0, 3));
+        assert_eq!("ร", data.slice(3, 6));
+        assert_eq!("", data.slice(3, 3));
+        assert_eq!("华", data.slice(30, 33));
 
         fn a_million_letter_X() -> ~str {
             let mut i = 0;
@@ -3299,23 +2628,23 @@ mod tests {
         }
         let letters = a_million_letter_X();
         assert!(half_a_million_letter_X() ==
-            slice(letters, 0u, 3u * 500000u).to_owned());
+            letters.slice(0u, 3u * 500000u).to_owned());
     }
 
     #[test]
     fn test_slice_2() {
         let ss = "中华Việt Nam";
 
-        assert_eq!("华", slice(ss, 3u, 6u));
-        assert_eq!("Việt Nam", slice(ss, 6u, 16u));
+        assert_eq!("华", ss.slice(3u, 6u));
+        assert_eq!("Việt Nam", ss.slice(6u, 16u));
 
-        assert_eq!("ab", slice("abc", 0u, 2u));
-        assert_eq!("bc", slice("abc", 1u, 3u));
-        assert_eq!("", slice("abc", 1u, 1u));
+        assert_eq!("ab", "abc".slice(0u, 2u));
+        assert_eq!("bc", "abc".slice(1u, 3u));
+        assert_eq!("", "abc".slice(1u, 1u));
 
-        assert_eq!("中", slice(ss, 0u, 3u));
-        assert_eq!("华V", slice(ss, 3u, 7u));
-        assert_eq!("", slice(ss, 3u, 3u));
+        assert_eq!("中", ss.slice(0u, 3u));
+        assert_eq!("华V", ss.slice(3u, 7u));
+        assert_eq!("", ss.slice(3u, 3u));
         /*0: 中
           3: 华
           6: V
@@ -3332,70 +2661,98 @@ mod tests {
     #[should_fail]
     #[ignore(cfg(windows))]
     fn test_slice_fail() {
-        slice("中华Việt Nam", 0u, 2u);
+        "中华Việt Nam".slice(0u, 2u);
+    }
+
+    #[test]
+    fn test_slice_from() {
+        assert_eq!("abcd".slice_from(0), "abcd");
+        assert_eq!("abcd".slice_from(2), "cd");
+        assert_eq!("abcd".slice_from(4), "");
+    }
+    #[test]
+    fn test_slice_to() {
+        assert_eq!("abcd".slice_to(0), "");
+        assert_eq!("abcd".slice_to(2), "ab");
+        assert_eq!("abcd".slice_to(4), "abcd");
     }
 
     #[test]
     fn test_trim_left_chars() {
-        assert!(trim_left_chars(" *** foo *** ", []) == " *** foo *** ");
-        assert!(trim_left_chars(" *** foo *** ", ['*', ' ']) == "foo *** ");
-        assert_eq!(trim_left_chars(" ***  *** ", ['*', ' ']), "");
-        assert!(trim_left_chars("foo *** ", ['*', ' ']) == "foo *** ");
+        let v: &[char] = &[];
+        assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
+        assert_eq!(" ***  *** ".trim_left_chars(& &['*', ' ']), "");
+        assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
+
+        assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
+        assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
+        assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
     }
 
     #[test]
     fn test_trim_right_chars() {
-        assert!(trim_right_chars(" *** foo *** ", []) == " *** foo *** ");
-        assert!(trim_right_chars(" *** foo *** ", ['*', ' ']) == " *** foo");
-        assert_eq!(trim_right_chars(" ***  *** ", ['*', ' ']), "");
-        assert!(trim_right_chars(" *** foo", ['*', ' ']) == " *** foo");
+        let v: &[char] = &[];
+        assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
+        assert_eq!(" ***  *** ".trim_right_chars(& &['*', ' ']), "");
+        assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
+
+        assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
+        assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
+        assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
     }
 
     #[test]
     fn test_trim_chars() {
-        assert_eq!(trim_chars(" *** foo *** ", []), " *** foo *** ");
-        assert_eq!(trim_chars(" *** foo *** ", ['*', ' ']), "foo");
-        assert_eq!(trim_chars(" ***  *** ", ['*', ' ']), "");
-        assert_eq!(trim_chars("foo", ['*', ' ']), "foo");
+        let v: &[char] = &[];
+        assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
+        assert_eq!(" ***  *** ".trim_chars(& &['*', ' ']), "");
+        assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
+
+        assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
+        assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
+        assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
     }
 
     #[test]
     fn test_trim_left() {
-        assert_eq!(trim_left(""), "");
-        assert_eq!(trim_left("a"), "a");
-        assert_eq!(trim_left("    "), "");
-        assert_eq!(trim_left("     blah"), "blah");
-        assert_eq!(trim_left("   \u3000  wut"), "wut");
-        assert_eq!(trim_left("hey "), "hey ");
+        assert_eq!("".trim_left(), "");
+        assert_eq!("a".trim_left(), "a");
+        assert_eq!("    ".trim_left(), "");
+        assert_eq!("     blah".trim_left(), "blah");
+        assert_eq!("   \u3000  wut".trim_left(), "wut");
+        assert_eq!("hey ".trim_left(), "hey ");
     }
 
     #[test]
     fn test_trim_right() {
-        assert_eq!(trim_right(""), "");
-        assert_eq!(trim_right("a"), "a");
-        assert_eq!(trim_right("    "), "");
-        assert_eq!(trim_right("blah     "), "blah");
-        assert_eq!(trim_right("wut   \u3000  "), "wut");
-        assert_eq!(trim_right(" hey"), " hey");
+        assert_eq!("".trim_right(), "");
+        assert_eq!("a".trim_right(), "a");
+        assert_eq!("    ".trim_right(), "");
+        assert_eq!("blah     ".trim_right(), "blah");
+        assert_eq!("wut   \u3000  ".trim_right(), "wut");
+        assert_eq!(" hey".trim_right(), " hey");
     }
 
     #[test]
     fn test_trim() {
-        assert_eq!(trim(""), "");
-        assert_eq!(trim("a"), "a");
-        assert_eq!(trim("    "), "");
-        assert_eq!(trim("    blah     "), "blah");
-        assert_eq!(trim("\nwut   \u3000  "), "wut");
-        assert_eq!(trim(" hey dude "), "hey dude");
+        assert_eq!("".trim(), "");
+        assert_eq!("a".trim(), "a");
+        assert_eq!("    ".trim(), "");
+        assert_eq!("    blah     ".trim(), "blah");
+        assert_eq!("\nwut   \u3000  ".trim(), "wut");
+        assert_eq!(" hey dude ".trim(), "hey dude");
     }
 
     #[test]
     fn test_is_whitespace() {
-        assert!(is_whitespace(""));
-        assert!(is_whitespace(" "));
-        assert!(is_whitespace("\u2009")); // Thin space
-        assert!(is_whitespace("  \n\t   "));
-        assert!(!is_whitespace("   _   "));
+        assert!("".is_whitespace());
+        assert!(" ".is_whitespace());
+        assert!("\u2009".is_whitespace()); // Thin space
+        assert!("  \n\t   ".is_whitespace());
+        assert!(!"   _   ".is_whitespace());
     }
 
     #[test]
@@ -3439,9 +2796,10 @@ mod tests {
     }
 
     #[test]
-    #[should_fail]
     #[ignore(cfg(windows))]
     fn test_from_bytes_fail() {
+        use str::not_utf8::cond;
+
         let bb = ~[0xff_u8, 0xb8_u8, 0xa8_u8,
                   0xe0_u8, 0xb9_u8, 0x84_u8,
                   0xe0_u8, 0xb8_u8, 0x97_u8,
@@ -3453,7 +2811,15 @@ mod tests {
                   0x20_u8, 0x4e_u8, 0x61_u8,
                   0x6d_u8];
 
-         let _x = from_bytes(bb);
+        let mut error_happened = false;
+        let _x = do cond.trap(|err| {
+            assert_eq!(err, ~"from_bytes: input is not UTF-8; first bad byte is 255");
+            error_happened = true;
+            ~""
+        }).in {
+            from_bytes(bb)
+        };
+        assert!(error_happened);
     }
 
     #[test]
@@ -3527,11 +2893,65 @@ mod tests {
     }
 
     #[test]
+    fn test_as_bytes() {
+        // no null
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109
+        ];
+        assert_eq!("".as_bytes(), &[]);
+        assert_eq!("abc".as_bytes(), &['a' as u8, 'b' as u8, 'c' as u8]);
+        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
+    }
+
+    #[test]
+    fn test_as_bytes_with_null() {
+        // has null
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109, 0
+        ];
+
+        let s1 = @"";
+        let s2 = @"abc";
+        let s3 = @"ศไทย中华Việt Nam";
+        assert_eq!(s1.as_bytes_with_null(), &[0]);
+        assert_eq!(s2.as_bytes_with_null(), &['a' as u8, 'b' as u8, 'c' as u8, 0]);
+        assert_eq!(s3.as_bytes_with_null(), v);
+
+        let s1 = ~"";
+        let s2 = ~"abc";
+        let s3 = ~"ศไทย中华Việt Nam";
+        assert_eq!(s1.as_bytes_with_null(), &[0]);
+        assert_eq!(s2.as_bytes_with_null(), &['a' as u8, 'b' as u8, 'c' as u8, 0]);
+        assert_eq!(s3.as_bytes_with_null(), v);
+    }
+
+    #[test]
+    fn test_as_bytes_with_null_consume() {
+        let s = ~"ศไทย中华Việt Nam";
+        let v = ~[
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109, 0
+        ];
+        assert_eq!((~"").as_bytes_with_null_consume(), ~[0]);
+        assert_eq!((~"abc").as_bytes_with_null_consume(),
+                   ~['a' as u8, 'b' as u8, 'c' as u8, 0]);
+        assert_eq!(s.as_bytes_with_null_consume(), v);
+    }
+
+    #[test]
     #[ignore(cfg(windows))]
     #[should_fail]
     fn test_as_bytes_fail() {
-        // Don't double free
-        as_bytes::<()>(&~"", |_bytes| fail!() );
+        // Don't double free. (I'm not sure if this exercises the
+        // original problem code path anymore.)
+        let s = ~"";
+        let _bytes = s.as_bytes_with_null();
+        fail!();
     }
 
     #[test]
@@ -3581,14 +3001,14 @@ mod tests {
     #[test]
     fn test_subslice_offset() {
         let a = "kernelsprite";
-        let b = slice(a, 7, len(a));
-        let c = slice(a, 0, len(a) - 6);
+        let b = a.slice(7, a.len());
+        let c = a.slice(0, a.len() - 6);
         assert_eq!(subslice_offset(a, b), 7);
         assert_eq!(subslice_offset(a, c), 0);
 
         let string = "a\nb\nc";
         let mut lines = ~[];
-        for each_line(string) |line| { lines.push(line) }
+        for string.line_iter().advance |line| { lines.push(line) }
         assert_eq!(subslice_offset(string, lines[0]), 0);
         assert_eq!(subslice_offset(string, lines[1]), 2);
         assert_eq!(subslice_offset(string, lines[2]), 4);
@@ -3606,11 +3026,11 @@ mod tests {
     fn vec_str_conversions() {
         let s1: ~str = ~"All mimsy were the borogoves";
 
-        let v: ~[u8] = to_bytes(s1);
+        let v: ~[u8] = s1.as_bytes().to_owned();
         let s2: ~str = from_bytes(v);
         let mut i: uint = 0u;
-        let n1: uint = len(s1);
-        let n2: uint = vec::len::<u8>(v);
+        let n1: uint = s1.len();
+        let n2: uint = v.len();
         assert_eq!(n1, n2);
         while i < n1 {
             let a: u8 = s1[i];
@@ -3624,99 +3044,27 @@ mod tests {
 
     #[test]
     fn test_contains() {
-        assert!(contains("abcde", "bcd"));
-        assert!(contains("abcde", "abcd"));
-        assert!(contains("abcde", "bcde"));
-        assert!(contains("abcde", ""));
-        assert!(contains("", ""));
-        assert!(!contains("abcde", "def"));
-        assert!(!contains("", "a"));
+        assert!("abcde".contains("bcd"));
+        assert!("abcde".contains("abcd"));
+        assert!("abcde".contains("bcde"));
+        assert!("abcde".contains(""));
+        assert!("".contains(""));
+        assert!(!"abcde".contains("def"));
+        assert!(!"".contains("a"));
 
         let data = ~"ประเทศไทย中华Việt Nam";
-        assert!(contains(data, "ประเ"));
-        assert!(contains(data, "ะเ"));
-        assert!(contains(data, "中华"));
-        assert!(!contains(data, "ไท华"));
+        assert!(data.contains("ประเ"));
+        assert!(data.contains("ะเ"));
+        assert!(data.contains("中华"));
+        assert!(!data.contains("ไท华"));
     }
 
     #[test]
     fn test_contains_char() {
-        assert!(contains_char("abc", 'b'));
-        assert!(contains_char("a", 'a'));
-        assert!(!contains_char("abc", 'd'));
-        assert!(!contains_char("", 'a'));
-    }
-
-    #[test]
-    fn test_split_char_each() {
-        let data = "\nMary had a little lamb\nLittle lamb\n";
-
-        let mut ii = 0;
-
-        for each_split_char(data, ' ') |xx| {
-            match ii {
-              0 => assert!("\nMary" == xx),
-              1 => assert!("had"    == xx),
-              2 => assert!("a"      == xx),
-              3 => assert!("little" == xx),
-              _ => ()
-            }
-            ii += 1;
-        }
-    }
-
-    #[test]
-    fn test_splitn_char_each() {
-        let data = "\nMary had a little lamb\nLittle lamb\n";
-
-        let mut ii = 0;
-
-        for each_splitn_char(data, ' ', 2u) |xx| {
-            match ii {
-              0 => assert!("\nMary" == xx),
-              1 => assert!("had"    == xx),
-              2 => assert!("a little lamb\nLittle lamb\n" == xx),
-              _ => ()
-            }
-            ii += 1;
-        }
-    }
-
-    #[test]
-    fn test_words_each() {
-        let data = "\nMary had a little lamb\nLittle lamb\n";
-
-        let mut ii = 0;
-
-        for each_word(data) |ww| {
-            match ii {
-              0 => assert!("Mary"   == ww),
-              1 => assert!("had"    == ww),
-              2 => assert!("a"      == ww),
-              3 => assert!("little" == ww),
-              _ => ()
-            }
-            ii += 1;
-        }
-
-        each_word("", |_x| fail!()); // should not fail
-    }
-
-    #[test]
-    fn test_lines_each () {
-        let lf = "\nMary had a little lamb\nLittle lamb\n";
-
-        let mut ii = 0;
-
-        for each_line(lf) |x| {
-            match ii {
-                0 => assert!("" == x),
-                1 => assert!("Mary had a little lamb" == x),
-                2 => assert!("Little lamb" == x),
-                _ => ()
-            }
-            ii += 1;
-        }
+        assert!("abc".contains_char('b'));
+        assert!("a".contains_char('a'));
+        assert!(!"abc".contains_char('d'));
+        assert!(!"".contains_char('a'));
     }
 
     #[test]
@@ -3726,32 +3074,6 @@ mod tests {
     }
 
     #[test]
-    fn test_all() {
-        assert_eq!(true, all("", char::is_uppercase));
-        assert_eq!(false, all("ymca", char::is_uppercase));
-        assert_eq!(true, all("YMCA", char::is_uppercase));
-        assert_eq!(false, all("yMCA", char::is_uppercase));
-        assert_eq!(false, all("YMCy", char::is_uppercase));
-    }
-
-    #[test]
-    fn test_any() {
-        assert_eq!(false, any("", char::is_uppercase));
-        assert_eq!(false, any("ymca", char::is_uppercase));
-        assert_eq!(true, any("YMCA", char::is_uppercase));
-        assert_eq!(true, any("yMCA", char::is_uppercase));
-        assert_eq!(true, any("Ymcy", char::is_uppercase));
-    }
-
-    #[test]
-    fn test_chars() {
-        let ss = ~"ศไทย中华Việt Nam";
-        assert!(~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a',
-                       'm']
-            == to_chars(ss));
-    }
-
-    #[test]
     fn test_utf16() {
         let pairs =
             [(~"𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n",
@@ -3815,85 +3137,107 @@ mod tests {
         let s = ~"ศไทย中华Việt Nam";
         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
         let mut pos = s.len();
-        for v.each_reverse |ch| {
+        for v.rev_iter().advance |ch| {
             assert!(s.char_at_reverse(pos) == *ch);
             pos -= from_char(*ch).len();
         }
     }
 
     #[test]
-    fn test_each() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = 0;
+    fn test_escape_unicode() {
+        assert_eq!("abc".escape_unicode(), ~"\\x61\\x62\\x63");
+        assert_eq!("a c".escape_unicode(), ~"\\x61\\x20\\x63");
+        assert_eq!("\r\n\t".escape_unicode(), ~"\\x0d\\x0a\\x09");
+        assert_eq!("'\"\\".escape_unicode(), ~"\\x27\\x22\\x5c");
+        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), ~"\\x00\\x01\\xfe\\xff");
+        assert_eq!("\u0100\uffff".escape_unicode(), ~"\\u0100\\uffff");
+        assert_eq!("\U00010000\U0010ffff".escape_unicode(), ~"\\U00010000\\U0010ffff");
+        assert_eq!("ab\ufb00".escape_unicode(), ~"\\x61\\x62\\ufb00");
+        assert_eq!("\U0001d4ea\r".escape_unicode(), ~"\\U0001d4ea\\x0d");
+    }
 
-        for s.each |b| {
-            assert_eq!(b, v[pos]);
-            pos += 1;
-        }
+    #[test]
+    fn test_escape_default() {
+        assert_eq!("abc".escape_default(), ~"abc");
+        assert_eq!("a c".escape_default(), ~"a c");
+        assert_eq!("\r\n\t".escape_default(), ~"\\r\\n\\t");
+        assert_eq!("'\"\\".escape_default(), ~"\\'\\\"\\\\");
+        assert_eq!("\u0100\uffff".escape_default(), ~"\\u0100\\uffff");
+        assert_eq!("\U00010000\U0010ffff".escape_default(), ~"\\U00010000\\U0010ffff");
+        assert_eq!("ab\ufb00".escape_default(), ~"ab\\ufb00");
+        assert_eq!("\U0001d4ea\r".escape_default(), ~"\\U0001d4ea\\r");
     }
 
     #[test]
-    fn test_each_empty() {
-        for "".each |b| {
-            assert_eq!(b, 0u8);
-        }
+    fn test_to_managed() {
+        assert_eq!("abc".to_managed(), @"abc");
+        assert_eq!("abcdef".slice(1, 5).to_managed(), @"bcde");
+    }
+
+    #[test]
+    fn test_total_ord() {
+        "1234".cmp(& &"123") == Greater;
+        "123".cmp(& &"1234") == Less;
+        "1234".cmp(& &"1234") == Equal;
+        "12345555".cmp(& &"123456") == Less;
+        "22".cmp(& &"1234") == Greater;
+    }
+
+    #[test]
+    fn test_char_range_at_reverse_underflow() {
+        assert_eq!("abc".char_range_at_reverse(0).next, 0);
     }
 
     #[test]
-    fn test_eachi() {
+    fn test_iterator() {
+        use iterator::*;
         let s = ~"ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
+        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
         let mut pos = 0;
+        let mut it = s.iter();
 
-        for s.eachi |i, b| {
-            assert_eq!(pos, i);
-            assert_eq!(b, v[pos]);
+        for it.advance |c| {
+            assert_eq!(c, v[pos]);
             pos += 1;
         }
+        assert_eq!(pos, v.len());
     }
 
     #[test]
-    fn test_eachi_empty() {
-        for "".eachi |i, b| {
-            assert_eq!(i, 0);
-            assert_eq!(b, 0);
+    fn test_rev_iterator() {
+        use iterator::*;
+        let s = ~"ศไทย中华Việt Nam";
+        let v = ~['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+        let mut pos = 0;
+        let mut it = s.rev_iter();
+
+        for it.advance |c| {
+            assert_eq!(c, v[pos]);
+            pos += 1;
         }
+        assert_eq!(pos, v.len());
     }
 
     #[test]
-    fn test_each_reverse() {
+    fn test_bytes_iterator() {
         let s = ~"ศไทย中华Việt Nam";
         let v = [
             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
             109
         ];
-        let mut pos = v.len();
+        let mut pos = 0;
 
-        for s.each_reverse |b| {
-            pos -= 1;
+        for s.bytes_iter().advance |b| {
             assert_eq!(b, v[pos]);
+            pos += 1;
         }
     }
 
     #[test]
-    fn test_each_empty_reverse() {
-        for "".each_reverse |b| {
-            assert_eq!(b, 0u8);
-        }
-    }
-
-    #[test]
-    fn test_eachi_reverse() {
+    fn test_bytes_rev_iterator() {
         let s = ~"ศไทย中华Việt Nam";
         let v = [
             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
@@ -3902,128 +3246,95 @@ mod tests {
         ];
         let mut pos = v.len();
 
-        for s.eachi_reverse |i, b| {
+        for s.bytes_rev_iter().advance |b| {
             pos -= 1;
-            assert_eq!(pos, i);
             assert_eq!(b, v[pos]);
         }
     }
 
     #[test]
-    fn test_eachi_reverse_empty() {
-        for "".eachi_reverse |i, b| {
-            assert_eq!(i, 0);
-            assert_eq!(b, 0);
-        }
-    }
+    fn test_split_char_iterator() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-    #[test]
-    fn test_each_char() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for s.each_char |ch| {
-            assert_eq!(ch, v[pos]);
-            pos += 1;
-        }
-    }
+        let split: ~[&str] = data.split_iter(' ').collect();
+        assert_eq!(split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-    #[test]
-    fn test_each_chari() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for s.each_chari |i, ch| {
-            assert_eq!(pos, i);
-            assert_eq!(ch, v[pos]);
-            pos += 1;
-        }
-    }
+        let split: ~[&str] = data.split_iter(|c: char| c == ' ').collect();
+        assert_eq!(split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-    #[test]
-    fn test_each_char_reverse() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = v.len();
-        for s.each_char_reverse |ch| {
-            pos -= 1;
-            assert_eq!(ch, v[pos]);
-        }
-    }
+        // Unicode
+        let split: ~[&str] = data.split_iter('ä').collect();
+        assert_eq!(split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-    #[test]
-    fn test_each_chari_reverse() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = v.len();
-        for s.each_chari_reverse |i, ch| {
-            pos -= 1;
-            assert_eq!(pos, i);
-            assert_eq!(ch, v[pos]);
-        }
+        let split: ~[&str] = data.split_iter(|c: char| c == 'ä').collect();
+        assert_eq!(split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
     }
-
     #[test]
-    fn test_escape_unicode() {
-        assert_eq!(escape_unicode("abc"), ~"\\x61\\x62\\x63");
-        assert_eq!(escape_unicode("a c"), ~"\\x61\\x20\\x63");
-        assert_eq!(escape_unicode("\r\n\t"), ~"\\x0d\\x0a\\x09");
-        assert_eq!(escape_unicode("'\"\\"), ~"\\x27\\x22\\x5c");
-        assert!(escape_unicode("\x00\x01\xfe\xff") ==
-                     ~"\\x00\\x01\\xfe\\xff");
-        assert_eq!(escape_unicode("\u0100\uffff"), ~"\\u0100\\uffff");
-        assert!(escape_unicode("\U00010000\U0010ffff") ==
-            ~"\\U00010000\\U0010ffff");
-        assert_eq!(escape_unicode("ab\ufb00"), ~"\\x61\\x62\\ufb00");
-        assert_eq!(escape_unicode("\U0001d4ea\r"), ~"\\U0001d4ea\\x0d");
-    }
+    fn test_splitn_char_iterator() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-    #[test]
-    fn test_escape_default() {
-        assert_eq!(escape_default("abc"), ~"abc");
-        assert_eq!(escape_default("a c"), ~"a c");
-        assert_eq!(escape_default("\r\n\t"), ~"\\r\\n\\t");
-        assert_eq!(escape_default("'\"\\"), ~"\\'\\\"\\\\");
-        assert_eq!(escape_default("\u0100\uffff"), ~"\\u0100\\uffff");
-        assert!(escape_default("\U00010000\U0010ffff") ==
-            ~"\\U00010000\\U0010ffff");
-        assert_eq!(escape_default("ab\ufb00"), ~"ab\\ufb00");
-        assert_eq!(escape_default("\U0001d4ea\r"), ~"\\U0001d4ea\\r");
-    }
+        let split: ~[&str] = data.splitn_iter(' ', 3).collect();
+        assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
-    #[test]
-    fn test_to_managed() {
-        assert_eq!("abc".to_managed(), @"abc");
-        assert_eq!(slice("abcdef", 1, 5).to_managed(), @"bcde");
+        let split: ~[&str] = data.splitn_iter(|c: char| c == ' ', 3).collect();
+        assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+        // Unicode
+        let split: ~[&str] = data.splitn_iter('ä', 3).collect();
+        assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+
+        let split: ~[&str] = data.splitn_iter(|c: char| c == 'ä', 3).collect();
+        assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
     }
 
     #[test]
-    fn test_total_ord() {
-        "1234".cmp(& &"123") == Greater;
-        "123".cmp(& &"1234") == Less;
-        "1234".cmp(& &"1234") == Equal;
-        "12345555".cmp(& &"123456") == Less;
-        "22".cmp(& &"1234") == Greater;
+    fn test_split_char_iterator_no_trailing() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+        let split: ~[&str] = data.split_options_iter('\n', 1000, true).collect();
+        assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb", ""]);
+
+        let split: ~[&str] = data.split_options_iter('\n', 1000, false).collect();
+        assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb"]);
     }
 
     #[test]
-    fn test_char_range_at_reverse_underflow() {
-        assert_eq!(char_range_at_reverse("abc", 0).next, 0);
+    fn test_word_iter() {
+        let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
+        let words: ~[&str] = data.word_iter().collect();
+        assert_eq!(words, ~["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
     }
 
     #[test]
-    fn test_iterator() {
-        use iterator::*;
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+    fn test_line_iter() {
+        let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
+        let lines: ~[&str] = data.line_iter().collect();
+        assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
 
-        let mut pos = 0;
-        let mut it = s.char_iter();
+        let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
+        let lines: ~[&str] = data.line_iter().collect();
+        assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
+    }
 
-        for it.advance |c| {
-            assert_eq!(c, v[pos]);
-            pos += 1;
+    #[test]
+    fn test_split_str_iterator() {
+        fn t<'a>(s: &str, sep: &'a str, u: ~[&str]) {
+            let v: ~[&str] = s.split_str_iter(sep).collect();
+            assert_eq!(v, u);
         }
-        assert_eq!(pos, v.len());
+        t("--1233345--", "12345", ~["--1233345--"]);
+        t("abc::hello::there", "::", ~["abc", "hello", "there"]);
+        t("::hello::there", "::", ~["", "hello", "there"]);
+        t("hello::there::", "::", ~["hello", "there", ""]);
+        t("::hello::there::", "::", ~["", "hello", "there", ""]);
+        t("ประเทศไทย中华Việt Nam", "中华", ~["ประเทศไทย", "Việt Nam"]);
+        t("zzXXXzzYYYzz", "zz", ~["", "XXX", "YYY", ""]);
+        t("zzXXXzYYYz", "XXX", ~["zz", "zYYYz"]);
+        t(".XXX.YYY.", ".", ~["", "XXX", "YYY", ""]);
+        t("", ".", ~[""]);
+        t("zz", "zz", ~["",""]);
+        t("ok", "z", ~["ok"]);
+        t("zzz", "zz", ~["","z"]);
+        t("zzzzz", "zz", ~["","","z"]);
     }
 }
diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs
index e48fef01df9..618d5095777 100644
--- a/src/libstd/str/ascii.rs
+++ b/src/libstd/str/ascii.rs
@@ -15,28 +15,29 @@ use str;
 use str::StrSlice;
 use cast;
 use old_iter::BaseIter;
+use iterator::IteratorUtil;
 use vec::{CopyableVector, ImmutableVector, OwnedVector};
 
 /// Datatype to hold one ascii character. It is 8 bit long.
 #[deriving(Clone, Eq)]
 pub struct Ascii { priv chr: u8 }
 
-pub impl Ascii {
+impl Ascii {
     /// Converts a ascii character into a `u8`.
     #[inline(always)]
-    fn to_byte(self) -> u8 {
+    pub fn to_byte(self) -> u8 {
         self.chr
     }
 
     /// Converts a ascii character into a `char`.
     #[inline(always)]
-    fn to_char(self) -> char {
+    pub fn to_char(self) -> char {
         self.chr as char
     }
 
     /// Convert to lowercase.
     #[inline(always)]
-    fn to_lower(self) -> Ascii {
+    pub fn to_lower(self) -> Ascii {
         if self.chr >= 65 && self.chr <= 90 {
             Ascii{chr: self.chr | 0x20 }
         } else {
@@ -46,7 +47,7 @@ pub impl Ascii {
 
     /// Convert to uppercase.
     #[inline(always)]
-    fn to_upper(self) -> Ascii {
+    pub fn to_upper(self) -> Ascii {
         if self.chr >= 97 && self.chr <= 122 {
             Ascii{chr: self.chr & !0x20 }
         } else {
@@ -54,9 +55,9 @@ pub impl Ascii {
         }
     }
 
-    // Compares two ascii characters of equality, ignoring case.
+    /// Compares two ascii characters of equality, ignoring case.
     #[inline(always)]
-    fn eq_ignore_case(self, other: Ascii) -> bool {
+    pub fn eq_ignore_case(self, other: Ascii) -> bool {
         self.to_lower().chr == other.to_lower().chr
     }
 }
@@ -101,10 +102,7 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
 
     #[inline(always)]
     fn is_ascii(&self) -> bool {
-        for self.each |b| {
-            if !b.is_ascii() { return false; }
-        }
-        true
+        self.bytes_iter().all(|b| b.is_ascii())
     }
 }
 
@@ -204,7 +202,6 @@ impl ToStrConsume for ~[Ascii] {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use str;
 
     macro_rules! v2ascii (
         ( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
@@ -228,8 +225,8 @@ mod tests {
         assert_eq!('`'.to_ascii().to_upper().to_char(), '`');
         assert_eq!('{'.to_ascii().to_upper().to_char(), '{');
 
-        assert!(str::all("banana", |c| c.is_ascii()));
-        assert!(! str::all("ประเทศไทย中华Việt Nam", |c| c.is_ascii()));
+        assert!("banana".iter().all(|c| c.is_ascii()));
+        assert!(!"ประเทศไทย中华Việt Nam".iter().all(|c| c.is_ascii()));
     }
 
     #[test]
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index 137070ce202..e49ad348542 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -10,9 +10,10 @@
 
 //! Misc low level stuff
 
+#[allow(missing_doc)];
+
 use option::{Some, None};
 use cast;
-use cmp::{Eq, Ord};
 use gc;
 use io;
 use libc;
@@ -50,20 +51,6 @@ pub mod rustrt {
     }
 }
 
-/// Compares contents of two pointers using the default method.
-/// Equivalent to `*x1 == *x2`.  Useful for hashtables.
-pub fn shape_eq<T:Eq>(x1: &T, x2: &T) -> bool {
-    *x1 == *x2
-}
-
-pub fn shape_lt<T:Ord>(x1: &T, x2: &T) -> bool {
-    *x1 < *x2
-}
-
-pub fn shape_le<T:Ord>(x1: &T, x2: &T) -> bool {
-    *x1 <= *x2
-}
-
 /**
  * Returns a pointer to a type descriptor.
  *
@@ -226,11 +213,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
                 gc::cleanup_stack_for_failure();
 
                 let task = Local::unsafe_borrow::<Task>();
-                let unwinder: &mut Option<Unwinder> = &mut (*task).unwinder;
-                match *unwinder {
-                    Some(ref mut unwinder) => unwinder.begin_unwind(),
-                    None => abort!("failure without unwinder. aborting process")
-                }
+                (*task).unwinder.begin_unwind();
             }
         }
     }
diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs
index d3757ea3f4f..f6b14a51539 100644
--- a/src/libstd/task/local_data_priv.rs
+++ b/src/libstd/task/local_data_priv.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(missing_doc)];
+
 use cast;
 use cmp::Eq;
 use libc;
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index f24d2327358..99858feab22 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -33,19 +33,26 @@
  * ~~~
  */
 
+#[allow(missing_doc)];
+
+use prelude::*;
+
 use cell::Cell;
 use cmp::Eq;
-use result::Result;
 use comm::{stream, Chan, GenericChan, GenericPort, Port};
-use prelude::*;
+use result::Result;
 use result;
+use rt::{context, OldTaskContext};
 use task::rt::{task_id, sched_id};
-use util;
-use util::replace;
 use unstable::finally::Finally;
-use rt::{context, OldTaskContext};
+use util::replace;
+use util;
 
+#[cfg(test)] use cast;
 #[cfg(test)] use comm::SharedChan;
+#[cfg(test)] use comm;
+#[cfg(test)] use ptr;
+#[cfg(test)] use task;
 
 mod local_data_priv;
 pub mod rt;
@@ -195,7 +202,7 @@ pub fn task() -> TaskBuilder {
     }
 }
 
-priv impl TaskBuilder {
+impl TaskBuilder {
     fn consume(&mut self) -> TaskBuilder {
         if self.consumed {
             fail!("Cannot copy a task_builder"); // Fake move mode on self
@@ -217,24 +224,24 @@ priv impl TaskBuilder {
     }
 }
 
-pub impl TaskBuilder {
+impl TaskBuilder {
     /// Decouple the child task's failure from the parent's. If either fails,
     /// the other will not be killed.
-    fn unlinked(&mut self) {
+    pub fn unlinked(&mut self) {
         self.opts.linked = false;
     }
 
     /// Unidirectionally link the child task's failure with the parent's. The
     /// child's failure will not kill the parent, but the parent's will kill
     /// the child.
-    fn supervised(&mut self) {
+    pub fn supervised(&mut self) {
         self.opts.supervised = true;
         self.opts.linked = false;
     }
 
     /// Link the child task's and parent task's failures. If either fails, the
     /// other will be killed.
-    fn linked(&mut self) {
+    pub fn linked(&mut self) {
         self.opts.linked = true;
         self.opts.supervised = false;
     }
@@ -256,7 +263,7 @@ pub impl TaskBuilder {
      * # Failure
      * Fails if a future_result was already set for this task.
      */
-    fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) {
+    pub fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) {
         // FIXME (#3725): Once linked failure and notification are
         // handled in the library, I can imagine implementing this by just
         // registering an arbitrary number of task::on_exit handlers and
@@ -276,7 +283,7 @@ pub impl TaskBuilder {
     }
 
     /// Configure a custom scheduler mode for the task.
-    fn sched_mode(&mut self, mode: SchedMode) {
+    pub fn sched_mode(&mut self, mode: SchedMode) {
         self.opts.sched.mode = mode;
     }
 
@@ -292,7 +299,7 @@ pub impl TaskBuilder {
      * generator by applying the task body which results from the
      * existing body generator to the new body generator.
      */
-    fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) {
+    pub fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) {
         let prev_gen_body = replace(&mut self.gen_body, None);
         let prev_gen_body = match prev_gen_body {
             Some(gen) => gen,
@@ -301,7 +308,7 @@ pub impl TaskBuilder {
                 f
             }
         };
-        let prev_gen_body = Cell(prev_gen_body);
+        let prev_gen_body = Cell::new(prev_gen_body);
         let next_gen_body = {
             let f: ~fn(~fn()) -> ~fn() = |body| {
                 let prev_gen_body = prev_gen_body.take();
@@ -324,7 +331,7 @@ pub impl TaskBuilder {
      * When spawning into a new scheduler, the number of threads requested
      * must be greater than zero.
      */
-    fn spawn(&mut self, f: ~fn()) {
+    pub fn spawn(&mut self, f: ~fn()) {
         let gen_body = replace(&mut self.gen_body, None);
         let notify_chan = replace(&mut self.opts.notify_chan, None);
         let x = self.consume();
@@ -346,8 +353,8 @@ pub impl TaskBuilder {
     }
 
     /// Runs a task, while transfering ownership of one argument to the child.
-    fn spawn_with<A:Owned>(&mut self, arg: A, f: ~fn(v: A)) {
-        let arg = Cell(arg);
+    pub fn spawn_with<A:Owned>(&mut self, arg: A, f: ~fn(v: A)) {
+        let arg = Cell::new(arg);
         do self.spawn {
             f(arg.take());
         }
@@ -366,7 +373,7 @@ pub impl TaskBuilder {
      * # Failure
      * Fails if a future_result was already set for this task.
      */
-    fn try<T:Owned>(&mut self, f: ~fn() -> T) -> Result<T,()> {
+    pub fn try<T:Owned>(&mut self, f: ~fn() -> T) -> Result<T,()> {
         let (po, ch) = stream::<T>();
         let mut result = None;
 
@@ -513,20 +520,9 @@ pub fn failing() -> bool {
             }
         }
         _ => {
-            let mut unwinding = false;
-            do Local::borrow::<Task> |local| {
-                unwinding = match local.unwinder {
-                    Some(unwinder) => {
-                        unwinder.unwinding
-                    }
-                    None => {
-                        // Because there is no unwinder we can't be unwinding.
-                        // (The process will abort on failure)
-                        false
-                    }
-                }
+            do Local::borrow::<Task, bool> |local| {
+                local.unwinder.unwinding
             }
-            return unwinding;
         }
     }
 }
@@ -784,9 +780,9 @@ struct Wrapper {
 fn test_add_wrapper() {
     let (po, ch) = stream::<()>();
     let mut b0 = task();
-    let ch = Cell(ch);
+    let ch = Cell::new(ch);
     do b0.add_wrapper |body| {
-        let ch = Cell(ch.take());
+        let ch = Cell::new(ch.take());
         let result: ~fn() = || {
             let ch = ch.take();
             body();
@@ -883,10 +879,10 @@ fn test_spawn_sched_childs_on_default_sched() {
     // Assuming tests run on the default scheduler
     let default_id = unsafe { rt::rust_get_sched_id() };
 
-    let ch = Cell(ch);
+    let ch = Cell::new(ch);
     do spawn_sched(SingleThreaded) {
         let parent_sched_id = unsafe { rt::rust_get_sched_id() };
-        let ch = Cell(ch.take());
+        let ch = Cell::new(ch.take());
         do spawn {
             let ch = ch.take();
             let child_sched_id = unsafe { rt::rust_get_sched_id() };
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 5941221821a..9df93d19d21 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -72,12 +72,13 @@
 
 #[doc(hidden)];
 
+use prelude::*;
+
 use cast::transmute;
 use cast;
 use cell::Cell;
 use container::Map;
 use comm::{Chan, GenericChan};
-use prelude::*;
 use ptr;
 use hashmap::HashSet;
 use task::local_data_priv::{local_get, local_set, OldHandle};
@@ -91,8 +92,12 @@ use uint;
 use util;
 use unstable::sync::{Exclusive, exclusive};
 use rt::local::Local;
+use iterator::{IteratorUtil};
+use rt::task::Task;
 
 #[cfg(test)] use task::default_task_opts;
+#[cfg(test)] use comm;
+#[cfg(test)] use task;
 
 macro_rules! move_it (
     { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } )
@@ -159,13 +164,17 @@ struct AncestorList(Option<Exclusive<AncestorNode>>);
 // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety.
 #[inline(always)]
 fn access_group<U>(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U {
-    x.with(blk)
+    unsafe {
+        x.with(blk)
+    }
 }
 
 #[inline(always)]
 fn access_ancestors<U>(x: &Exclusive<AncestorNode>,
                        blk: &fn(x: &mut AncestorNode) -> U) -> U {
-    x.with(blk)
+    unsafe {
+        x.with(blk)
+    }
 }
 
 // Iterates over an ancestor list.
@@ -269,7 +278,7 @@ fn each_ancestor(list:        &mut AncestorList,
                  * Step 3: Maybe unwind; compute return info for our caller.
                  *##########################################################*/
                 if need_unwind && !nobe_is_dead {
-                    for bail_opt.each |bail_blk| {
+                    for bail_opt.iter().advance |bail_blk| {
                         do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
                             (*bail_blk)(tg_opt)
                         }
@@ -316,11 +325,12 @@ impl Drop for TCB {
     // Runs on task exit.
     fn finalize(&self) {
         unsafe {
+            // FIXME(#4330) Need self by value to get mutability.
             let this: &mut TCB = transmute(self);
 
             // If we are failing, the whole taskgroup needs to die.
             if rt::rust_task_is_unwinding(self.me) {
-                for this.notifier.each_mut |x| {
+                for this.notifier.mut_iter().advance |x| {
                     x.failed = true;
                 }
                 // Take everybody down with us.
@@ -349,7 +359,7 @@ fn TCB(me: *rust_task,
        ancestors: AncestorList,
        is_main: bool,
        mut notifier: Option<AutoNotify>) -> TCB {
-    for notifier.each_mut |x| {
+    for notifier.mut_iter().advance |x| {
         x.failed = false;
     }
 
@@ -576,9 +586,14 @@ pub fn spawn_raw(opts: TaskOpts, f: ~fn()) {
 fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) {
     use rt::sched::*;
 
+    let task = do Local::borrow::<Task, ~Task>() |running_task| {
+        ~running_task.new_child()
+    };
+
     let mut sched = Local::take::<Scheduler>();
-    let task = ~Coroutine::new(&mut sched.stack_pool, f);
-    sched.schedule_new_task(task);
+    let task = ~Coroutine::with_task(&mut sched.stack_pool,
+                                     task, f);
+    sched.schedule_task(task);
 }
 
 fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
@@ -587,7 +602,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
         gen_child_taskgroup(opts.linked, opts.supervised);
 
     unsafe {
-        let child_data = Cell((child_tg, ancestors, f));
+        let child_data = Cell::new((child_tg, ancestors, f));
         // Being killed with the unsafe task/closure pointers would leak them.
         do unkillable {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
@@ -629,7 +644,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
                           notify_chan: Option<Chan<TaskResult>>,
                           f: ~fn())
                        -> ~fn() {
-        let child_data = Cell((child_arc, ancestors));
+        let child_data = Cell::new((child_arc, ancestors));
         let result: ~fn() = || {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
             let mut (child_arc, ancestors) = child_data.take();
diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs
index 20b45dfb2cc..c0c8b729f9e 100644
--- a/src/libstd/to_bytes.rs
+++ b/src/libstd/to_bytes.rs
@@ -18,7 +18,7 @@ use io;
 use io::Writer;
 use option::{None, Option, Some};
 use old_iter::BaseIter;
-use str;
+use str::StrSlice;
 
 pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;
 
@@ -239,27 +239,25 @@ impl<A:IterBytes> IterBytes for @[A] {
 impl<'self> IterBytes for &'self str {
     #[inline(always)]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
-        do str::byte_slice(*self) |bytes| {
-            f(bytes)
-        }
+        f(self.as_bytes())
     }
 }
 
 impl IterBytes for ~str {
     #[inline(always)]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
-        do str::byte_slice(*self) |bytes| {
-            f(bytes)
-        }
+        // this should possibly include the null terminator, but that
+        // breaks .find_equiv on hashmaps.
+        f(self.as_bytes())
     }
 }
 
 impl IterBytes for @str {
     #[inline(always)]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
-        do str::byte_slice(*self) |bytes| {
-            f(bytes)
-        }
+        // this should possibly include the null terminator, but that
+        // breaks .find_equiv on hashmaps.
+        f(self.as_bytes())
     }
 }
 
@@ -303,7 +301,11 @@ impl<A> IterBytes for *const A {
     }
 }
 
+/// A trait for converting a value to a list of bytes.
 pub trait ToBytes {
+    /// Converts the current value to a list of bytes. This is equivalent to
+    /// invoking iter_bytes on a type and collecting all yielded values in an
+    /// array
     fn to_bytes(&self, lsb0: bool) -> ~[u8];
 }
 
diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs
index 9ca54066289..bfda92d46a2 100644
--- a/src/libstd/to_str.rs
+++ b/src/libstd/to_str.rs
@@ -22,20 +22,18 @@ use hash::Hash;
 use cmp::Eq;
 use old_iter::BaseIter;
 
+/// A generic trait for converting a value to a string
 pub trait ToStr {
+    /// Converts the value of `self` to an owned string
     fn to_str(&self) -> ~str;
 }
 
 /// Trait for converting a type to a string, consuming it in the process.
 pub trait ToStrConsume {
-    // Cosume and convert to a string.
+    /// Cosume and convert to a string.
     fn to_str_consume(self) -> ~str;
 }
 
-impl ToStr for bool {
-    #[inline(always)]
-    fn to_str(&self) -> ~str { ::bool::to_str(*self) }
-}
 impl ToStr for () {
     #[inline(always)]
     fn to_str(&self) -> ~str { ~"()" }
@@ -46,7 +44,7 @@ impl<A:ToStr> ToStr for (A,) {
     fn to_str(&self) -> ~str {
         match *self {
             (ref a,) => {
-                ~"(" + a.to_str() + ",)"
+                fmt!("(%s,)", (*a).to_str())
             }
         }
     }
@@ -55,7 +53,7 @@ impl<A:ToStr> ToStr for (A,) {
 impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-        let mut acc = ~"{", first = true;
+        let mut (acc, first) = (~"{", true);
         for self.each |key, value| {
             if first {
                 first = false;
@@ -75,29 +73,29 @@ impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
 impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-    let mut acc = ~"{", first = true;
-    for self.each |element| {
-        if first {
-            first = false;
-        }
-        else {
-            acc.push_str(", ");
+        let mut (acc, first) = (~"{", true);
+        for self.each |element| {
+            if first {
+                first = false;
+            }
+            else {
+                acc.push_str(", ");
+            }
+            acc.push_str(element.to_str());
         }
-        acc.push_str(element.to_str());
-    }
-    acc.push_char('}');
-    acc
+        acc.push_char('}');
+        acc
     }
 }
 
 impl<A:ToStr,B:ToStr> ToStr for (A, B) {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-        // FIXME(#4760): this causes an llvm assertion
+        // FIXME(#4653): this causes an llvm assertion
         //let &(ref a, ref b) = self;
         match *self {
             (ref a, ref b) => {
-                ~"(" + a.to_str() + ", " + b.to_str() + ")"
+                fmt!("(%s, %s)", (*a).to_str(), (*b).to_str())
             }
         }
     }
@@ -106,7 +104,7 @@ impl<A:ToStr,B:ToStr> ToStr for (A, B) {
 impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-        // FIXME(#4760): this causes an llvm assertion
+        // FIXME(#4653): this causes an llvm assertion
         //let &(ref a, ref b, ref c) = self;
         match *self {
             (ref a, ref b, ref c) => {
@@ -123,7 +121,7 @@ impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
 impl<'self,A:ToStr> ToStr for &'self [A] {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-        let mut acc = ~"[", first = true;
+        let mut (acc, first) = (~"[", true);
         for self.each |elt| {
             if first {
                 first = false;
@@ -141,7 +139,7 @@ impl<'self,A:ToStr> ToStr for &'self [A] {
 impl<A:ToStr> ToStr for ~[A] {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-        let mut acc = ~"[", first = true;
+        let mut (acc, first) = (~"[", true);
         for self.each |elt| {
             if first {
                 first = false;
@@ -159,7 +157,7 @@ impl<A:ToStr> ToStr for ~[A] {
 impl<A:ToStr> ToStr for @[A] {
     #[inline(always)]
     fn to_str(&self) -> ~str {
-        let mut acc = ~"[", first = true;
+        let mut (acc, first) = (~"[", true);
         for self.each |elt| {
             if first {
                 first = false;
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index 13b892e700e..4bd3946f885 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -11,6 +11,8 @@
 //! An ordered map and set for integer keys implemented as a radix trie
 
 use prelude::*;
+use iterator::IteratorUtil;
+use uint;
 use util::{swap, replace};
 
 // FIXME: #5244: need to manually update the TrieNode constructor
@@ -24,6 +26,7 @@ enum Child<T> {
     Nothing
 }
 
+#[allow(missing_doc)]
 pub struct TrieMap<T> {
     priv root: TrieNode<T>,
     priv length: uint
@@ -142,32 +145,33 @@ impl<T> Map<uint, T> for TrieMap<T> {
     }
 }
 
-pub impl<T> TrieMap<T> {
+impl<T> TrieMap<T> {
     /// Create an empty TrieMap
     #[inline(always)]
-    fn new() -> TrieMap<T> {
+    pub fn new() -> TrieMap<T> {
         TrieMap{root: TrieNode::new(), length: 0}
     }
 
     /// Visit all key-value pairs in reverse order
     #[inline(always)]
-    fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
+    pub fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
         self.root.each_reverse(f)
     }
 
     /// Visit all keys in reverse order
     #[inline(always)]
-    fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool {
+    pub fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool {
         self.each_reverse(|k, _| f(k))
     }
 
     /// Visit all values in reverse order
     #[inline(always)]
-    fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
+    pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
         self.each_reverse(|_, v| f(v))
     }
 }
 
+#[allow(missing_doc)]
 pub struct TrieSet {
     priv map: TrieMap<()>
 }
@@ -204,28 +208,32 @@ impl Mutable for TrieSet {
     fn clear(&mut self) { self.map.clear() }
 }
 
-pub impl TrieSet {
+impl TrieSet {
     /// Create an empty TrieSet
     #[inline(always)]
-    fn new() -> TrieSet {
+    pub fn new() -> TrieSet {
         TrieSet{map: TrieMap::new()}
     }
 
     /// Return true if the set contains a value
     #[inline(always)]
-    fn contains(&self, value: &uint) -> bool {
+    pub fn contains(&self, value: &uint) -> bool {
         self.map.contains_key(value)
     }
 
     /// Add a value to the set. Return true if the value was not already
     /// present in the set.
     #[inline(always)]
-    fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }
+    pub fn insert(&mut self, value: uint) -> bool {
+        self.map.insert(value, ())
+    }
 
     /// Remove a value from the set. Return true if the value was
     /// present in the set.
     #[inline(always)]
-    fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
+    pub fn remove(&mut self, value: &uint) -> bool {
+        self.map.remove(value)
+    }
 }
 
 struct TrieNode<T> {
@@ -269,7 +277,7 @@ impl<T> TrieNode<T> {
     }
 
     fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
-        for vec::each_mut(self.children) |child| {
+        for self.children.mut_iter().advance |child| {
             match *child {
                 Internal(ref mut x) => if !x.mutate_values(f) {
                     return false
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 639df89a377..589c18de0ab 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -10,14 +10,20 @@
 
 //! Operations on tuples
 
+#[allow(missing_doc)];
+
 use kinds::Copy;
 use vec;
 
 pub use self::inner::*;
 
+/// Method extensions to pairs where both types satisfy the `Copy` bound
 pub trait CopyableTuple<T, U> {
+    /// Return the first element of self
     fn first(&self) -> T;
+    /// Return the second element of self
     fn second(&self) -> U;
+    /// Return the results of swapping the two elements of self
     fn swap(&self) -> (U, T);
 }
 
@@ -47,8 +53,12 @@ impl<T:Copy,U:Copy> CopyableTuple<T, U> for (T, U) {
     }
 }
 
+/// Method extensions for pairs where the types don't necessarily satisfy the
+/// `Copy` bound
 pub trait ImmutableTuple<T, U> {
+    /// Return a reference to the first element of self
     fn first_ref<'a>(&'a self) -> &'a T;
+    /// Return a reference to the second element of self
     fn second_ref<'a>(&'a self) -> &'a U;
 }
 
@@ -402,7 +412,7 @@ mod tests {
 
     #[test]
     fn test_tuple_cmp() {
-        let small = (1u, 2u, 3u), big = (3u, 2u, 1u);
+        let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
 
         // Eq
         assert_eq!(small, small);
diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs
index ce584c0f1ba..f8f56c75a29 100644
--- a/src/libstd/unicode.rs
+++ b/src/libstd/unicode.rs
@@ -10,6 +10,8 @@
 
 // The following code was generated by "src/etc/unicode.py"
 
+#[allow(missing_doc)];
+
 pub mod general_category {
 
     fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs
index 58d0c01f990..aa70897ad48 100644
--- a/src/libstd/unstable/atomics.rs
+++ b/src/libstd/unstable/atomics.rs
@@ -155,11 +155,13 @@ impl AtomicInt {
         unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
     }
 
+    /// Returns the old value (like __sync_fetch_and_add).
     #[inline(always)]
     pub fn fetch_add(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_add(&mut self.v, val, order) }
     }
 
+    /// Returns the old value (like __sync_fetch_and_sub).
     #[inline(always)]
     pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_sub(&mut self.v, val, order) }
@@ -191,11 +193,13 @@ impl AtomicUint {
         unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
     }
 
+    /// Returns the old value (like __sync_fetch_and_add).
     #[inline(always)]
     pub fn fetch_add(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_add(&mut self.v, val, order) }
     }
 
+    /// Returns the old value (like __sync_fetch_and_sub)..
     #[inline(always)]
     pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_sub(&mut self.v, val, order) }
@@ -275,6 +279,7 @@ impl<T> Drop for AtomicOption<T> {
         // This will ensure that the contained data is
         // destroyed, unless it's null.
         unsafe {
+            // FIXME(#4330) Need self by value to get mutability.
             let this : &mut AtomicOption<T> = cast::transmute(self);
             let _ = this.take(SeqCst);
         }
@@ -314,6 +319,7 @@ pub unsafe fn atomic_swap<T>(dst: &mut T, val: T, order: Ordering) -> T {
     })
 }
 
+/// Returns the old value (like __sync_fetch_and_add).
 #[inline(always)]
 pub unsafe fn atomic_add<T>(dst: &mut T, val: T, order: Ordering) -> T {
     let dst = cast::transmute(dst);
@@ -326,6 +332,7 @@ pub unsafe fn atomic_add<T>(dst: &mut T, val: T, order: Ordering) -> T {
     })
 }
 
+/// Returns the old value (like __sync_fetch_and_sub).
 #[inline(always)]
 pub unsafe fn atomic_sub<T>(dst: &mut T, val: T, order: Ordering) -> T {
     let dst = cast::transmute(dst);
diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs
new file mode 100644
index 00000000000..96aba1d2971
--- /dev/null
+++ b/src/libstd/unstable/dynamic_lib.rs
@@ -0,0 +1,199 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+
+Dynamic library facilities.
+
+A simple wrapper over the platforms dynamic library facilities
+
+*/
+use ptr;
+use cast;
+use path;
+use libc;
+use ops::*;
+use option::*;
+use result::*;
+
+pub struct DynamicLibrary { priv handle: *libc::c_void }
+
+impl Drop for DynamicLibrary {
+    fn finalize(&self) {
+        match do dl::check_for_errors_in {
+            unsafe {
+                dl::close(self.handle)
+            }
+        } {
+            Ok(()) => { },
+            Err(str) => fail!(str)
+        }
+    }
+}
+
+impl DynamicLibrary {
+    /// Lazily open a dynamic library. When passed None it gives a
+    /// handle to the calling process
+    pub fn open(filename: Option<&path::Path>) -> Result<DynamicLibrary, ~str> {
+        let open_wrapper = |raw_ptr| {
+            do dl::check_for_errors_in {
+                unsafe {
+                    DynamicLibrary { handle: dl::open(raw_ptr) }
+                }
+            }
+        };
+
+        match filename {
+            Some(name) => do name.to_str().as_c_str |raw_name| {
+                open_wrapper(raw_name)
+            },
+            None => open_wrapper(ptr::null())
+        }
+    }
+
+    /// Access the value at the symbol of the dynamic library
+    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, ~str> {
+        // This function should have a lifetime constraint of 'self on
+        // T but that feature is still unimplemented
+
+        do dl::check_for_errors_in {
+            let symbol_value = do symbol.as_c_str |raw_string| {
+                dl::symbol(self.handle, raw_string)
+            };
+
+            cast::transmute(symbol_value)
+        }
+    }
+}
+
+#[test]
+priv fn test_loading_cosine () {
+    // The math library does not need to be loaded since it is already
+    // statically linked in
+    let libm = match DynamicLibrary::open(None) {
+        Err (error) => fail!("Could not load self as module: %s", error),
+        Ok (libm) => libm
+    };
+
+    // Unfortunately due to issue #6194 it is not possible to call
+    // this as a C function
+    let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
+        match libm.symbol("cos") {
+            Err (error) => fail!("Could not load function cos: %s", error),
+            Ok (cosine) => cosine
+        }
+    };
+
+    let argument = 0.0;
+    let expected_result = 1.0;
+    let result = cosine(argument);
+    if result != expected_result {
+        fail!("cos(%?) != %? but equaled %? instead", argument,
+              expected_result, result)
+    }
+}
+
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+mod dl {
+    use libc;
+    use ptr;
+    use str;
+    use task;
+    use result::*;
+
+    pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void {
+        dlopen(filename, Lazy as libc::c_int)
+    }
+
+    pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
+        unsafe {
+            do task::atomically {
+                let _old_error = dlerror();
+
+                let result = f();
+
+                let last_error = dlerror();
+                if ptr::null() == last_error {
+                    Ok(result)
+                } else {
+                    Err(str::raw::from_c_str(last_error))
+                }
+            }
+        }
+    }
+
+    pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
+        dlsym(handle, symbol)
+    }
+    pub unsafe fn close(handle: *libc::c_void) {
+        dlclose(handle); ()
+    }
+
+    pub enum RTLD {
+        Lazy = 1,
+        Now = 2,
+        Global = 256,
+        Local = 0,
+    }
+
+    #[link_name = "dl"]
+    extern {
+        fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
+        fn dlerror() -> *libc::c_char;
+        fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
+        fn dlclose(handle: *libc::c_void) -> libc::c_int;
+    }
+}
+
+#[cfg(target_os = "win32")]
+mod dl {
+    use os;
+    use libc;
+    use task;
+    use result::*;
+
+    pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void {
+        LoadLibrary(filename)
+    }
+
+    pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
+        unsafe {
+            do task::atomically {
+                SetLastError(0);
+
+                let result = f();
+
+                let error = os::errno();
+                if 0 == error {
+                    Ok(result)
+                } else {
+                    Err(fmt!("Error code %?", error))
+                }
+            }
+        }
+    }
+    pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
+        GetProcAddress(handle, symbol)
+    }
+    pub unsafe fn close(handle: *libc::c_void) {
+        FreeLibrary(handle); ()
+    }
+
+    #[link_name = "kernel32"]
+    extern "stdcall" {
+        fn SetLastError(error: u32);
+        fn LoadLibrary(name: *libc::c_char) -> *libc::c_void;
+        fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
+        fn FreeLibrary(handle: *libc::c_void);
+    }
+}
diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs
index 8da378fdc97..7d9ce585d7c 100644
--- a/src/libstd/unstable/extfmt.rs
+++ b/src/libstd/unstable/extfmt.rs
@@ -76,8 +76,8 @@ debug!("hello, %s!", "world");
 
 */
 
-use cmp::Eq;
 use prelude::*;
+use iterator::IteratorUtil;
 
 /*
  * We have a 'ct' (compile-time) module that parses format strings into a
@@ -139,8 +139,8 @@ pub mod ct {
         next: uint
     }
 
-    pub impl<T> Parsed<T> {
-        fn new(val: T, next: uint) -> Parsed<T> {
+    impl<T> Parsed<T> {
+        pub fn new(val: T, next: uint) -> Parsed<T> {
             Parsed {val: val, next: next}
         }
     }
@@ -325,7 +325,7 @@ pub mod ct {
             'o' => TyOctal,
             'f' => TyFloat,
             '?' => TyPoly,
-            _ => err(~"unknown type in conversion: " + s.substr(i, 1))
+            _ => err(fmt!("unknown type in conversion: %c", s.char_at(i)))
         };
 
         Parsed::new(t, i + 1)
@@ -546,8 +546,8 @@ pub mod rt {
         // displayed
         let unpadded = match cv.precision {
           CountImplied => s,
-          CountIs(max) => if (max as uint) < str::char_len(s) {
-            str::slice(s, 0, max as uint)
+          CountIs(max) => if (max as uint) < s.char_len() {
+            s.slice(0, max as uint)
           } else {
             s
           }
@@ -584,7 +584,7 @@ pub mod rt {
                 ~""
             } else {
                 let s = uint::to_str_radix(num, radix);
-                let len = str::char_len(s);
+                let len = s.char_len();
                 if len < prec {
                     let diff = prec - len;
                     let pad = str::from_chars(vec::from_elem(diff, '0'));
@@ -607,16 +607,16 @@ pub mod rt {
         let headsize = match head { Some(_) => 1, _ => 0 };
         let uwidth : uint = match cv.width {
             CountImplied => {
-                for head.each |&c| {
+                for head.iter().advance |&c| {
                     buf.push_char(c);
                 }
                 return buf.push_str(s);
             }
             CountIs(width) => { width as uint }
         };
-        let strlen = str::char_len(s) + headsize;
+        let strlen = s.char_len() + headsize;
         if uwidth <= strlen {
-            for head.each |&c| {
+            for head.iter().advance |&c| {
                 buf.push_char(c);
             }
             return buf.push_str(s);
@@ -624,7 +624,7 @@ pub mod rt {
         let mut padchar = ' ';
         let diff = uwidth - strlen;
         if have_flag(cv.flags, flag_left_justify) {
-            for head.each |&c| {
+            for head.iter().advance |&c| {
                 buf.push_char(c);
             }
             buf.push_str(s);
@@ -658,7 +658,7 @@ pub mod rt {
         // instead.
 
         if signed && zero_padding {
-            for head.each |&head| {
+            for head.iter().advance |&head| {
                 if head == '+' || head == '-' || head == ' ' {
                     buf.push_char(head);
                     buf.push_str(padstr);
@@ -668,7 +668,7 @@ pub mod rt {
             }
         }
         buf.push_str(padstr);
-        for head.each |&c| {
+        for head.iter().advance |&c| {
             buf.push_char(c);
         }
         buf.push_str(s);
diff --git a/src/libstd/unstable/finally.rs b/src/libstd/unstable/finally.rs
index 5001fb421cd..b15bceddb1c 100644
--- a/src/libstd/unstable/finally.rs
+++ b/src/libstd/unstable/finally.rs
@@ -31,17 +31,20 @@ pub trait Finally<T> {
     fn finally(&self, dtor: &fn()) -> T;
 }
 
-impl<'self,T> Finally<T> for &'self fn() -> T {
-    fn finally(&self, dtor: &fn()) -> T {
-        let _d = Finallyalizer {
-            dtor: dtor
-        };
-
-        (*self)()
+macro_rules! finally_fn {
+    ($fnty:ty) => {
+        impl<T> Finally<T> for $fnty {
+            fn finally(&self, dtor: &fn()) -> T {
+                let _d = Finallyalizer {
+                    dtor: dtor
+                };
+                (*self)()
+            }
+        }
     }
 }
 
-impl<T> Finally<T> for ~fn() -> T {
+impl<'self,T> Finally<T> for &'self fn() -> T {
     fn finally(&self, dtor: &fn()) -> T {
         let _d = Finallyalizer {
             dtor: dtor
@@ -51,15 +54,9 @@ impl<T> Finally<T> for ~fn() -> T {
     }
 }
 
-impl<T> Finally<T> for @fn() -> T {
-    fn finally(&self, dtor: &fn()) -> T {
-        let _d = Finallyalizer {
-            dtor: dtor
-        };
-
-        (*self)()
-    }
-}
+finally_fn!(~fn() -> T)
+finally_fn!(@fn() -> T)
+finally_fn!(extern "Rust" fn() -> T)
 
 struct Finallyalizer<'self> {
     dtor: &'self fn()
@@ -108,10 +105,7 @@ fn test_retval() {
 
 #[test]
 fn test_compact() {
-    // FIXME #4727: Should be able to use a fn item instead
-    // of a closure for do_some_fallible_work,
-    // but it's a type error.
-    let do_some_fallible_work: &fn() = || { };
+    fn do_some_fallible_work() {}
     fn but_always_run_this_function() { }
     do_some_fallible_work.finally(
         but_always_run_this_function);
@@ -136,4 +130,4 @@ fn test_managed() {
     };
     assert_eq!(do managed.finally {}, 10);
     assert_eq!(*i, 20);
-}
\ No newline at end of file
+}
diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs
index 350b18d4541..3d61c1fe144 100644
--- a/src/libstd/unstable/lang.rs
+++ b/src/libstd/unstable/lang.rs
@@ -10,6 +10,7 @@
 
 //! Runtime calls emitted by the compiler.
 
+use iterator::IteratorUtil;
 use uint;
 use cast::transmute;
 use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
@@ -133,12 +134,12 @@ unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
         Some(borrow_list) => { // recording borrows
             let mut msg = ~"borrowed";
             let mut sep = " at ";
-            for borrow_list.each_reverse |entry| {
+            for borrow_list.rev_iter().advance |entry| {
                 if entry.box == box {
-                    str::push_str(&mut msg, sep);
+                    msg.push_str(sep);
                     let filename = str::raw::from_c_str(entry.file);
-                    str::push_str(&mut msg, filename);
-                    str::push_str(&mut msg, fmt!(":%u", entry.line as uint));
+                    msg.push_str(filename);
+                    msg.push_str(fmt!(":%u", entry.line as uint));
                     sep = " and at ";
                 }
             }
@@ -244,7 +245,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
         }
         _ => {
             let mut alloc = ::ptr::null();
-            do Local::borrow::<Task> |task| {
+            do Local::borrow::<Task,()> |task| {
                 alloc = task.heap.alloc(td as *c_void, size as uint) as *c_char;
             }
             return alloc;
@@ -262,7 +263,7 @@ pub unsafe fn local_free(ptr: *c_char) {
             rustrt::rust_upcall_free_noswitch(ptr);
         }
         _ => {
-            do Local::borrow::<Task> |task| {
+            do Local::borrow::<Task,()> |task| {
                 task.heap.free(ptr as *c_void);
             }
         }
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
index afdc22a1c63..ae878050142 100644
--- a/src/libstd/unstable/mod.rs
+++ b/src/libstd/unstable/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -10,12 +10,21 @@
 
 #[doc(hidden)];
 
-use libc;
 use comm::{GenericChan, GenericPort};
+use comm;
+use libc;
 use prelude::*;
 use task;
 
 pub mod at_exit;
+
+// Currently only works for *NIXes
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+pub mod dynamic_lib;
+
 pub mod global;
 pub mod finally;
 pub mod weak_task;
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index 6085ca1a482..3cf46bec41a 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -117,9 +117,9 @@ fn LittleLock() -> LittleLock {
     }
 }
 
-pub impl LittleLock {
+impl LittleLock {
     #[inline(always)]
-    unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
+    pub unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
         do atomically {
             rust_lock_little_lock(self.l);
             do (|| {
@@ -162,7 +162,7 @@ impl<T:Owned> Clone for Exclusive<T> {
     }
 }
 
-pub impl<T:Owned> Exclusive<T> {
+impl<T:Owned> Exclusive<T> {
     // Exactly like std::arc::mutex_arc,access(), but with the little_lock
     // instead of a proper mutex. Same reason for being unsafe.
     //
@@ -170,7 +170,7 @@ pub impl<T:Owned> Exclusive<T> {
     // accessing the provided condition variable) are prohibited while inside
     // the exclusive. Supporting that is a work in progress.
     #[inline(always)]
-    unsafe fn with<U>(&self, f: &fn(x: &mut T) -> U) -> U {
+    pub unsafe fn with<U>(&self, f: &fn(x: &mut T) -> U) -> U {
         let rec = self.x.get();
         do (*rec).lock.lock {
             if (*rec).failed {
@@ -184,7 +184,7 @@ pub impl<T:Owned> Exclusive<T> {
     }
 
     #[inline(always)]
-    unsafe fn with_imm<U>(&self, f: &fn(x: &T) -> U) -> U {
+    pub unsafe fn with_imm<U>(&self, f: &fn(x: &T) -> U) -> U {
         do self.with |x| {
             f(cast::transmute_immut(x))
         }
@@ -259,48 +259,52 @@ mod tests {
 
     #[test]
     fn exclusive_arc() {
-        let mut futures = ~[];
+        unsafe {
+            let mut futures = ~[];
 
-        let num_tasks = 10;
-        let count = 10;
+            let num_tasks = 10;
+            let count = 10;
 
-        let total = exclusive(~0);
+            let total = exclusive(~0);
 
-        for uint::range(0, num_tasks) |_i| {
-            let total = total.clone();
-            let (port, chan) = comm::stream();
-            futures.push(port);
+            for uint::range(0, num_tasks) |_i| {
+                let total = total.clone();
+                let (port, chan) = comm::stream();
+                futures.push(port);
 
-            do task::spawn || {
-                for uint::range(0, count) |_i| {
-                    do total.with |count| {
-                        **count += 1;
+                do task::spawn || {
+                    for uint::range(0, count) |_i| {
+                        do total.with |count| {
+                            **count += 1;
+                        }
                     }
+                    chan.send(());
                 }
-                chan.send(());
-            }
-        };
+            };
 
-        for futures.each |f| { f.recv() }
+            for futures.each |f| { f.recv() }
 
-        do total.with |total| {
-            assert!(**total == num_tasks * count)
-        };
+            do total.with |total| {
+                assert!(**total == num_tasks * count)
+            };
+        }
     }
 
     #[test] #[should_fail] #[ignore(cfg(windows))]
     fn exclusive_poison() {
-        // Tests that if one task fails inside of an exclusive, subsequent
-        // accesses will also fail.
-        let x = exclusive(1);
-        let x2 = x.clone();
-        do task::try || {
-            do x2.with |one| {
-                assert_eq!(*one, 2);
+        unsafe {
+            // Tests that if one task fails inside of an exclusive, subsequent
+            // accesses will also fail.
+            let x = exclusive(1);
+            let x2 = x.clone();
+            do task::try || {
+                do x2.with |one| {
+                    assert_eq!(*one, 2);
+                }
+            };
+            do x.with |one| {
+                assert_eq!(*one, 1);
             }
-        };
-        do x.with |one| {
-            assert_eq!(*one, 1);
         }
     }
 
diff --git a/src/libstd/unstable/weak_task.rs b/src/libstd/unstable/weak_task.rs
index d5c5230cef8..7819fe00597 100644
--- a/src/libstd/unstable/weak_task.rs
+++ b/src/libstd/unstable/weak_task.rs
@@ -39,7 +39,7 @@ pub unsafe fn weaken_task(f: &fn(Port<ShutdownMsg>)) {
     let service = global_data_clone_create(global_data_key,
                                            create_global_service);
     let (shutdown_port, shutdown_chan) = stream::<ShutdownMsg>();
-    let shutdown_port = Cell(shutdown_port);
+    let shutdown_port = Cell::new(shutdown_port);
     let task = get_task_id();
     // Expect the weak task service to be alive
     assert!(service.try_send(RegisterWeakTask(task, shutdown_chan)));
@@ -68,7 +68,7 @@ fn create_global_service() -> ~WeakTaskService {
 
     debug!("creating global weak task service");
     let (port, chan) = stream::<ServiceMsg>();
-    let port = Cell(port);
+    let port = Cell::new(port);
     let chan = SharedChan::new(chan);
     let chan_clone = chan.clone();
 
@@ -76,7 +76,7 @@ fn create_global_service() -> ~WeakTaskService {
     task.unlinked();
     do task.spawn {
         debug!("running global weak task service");
-        let port = Cell(port.take());
+        let port = Cell::new(port.take());
         do (|| {
             let port = port.take();
             // The weak task service is itself a weak task
@@ -192,7 +192,7 @@ fn test_select_stream_and_oneshot() {
     use either::{Left, Right};
 
     let (port, chan) = stream();
-    let port = Cell(port);
+    let port = Cell::new(port);
     let (waitport, waitchan) = stream();
     do spawn {
         unsafe {
diff --git a/src/libstd/util.rs b/src/libstd/util.rs
index 9e7f18f446d..61c284f580c 100644
--- a/src/libstd/util.rs
+++ b/src/libstd/util.rs
@@ -8,12 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-
-Miscellaneous helpers for common patterns.
-
-*/
+//! Miscellaneous helpers for common patterns.
 
+use cast;
+use ptr;
 use prelude::*;
 use unstable::intrinsics;
 
@@ -67,26 +65,6 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 }
 
 /**
- * Swap the values at two mutable locations of the same type, without
- * deinitialising or copying either one.
- */
-#[inline]
-pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
-    // Give ourselves some scratch space to work with
-    let mut tmp: T = intrinsics::uninit();
-    let t: *mut T = &mut tmp;
-
-    // Perform the swap
-    ptr::copy_memory(t, x, 1);
-    ptr::copy_memory(x, y, 1);
-    ptr::copy_memory(y, t, 1);
-
-    // y and t now point to the same thing, but we need to completely forget `tmp`
-    // because it's no longer relevant.
-    cast::forget(tmp);
-}
-
-/**
  * Replace the value at a mutable location with a new one, returning the old
  * value, without deinitialising or copying either one.
  */
@@ -96,34 +74,25 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
     src
 }
 
-/**
- * Replace the value at a mutable location with a new one, returning the old
- * value, without deinitialising or copying either one.
- */
-#[inline(always)]
-pub unsafe fn replace_ptr<T>(dest: *mut T, mut src: T) -> T {
-    swap_ptr(dest, ptr::to_mut_unsafe_ptr(&mut src));
-    src
-}
-
 /// A non-copyable dummy type.
-pub struct NonCopyable {
-    i: (),
+pub struct NonCopyable;
+
+impl NonCopyable {
+    /// Creates a dummy non-copyable structure and returns it for use.
+    pub fn new() -> NonCopyable { NonCopyable }
 }
 
 impl Drop for NonCopyable {
     fn finalize(&self) { }
 }
 
-pub fn NonCopyable() -> NonCopyable { NonCopyable { i: () } }
-
 
 /// A type with no inhabitants
 pub enum Void { }
 
-pub impl Void {
+impl Void {
     /// A utility function for ignoring this uninhabited type
-    fn uninhabited(self) -> ! {
+    pub fn uninhabited(self) -> ! {
         match self {
             // Nothing to match on
         }
@@ -183,7 +152,7 @@ mod tests {
     }
     #[test]
     pub fn test_replace() {
-        let mut x = Some(NonCopyable());
+        let mut x = Some(NonCopyable::new());
         let y = replace(&mut x, None);
         assert!(x.is_none());
         assert!(y.is_some());
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 33e7b0a97c4..211ee12c291 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -19,14 +19,15 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
 use clone::Clone;
 use old_iter::BaseIter;
 use old_iter;
-use iterator::Iterator;
+use iterator::{Iterator, IteratorUtil};
+use iter::FromIter;
 use kinds::Copy;
 use libc;
 use old_iter::CopyableIter;
 use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
 use ptr;
-use ptr::Ptr;
+use ptr::RawPtr;
 use sys;
 use uint;
 use unstable::intrinsics;
@@ -55,11 +56,6 @@ pub mod rustrt {
     }
 }
 
-/// Returns true if a vector contains no elements
-pub fn is_empty<T>(v: &const [T]) -> bool {
-    as_const_buf(v, |_p, len| len == 0u)
-}
-
 /// Returns true if two vectors have the same length
 pub fn same_length<T, U>(xs: &const [T], ys: &const [U]) -> bool {
     xs.len() == ys.len()
@@ -122,13 +118,8 @@ pub fn capacity<T>(v: &const ~[T]) -> uint {
     }
 }
 
-/// Returns the length of a vector
-#[inline(always)]
-pub fn len<T>(v: &const [T]) -> uint {
-    as_const_buf(v, |_p, len| len)
-}
-
 // A botch to tide us over until core and std are fully demuted.
+#[allow(missing_doc)]
 pub fn uniq_len<T>(v: &const ~[T]) -> uint {
     unsafe {
         let v: &~[T] = transmute(v);
@@ -148,8 +139,7 @@ pub fn from_fn<T>(n_elts: uint, op: old_iter::InitOp<T>) -> ~[T] {
         do as_mut_buf(v) |p, _len| {
             let mut i: uint = 0u;
             while i < n_elts {
-                intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)),
-                                          op(i));
+                intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
                 i += 1u;
             }
         }
@@ -165,7 +155,20 @@ pub fn from_fn<T>(n_elts: uint, op: old_iter::InitOp<T>) -> ~[T] {
  * to the value `t`.
  */
 pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
-    from_fn(n_elts, |_i| copy t)
+    // hack: manually inline from_fn for 2x plus speedup (sadly very important, from_elem is a
+    // bottleneck in borrowck!)
+    unsafe {
+        let mut v = with_capacity(n_elts);
+        do as_mut_buf(v) |p, _len| {
+            let mut i = 0u;
+            while i < n_elts {
+                intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t);
+                i += 1u;
+            }
+        }
+        raw::set_len(&mut v, n_elts);
+        v
+    }
 }
 
 /// Creates a new unique vector with the same contents as the slice
@@ -277,7 +280,7 @@ pub fn last_opt<'r,T>(v: &'r [T]) -> Option<&'r T> {
 #[inline(always)]
 pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] {
     assert!(start <= end);
-    assert!(end <= len(v));
+    assert!(end <= v.len());
     do as_imm_buf(v) |p, _len| {
         unsafe {
             transmute((ptr::offset(p, start),
@@ -305,7 +308,7 @@ pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint)
 pub fn const_slice<'r,T>(v: &'r const [T], start: uint, end: uint)
                       -> &'r const [T] {
     assert!(start <= end);
-    assert!(end <= len(v));
+    assert!(end <= v.len());
     do as_const_buf(v) |p, _len| {
         unsafe {
             transmute((ptr::const_offset(p, start),
@@ -318,7 +321,7 @@ pub fn const_slice<'r,T>(v: &'r const [T], start: uint, end: uint)
 
 /// Split the vector `v` by applying each element against the predicate `f`.
 pub fn split<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = len(v);
+    let ln = v.len();
     if (ln == 0u) { return ~[] }
 
     let mut start = 0u;
@@ -341,7 +344,7 @@ pub fn split<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
  * to `n` times.
  */
 pub fn splitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = len(v);
+    let ln = v.len();
     if (ln == 0u) { return ~[] }
 
     let mut start = 0u;
@@ -367,7 +370,7 @@ pub fn splitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
  * `f`.
  */
 pub fn rsplit<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = len(v);
+    let ln = v.len();
     if (ln == 0) { return ~[] }
 
     let mut end = ln;
@@ -391,7 +394,7 @@ pub fn rsplit<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
  * `f` up to `n times.
  */
 pub fn rsplitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = len(v);
+    let ln = v.len();
     if (ln == 0u) { return ~[] }
 
     let mut end = ln;
@@ -505,7 +508,7 @@ pub fn shift<T>(v: &mut ~[T]) -> T {
         let vp = raw::to_mut_ptr(*v);
         let vp = ptr::mut_offset(vp, next_ln - 1);
 
-        util::replace_ptr(vp, work_elt)
+        ptr::replace_ptr(vp, work_elt)
     }
 }
 
@@ -543,6 +546,22 @@ pub fn remove<T>(v: &mut ~[T], i: uint) -> T {
     v.pop()
 }
 
+/// Consumes all elements, in a vector, moving them out into the / closure
+/// provided. The vector is traversed from the start to the end.
+///
+/// This method does not impose any requirements on the type of the vector being
+/// consumed, but it prevents any usage of the vector after this function is
+/// called.
+///
+/// # Examples
+///
+/// ~~~ {.rust}
+/// let v = ~[~"a", ~"b"];
+/// do vec::consume(v) |i, s| {
+///   // s has type ~str, not &~str
+///   io::println(s + fmt!(" %d", i));
+/// }
+/// ~~~
 pub fn consume<T>(mut v: ~[T], f: &fn(uint, v: T)) {
     unsafe {
         do as_mut_buf(v) |p, ln| {
@@ -553,7 +572,7 @@ pub fn consume<T>(mut v: ~[T], f: &fn(uint, v: T)) {
                 // elements during unwinding
                 let x = intrinsics::init();
                 let p = ptr::mut_offset(p, i);
-                f(i, util::replace_ptr(p, x));
+                f(i, ptr::replace_ptr(p, x));
             }
         }
 
@@ -561,6 +580,12 @@ pub fn consume<T>(mut v: ~[T], f: &fn(uint, v: T)) {
     }
 }
 
+/// Consumes all elements, in a vector, moving them out into the / closure
+/// provided. The vectors is traversed in reverse order (from end to start).
+///
+/// This method does not impose any requirements on the type of the vector being
+/// consumed, but it prevents any usage of the vector after this function is
+/// called.
 pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
     unsafe {
         do as_mut_buf(v) |p, ln| {
@@ -574,7 +599,7 @@ pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
                 // elements during unwinding
                 let x = intrinsics::init();
                 let p = ptr::mut_offset(p, i);
-                f(i, util::replace_ptr(p, x));
+                f(i, ptr::replace_ptr(p, x));
             }
         }
 
@@ -590,7 +615,7 @@ pub fn pop<T>(v: &mut ~[T]) -> T {
     }
     let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]);
     unsafe {
-        let val = util::replace_ptr(valptr, intrinsics::init());
+        let val = ptr::replace_ptr(valptr, intrinsics::init());
         raw::set_len(v, ln - 1u);
         val
     }
@@ -646,6 +671,16 @@ fn push_slow<T>(v: &mut ~[T], initval: T) {
     unsafe { push_fast(v, initval) }
 }
 
+/// Iterates over the slice `rhs`, copies each element, and then appends it to
+/// the vector provided `v`. The `rhs` vector is traversed in-order.
+///
+/// # Example
+///
+/// ~~~ {.rust}
+/// let mut a = ~[1];
+/// vec::push_all(&mut a, [2, 3, 4]);
+/// assert!(a == ~[1, 2, 3, 4]);
+/// ~~~
 #[inline(always)]
 pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
     let new_len = v.len() + rhs.len();
@@ -656,6 +691,17 @@ pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
     }
 }
 
+/// Takes ownership of the vector `rhs`, moving all elements into the specified
+/// vector `v`. This does not copy any elements, and it is illegal to use the
+/// `rhs` vector after calling this method (because it is moved here).
+///
+/// # Example
+///
+/// ~~~ {.rust}
+/// let mut a = ~[~1];
+/// vec::push_all_move(&mut a, ~[~2, ~3, ~4]);
+/// assert!(a == ~[~1, ~2, ~3, ~4]);
+/// ~~~
 #[inline(always)]
 pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
     let new_len = v.len() + rhs.len();
@@ -663,8 +709,8 @@ pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
     unsafe {
         do as_mut_buf(rhs) |p, len| {
             for uint::range(0, len) |i| {
-                let x = util::replace_ptr(ptr::mut_offset(p, i),
-                                          intrinsics::uninit());
+                let x = ptr::replace_ptr(ptr::mut_offset(p, i),
+                                         intrinsics::uninit());
                 push(&mut *v, x);
             }
         }
@@ -679,7 +725,7 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
         unsafe {
             // This loop is optimized out for non-drop types.
             for uint::range(newlen, oldlen) |i| {
-                util::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit());
+                ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit());
             }
         }
     }
@@ -693,7 +739,7 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
 pub fn dedup<T:Eq>(v: &mut ~[T]) {
     unsafe {
         if v.len() < 1 { return; }
-        let mut last_written = 0, next_to_read = 1;
+        let mut (last_written, next_to_read) = (0, 1);
         do as_const_buf(*v) |p, ln| {
             // We have a mutable reference to v, so we can make arbitrary
             // changes. (cf. push and pop)
@@ -703,14 +749,14 @@ pub fn dedup<T:Eq>(v: &mut ~[T]) {
                 // last_written < next_to_read < ln
                 if *ptr::mut_offset(p, next_to_read) ==
                     *ptr::mut_offset(p, last_written) {
-                    util::replace_ptr(ptr::mut_offset(p, next_to_read),
-                                      intrinsics::uninit());
+                    ptr::replace_ptr(ptr::mut_offset(p, next_to_read),
+                                     intrinsics::uninit());
                 } else {
                     last_written += 1;
                     // last_written <= next_to_read < ln
                     if next_to_read != last_written {
-                        util::swap_ptr(ptr::mut_offset(p, last_written),
-                                       ptr::mut_offset(p, next_to_read));
+                        ptr::swap_ptr(ptr::mut_offset(p, last_written),
+                                      ptr::mut_offset(p, next_to_read));
                     }
                 }
                 // last_written <= next_to_read < ln
@@ -724,6 +770,9 @@ pub fn dedup<T:Eq>(v: &mut ~[T]) {
 }
 
 // Appending
+
+/// Iterates over the `rhs` vector, copying each element and appending it to the
+/// `lhs`. Afterwards, the `lhs` is then returned for use again.
 #[inline(always)]
 pub fn append<T:Copy>(lhs: ~[T], rhs: &const [T]) -> ~[T] {
     let mut v = lhs;
@@ -731,6 +780,8 @@ pub fn append<T:Copy>(lhs: ~[T], rhs: &const [T]) -> ~[T] {
     v
 }
 
+/// Appends one element to the vector provided. The vector itself is then
+/// returned for use again.
 #[inline(always)]
 pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
     let mut v = lhs;
@@ -799,13 +850,20 @@ pub fn grow_set<T:Copy>(v: &mut ~[T], index: uint, initval: &T, val: T) {
 
 /// Apply a function to each element of a vector and return the results
 pub fn map<T, U>(v: &[T], f: &fn(t: &T) -> U) -> ~[U] {
-    let mut result = with_capacity(len(v));
+    let mut result = with_capacity(v.len());
     for each(v) |elem| {
         result.push(f(elem));
     }
     result
 }
 
+/// Consumes a vector, mapping it into a different vector. This function takes
+/// ownership of the supplied vector `v`, moving each element into the closure
+/// provided to generate a new element. The vector of new elements is then
+/// returned.
+///
+/// The original vector `v` cannot be used after this function call (it is moved
+/// inside), but there are no restrictions on the type of the vector.
 pub fn map_consume<T, U>(v: ~[T], f: &fn(v: T) -> U) -> ~[U] {
     let mut result = ~[];
     do consume(v) |_i, x| {
@@ -839,8 +897,8 @@ pub fn flat_map<T, U>(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] {
  */
 pub fn map_zip<T:Copy,U:Copy,V>(v0: &[T], v1: &[U],
                                   f: &fn(t: &T, v: &U) -> V) -> ~[V] {
-    let v0_len = len(v0);
-    if v0_len != len(v1) { fail!(); }
+    let v0_len = v0.len();
+    if v0_len != v1.len() { fail!(); }
     let mut u: ~[V] = ~[];
     let mut i = 0u;
     while i < v0_len {
@@ -943,145 +1001,60 @@ pub fn retain<T>(v: &mut ~[T], f: &fn(t: &T) -> bool) {
     }
 }
 
-/**
- * Concatenate a vector of vectors.
- *
- * Flattens a vector of vectors of T into a single vector of T.
- */
-pub fn concat<T:Copy>(v: &[~[T]]) -> ~[T] {
-    let mut r = ~[];
-    for each(v) |inner| { r.push_all(*inner); }
-    r
-}
+/// Flattens a vector of vectors of T into a single vector of T.
+pub fn concat<T:Copy>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
 
 /// Concatenate a vector of vectors, placing a given separator between each
-pub fn connect<T:Copy>(v: &[~[T]], sep: &T) -> ~[T] {
-    let mut r: ~[T] = ~[];
-    let mut first = true;
-    for each(v) |inner| {
-        if first { first = false; } else { r.push(*sep); }
-        r.push_all(*inner);
-    }
-    r
-}
+pub fn connect<T:Copy>(v: &[~[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
 
-/**
- * Reduces a vector from left to right.
- *
- * # Arguments
- * * `z` - initial accumulator value
- * * `v` - vector to iterate over
- * * `p` - a closure to operate on vector elements
- *
- * # Examples
- *
- * Sum all values in the vector [1, 2, 3]:
- *
- * ~~~ {.rust}
- * vec::foldl(0, [1, 2, 3], |a, b| a + *b);
- * ~~~
- *
- */
-pub fn foldl<'a, T, U>(z: T, v: &'a [U], p: &fn(t: T, u: &'a U) -> T) -> T {
-    let mut accum = z;
-    let mut i = 0;
-    let l = v.len();
-    while i < l {
-        // Use a while loop so that liveness analysis can handle moving
-        // the accumulator.
-        accum = p(accum, &v[i]);
-        i += 1;
-    }
-    accum
-}
+/// Flattens a vector of vectors of T into a single vector of T.
+pub fn concat_slices<T:Copy>(v: &[&[T]]) -> ~[T] { v.concat_vec() }
 
-/**
- * Reduces a vector from right to left. Note that the argument order is
- * reversed compared to `foldl` to reflect the order they are provided to
- * the closure.
- *
- * # Arguments
- * * `v` - vector to iterate over
- * * `z` - initial accumulator value
- * * `p` - a closure to do operate on vector elements
- *
- * # Examples
- *
- * Sum all values in the vector [1, 2, 3]:
- *
- * ~~~ {.rust}
- * vec::foldr([1, 2, 3], 0, |a, b| a + *b);
- * ~~~
- *
- */
-pub fn foldr<'a, T, U>(v: &'a [T], mut z: U, p: &fn(t: &'a T, u: U) -> U) -> U {
-    let mut i = v.len();
-    while i > 0 {
-        i -= 1;
-        z = p(&v[i], z);
-    }
-    return z;
-}
+/// Concatenate a vector of vectors, placing a given separator between each
+pub fn connect_slices<T:Copy>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
 
-/**
- * Return true if a predicate matches any elements
- *
- * If the vector contains no elements then false is returned.
- */
-pub fn any<T>(v: &[T], f: &fn(t: &T) -> bool) -> bool {
-    for each(v) |elem| { if f(elem) { return true; } }
-    false
+#[allow(missing_doc)]
+pub trait VectorVector<T> {
+    // FIXME #5898: calling these .concat and .connect conflicts with
+    // StrVector::con{cat,nect}, since they have generic contents.
+    pub fn concat_vec(&self) -> ~[T];
+    pub fn connect_vec(&self, sep: &T) -> ~[T];
 }
 
-/**
- * Return true if a predicate matches any elements in both vectors.
- *
- * If the vectors contains no elements then false is returned.
- */
-pub fn any2<T, U>(v0: &[T], v1: &[U],
-                   f: &fn(a: &T, b: &U) -> bool) -> bool {
-    let v0_len = len(v0);
-    let v1_len = len(v1);
-    let mut i = 0u;
-    while i < v0_len && i < v1_len {
-        if f(&v0[i], &v1[i]) { return true; };
-        i += 1u;
+impl<'self, T:Copy> VectorVector<T> for &'self [~[T]] {
+    /// Flattens a vector of slices of T into a single vector of T.
+    pub fn concat_vec(&self) -> ~[T] {
+        self.flat_map(|&inner| inner)
     }
-    false
-}
 
-/**
- * Return true if a predicate matches all elements
- *
- * If the vector contains no elements then true is returned.
- */
-pub fn all<T>(v: &[T], f: &fn(t: &T) -> bool) -> bool {
-    for each(v) |elem| { if !f(elem) { return false; } }
-    true
+    /// Concatenate a vector of vectors, placing a given separator between each.
+    pub fn connect_vec(&self, sep: &T) -> ~[T] {
+        let mut r = ~[];
+        let mut first = true;
+        for self.each |&inner| {
+            if first { first = false; } else { r.push(*sep); }
+            r.push_all(inner);
+        }
+        r
+    }
 }
 
-/**
- * Return true if a predicate matches all elements
- *
- * If the vector contains no elements then true is returned.
- */
-pub fn alli<T>(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool {
-    for eachi(v) |i, elem| { if !f(i, elem) { return false; } }
-    true
-}
+impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
+    /// Flattens a vector of slices of T into a single vector of T.
+    pub fn concat_vec(&self) -> ~[T] {
+        self.flat_map(|&inner| inner.to_owned())
+    }
 
-/**
- * Return true if a predicate matches all elements in both vectors.
- *
- * If the vectors are not the same size then false is returned.
- */
-pub fn all2<T, U>(v0: &[T], v1: &[U],
-                   f: &fn(t: &T, u: &U) -> bool) -> bool {
-    let v0_len = len(v0);
-    if v0_len != len(v1) { return false; }
-    let mut i = 0u;
-    while i < v0_len { if !f(&v0[i], &v1[i]) { return false; }; i += 1u; }
-    true
+    /// Concatenate a vector of slices, placing a given separator between each.
+    pub fn connect_vec(&self, sep: &T) -> ~[T] {
+        let mut r = ~[];
+        let mut first = true;
+        for self.each |&inner| {
+            if first { first = false; } else { r.push(*sep); }
+            r.push_all(inner);
+        }
+        r
+    }
 }
 
 /// Return true if a vector contains an element with the given value
@@ -1090,13 +1063,6 @@ pub fn contains<T:Eq>(v: &[T], x: &T) -> bool {
     false
 }
 
-/// Returns the number of elements that are equal to a given value
-pub fn count<T:Eq>(v: &[T], x: &T) -> uint {
-    let mut cnt = 0u;
-    for each(v) |elt| { if *x == *elt { cnt += 1u; } }
-    cnt
-}
-
 /**
  * Search for the first element that matches a given predicate
  *
@@ -1105,7 +1071,7 @@ pub fn count<T:Eq>(v: &[T], x: &T) -> uint {
  * is returned. If `f` matches no elements then none is returned.
  */
 pub fn find<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> Option<T> {
-    find_between(v, 0u, len(v), f)
+    find_between(v, 0u, v.len(), f)
 }
 
 /**
@@ -1128,7 +1094,7 @@ pub fn find_between<T:Copy>(v: &[T], start: uint, end: uint,
  * matches no elements then none is returned.
  */
 pub fn rfind<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> Option<T> {
-    rfind_between(v, 0u, len(v), f)
+    rfind_between(v, 0u, v.len(), f)
 }
 
 /**
@@ -1159,7 +1125,7 @@ pub fn position_elem<T:Eq>(v: &[T], x: &T) -> Option<uint> {
  * then none is returned.
  */
 pub fn position<T>(v: &[T], f: &fn(t: &T) -> bool) -> Option<uint> {
-    position_between(v, 0u, len(v), f)
+    position_between(v, 0u, v.len(), f)
 }
 
 /**
@@ -1175,7 +1141,7 @@ pub fn position_between<T>(v: &[T],
                            f: &fn(t: &T) -> bool)
                         -> Option<uint> {
     assert!(start <= end);
-    assert!(end <= len(v));
+    assert!(end <= v.len());
     let mut i = start;
     while i < end { if f(&v[i]) { return Some::<uint>(i); } i += 1u; }
     None
@@ -1194,7 +1160,7 @@ pub fn rposition_elem<T:Eq>(v: &[T], x: &T) -> Option<uint> {
  * matches no elements then none is returned.
  */
 pub fn rposition<T>(v: &[T], f: &fn(t: &T) -> bool) -> Option<uint> {
-    rposition_between(v, 0u, len(v), f)
+    rposition_between(v, 0u, v.len(), f)
 }
 
 /**
@@ -1208,7 +1174,7 @@ pub fn rposition<T>(v: &[T], f: &fn(t: &T) -> bool) -> Option<uint> {
 pub fn rposition_between<T>(v: &[T], start: uint, end: uint,
                              f: &fn(t: &T) -> bool) -> Option<uint> {
     assert!(start <= end);
-    assert!(end <= len(v));
+    assert!(end <= v.len());
     let mut i = end;
     while i > start {
         if f(&v[i - 1u]) { return Some::<uint>(i - 1u); }
@@ -1265,7 +1231,7 @@ pub fn bsearch_elem<T:TotalOrd>(v: &[T], x: &T) -> Option<uint> {
  * Convert a vector of pairs into a pair of vectors, by reference. As unzip().
  */
 pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
-    let mut ts = ~[], us = ~[];
+    let mut (ts, us) = (~[], ~[]);
     for each(v) |p| {
         let (t, u) = *p;
         ts.push(t);
@@ -1283,7 +1249,7 @@ pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
  * of the i-th tuple of the input vector.
  */
 pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
-    let mut ts = ~[], us = ~[];
+    let mut (ts, us) = (~[], ~[]);
     do consume(v) |_i, p| {
         let (t, u) = p;
         ts.push(t);
@@ -1298,9 +1264,9 @@ pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
 pub fn zip_slice<T:Copy,U:Copy>(v: &const [T], u: &const [U])
         -> ~[(T, U)] {
     let mut zipped = ~[];
-    let sz = len(v);
+    let sz = v.len();
     let mut i = 0u;
-    assert_eq!(sz, len(u));
+    assert_eq!(sz, u.len());
     while i < sz {
         zipped.push((v[i], u[i]));
         i += 1u;
@@ -1311,12 +1277,12 @@ pub fn zip_slice<T:Copy,U:Copy>(v: &const [T], u: &const [U])
 /**
  * Convert two vectors to a vector of pairs.
  *
- * Returns a vector of tuples, where the i-th tuple contains contains the
+ * Returns a vector of tuples, where the i-th tuple contains the
  * i-th elements from each of the input vectors.
  */
 pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
-    let mut i = len(v);
-    assert_eq!(i, len(u));
+    let mut i = v.len();
+    assert_eq!(i, u.len());
     let mut w = with_capacity(i);
     while i > 0 {
         w.push((v.pop(),u.pop()));
@@ -1340,16 +1306,16 @@ pub fn swap<T>(v: &mut [T], a: uint, b: uint) {
     unsafe {
         // Can't take two mutable loans from one vector, so instead just cast
         // them to their raw pointers to do the swap
-        let pa: *mut T = ptr::to_mut_unsafe_ptr(&mut v[a]);
-        let pb: *mut T = ptr::to_mut_unsafe_ptr(&mut v[b]);
-        util::swap_ptr(pa, pb);
+        let pa: *mut T = &mut v[a];
+        let pb: *mut T = &mut v[b];
+        ptr::swap_ptr(pa, pb);
     }
 }
 
 /// Reverse the order of elements in a vector, in place
 pub fn reverse<T>(v: &mut [T]) {
     let mut i: uint = 0;
-    let ln = len::<T>(v);
+    let ln = v.len();
     while i < ln / 2 {
         swap(v, i, ln - i - 1);
         i += 1;
@@ -1397,7 +1363,7 @@ pub fn reverse_part<T>(v: &mut [T], start: uint, end : uint) {
 /// Returns a vector with the order of elements reversed
 pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
     let mut rs: ~[T] = ~[];
-    let mut i = len::<T>(v);
+    let mut i = v.len();
     if i == 0 { return (rs); } else { i -= 1; }
     while i != 0 { rs.push(v[i]); i -= 1; }
     rs.push(v[0]);
@@ -1444,8 +1410,8 @@ pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
  * ~~~
  */
 #[inline(always)]
-pub fn _each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool {
-    //             ^^^^
+pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool {
+    //            ^^^^
     // NB---this CANNOT be &const [T]!  The reason
     // is that you are passing it to `f()` using
     // an immutable.
@@ -1464,41 +1430,13 @@ pub fn _each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool {
         }
         broke = n > 0;
     }
-    return true;
-}
-
-pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { _each(v, f) }
-
-/// Like `each()`, but for the case where you have
-/// a vector with mutable contents and you would like
-/// to mutate the contents as you iterate.
-#[inline(always)]
-pub fn _each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool {
-    let mut broke = false;
-    do as_mut_buf(v) |p, n| {
-        let mut n = n;
-        let mut p = p;
-        while n > 0 {
-            unsafe {
-                let q: &'r mut T = cast::transmute_mut_region(&mut *p);
-                if !f(q) { break; }
-                p = p.offset(1);
-            }
-            n -= 1;
-        }
-        broke = n > 0;
-    }
-    return broke;
-}
-
-pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool {
-    _each_mut(v, f)
+    return !broke;
 }
 
 /// Like `each()`, but for the case where you have a vector that *may or may
 /// not* have mutable contents.
 #[inline(always)]
-pub fn _each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool {
+pub fn each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool {
     let mut i = 0;
     let n = v.len();
     while i < n {
@@ -1510,17 +1448,13 @@ pub fn _each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool {
     return true;
 }
 
-pub fn each_const<t>(v: &const [t], f: &fn(elem: &const t) -> bool) -> bool {
-    _each_const(v, f)
-}
-
 /**
  * Iterates over a vector's elements and indices
  *
  * Return true to continue, false to break.
  */
 #[inline(always)]
-pub fn _eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
+pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
     let mut i = 0;
     for each(v) |p| {
         if !f(i, p) { return false; }
@@ -1529,115 +1463,6 @@ pub fn _eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
     return true;
 }
 
-pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
-    _eachi(v, f)
-}
-
-/**
- * Iterates over a mutable vector's elements and indices
- *
- * Return true to continue, false to break.
- */
-#[inline(always)]
-pub fn _eachi_mut<'r,T>(v: &'r mut [T],
-                        f: &fn(uint, v: &'r mut T) -> bool) -> bool {
-    let mut i = 0;
-    for each_mut(v) |p| {
-        if !f(i, p) {
-            return false;
-        }
-        i += 1;
-    }
-    return true;
-}
-
-pub fn eachi_mut<'r,T>(v: &'r mut [T],
-                       f: &fn(uint, v: &'r mut T) -> bool) -> bool {
-    _eachi_mut(v, f)
-}
-
-/**
- * Iterates over a vector's elements in reverse
- *
- * Return true to continue, false to break.
- */
-#[inline(always)]
-pub fn _each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool {
-    _eachi_reverse(v, |_i, v| blk(v))
-}
-
-pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool {
-    _each_reverse(v, blk)
-}
-
-/**
- * Iterates over a vector's elements and indices in reverse
- *
- * Return true to continue, false to break.
- */
-#[inline(always)]
-pub fn _eachi_reverse<'r,T>(v: &'r [T],
-                            blk: &fn(i: uint, v: &'r T) -> bool) -> bool {
-    let mut i = v.len();
-    while i > 0 {
-        i -= 1;
-        if !blk(i, &v[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-pub fn eachi_reverse<'r,T>(v: &'r [T],
-                           blk: &fn(i: uint, v: &'r T) -> bool) -> bool {
-    _eachi_reverse(v, blk)
-}
-
-/**
- * Iterates over two vectors simultaneously
- *
- * # Failure
- *
- * Both vectors must have the same length
- */
-#[inline]
-pub fn _each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool {
-    assert_eq!(v1.len(), v2.len());
-    for uint::range(0u, v1.len()) |i| {
-        if !f(&v1[i], &v2[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-pub fn each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool {
-    _each2(v1, v2, f)
-}
-
-/**
- *
- * Iterates over two vector with mutable.
- *
- * # Failure
- *
- * Both vectors must have the same length
- */
-#[inline]
-pub fn _each2_mut<U, T>(v1: &mut [U], v2: &mut [T], f: &fn(u: &mut U, t: &mut T) -> bool) -> bool {
-    assert_eq!(v1.len(), v2.len());
-    for uint::range(0u, v1.len()) |i| {
-        if !f(&mut v1[i], &mut v2[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-pub fn each2_mut<U, T>(v1: &mut [U], v2: &mut [T], f: &fn(u: &mut U, t: &mut T) -> bool) -> bool {
-    _each2_mut(v1, v2, f)
-}
-
 /**
  * Iterate over all permutations of vector `v`.
  *
@@ -1645,7 +1470,7 @@ pub fn each2_mut<U, T>(v1: &mut [U], v2: &mut [T], f: &fn(u: &mut U, t: &mut T)
  * of elements in `v` (so if `v` is sorted then the permutations are
  * lexicographically sorted).
  *
- * The total number of permutations produced is `len(v)!`.  If `v` contains
+ * The total number of permutations produced is `v.len()!`.  If `v` contains
  * repeated elements, then some permutations are repeated.
  *
  * See [Algorithms to generate
@@ -1761,6 +1586,9 @@ pub fn as_mut_buf<T,U>(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U {
 
 // Equality
 
+/// Tests whether two slices are equal to one another. This is only true if both
+/// slices are of the same length, and each of the corresponding elements return
+/// true when queried via the `eq` function.
 fn eq<T: Eq>(a: &[T], b: &[T]) -> bool {
     let (a_len, b_len) = (a.len(), b.len());
     if a_len != b_len { return false; }
@@ -1773,6 +1601,9 @@ fn eq<T: Eq>(a: &[T], b: &[T]) -> bool {
     true
 }
 
+/// Similar to the `vec::eq` function, but this is defined for types which
+/// implement `TotalEq` as opposed to types which implement `Eq`. Equality
+/// comparisons are done via the `equals` function instead of `eq`.
 fn equals<T: TotalEq>(a: &[T], b: &[T]) -> bool {
     let (a_len, b_len) = (a.len(), b.len());
     if a_len != b_len { return false; }
@@ -1939,13 +1770,19 @@ pub mod traits {
 impl<'self,T> Container for &'self const [T] {
     /// Returns true if a vector contains no elements
     #[inline]
-    fn is_empty(&const self) -> bool { is_empty(*self) }
+    fn is_empty(&const self) -> bool {
+        as_const_buf(*self, |_p, len| len == 0u)
+    }
 
     /// Returns the length of a vector
     #[inline]
-    fn len(&const self) -> uint { len(*self) }
+    fn len(&const self) -> uint {
+        as_const_buf(*self, |_p, len| len)
+    }
+
 }
 
+#[allow(missing_doc)]
 pub trait CopyableVector<T> {
     fn to_owned(&self) -> ~[T];
 }
@@ -1965,9 +1802,11 @@ impl<'self,T:Copy> CopyableVector<T> for &'self [T] {
     }
 }
 
+#[allow(missing_doc)]
 pub trait ImmutableVector<'self, T> {
     fn slice(&self, start: uint, end: uint) -> &'self [T];
     fn iter(self) -> VecIterator<'self, T>;
+    fn rev_iter(self) -> VecRevIterator<'self, T>;
     fn head(&self) -> &'self T;
     fn head_opt(&self) -> Option<&'self T>;
     fn tail(&self) -> &'self [T];
@@ -1978,13 +1817,9 @@ pub trait ImmutableVector<'self, T> {
     fn last_opt(&self) -> Option<&'self T>;
     fn position(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
     fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
-    fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool;
-    fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool;
-    fn foldr<'a, U>(&'a self, z: U, p: &fn(t: &'a T, u: U) -> U) -> U;
     fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U];
     fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U];
     fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U];
-    fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool;
     fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
     fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U];
     unsafe fn unsafe_ref(&self, index: uint) -> *T;
@@ -2006,6 +1841,15 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
                         lifetime: cast::transmute(p)}
         }
     }
+    #[inline]
+    fn rev_iter(self) -> VecRevIterator<'self, T> {
+        unsafe {
+            let p = vec::raw::to_ptr(self);
+            VecRevIterator{ptr: p.offset(self.len() - 1),
+                           end: p.offset(-1),
+                           lifetime: cast::transmute(p)}
+        }
+    }
 
     /// Returns the first element of a vector, failing if the vector is empty.
     #[inline]
@@ -2063,24 +1907,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         rposition(*self, f)
     }
 
-    /// Iterates over a vector's elements in reverse.
-    #[inline]
-    fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool {
-        each_reverse(*self, blk)
-    }
-
-    /// Iterates over a vector's elements and indices in reverse.
-    #[inline]
-    fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool {
-        eachi_reverse(*self, blk)
-    }
-
-    /// Reduce a vector from right to left
-    #[inline]
-    fn foldr<'a, U>(&'a self, z: U, p: &fn(t: &'a T, u: U) -> U) -> U {
-        foldr(*self, z, p)
-    }
-
     /// Apply a function to each element of a vector and return the results
     #[inline]
     fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) }
@@ -2105,14 +1931,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     }
 
     /**
-     * Returns true if the function returns true for all elements.
-     *
-     *     If the vector is empty, true is returned.
-     */
-    fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool {
-        alli(*self, f)
-    }
-    /**
      * Apply a function to each element of a vector and return a concatenation
      * of each result vector
      */
@@ -2140,6 +1958,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     }
 }
 
+#[allow(missing_doc)]
 pub trait ImmutableEqVector<T:Eq> {
     fn position_elem(&self, t: &T) -> Option<uint>;
     fn rposition_elem(&self, t: &T) -> Option<uint>;
@@ -2159,6 +1978,7 @@ impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
     }
 }
 
+#[allow(missing_doc)]
 pub trait ImmutableCopyableVector<T> {
     fn filtered(&self, f: &fn(&T) -> bool) -> ~[T];
     fn rfind(&self, f: &fn(t: &T) -> bool) -> Option<T>;
@@ -2208,6 +2028,7 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
     }
 }
 
+#[allow(missing_doc)]
 pub trait OwnedVector<T> {
     fn push(&mut self, t: T);
     fn push_all_move(&mut self, rhs: ~[T]);
@@ -2312,6 +2133,7 @@ impl<T> Mutable for ~[T] {
     fn clear(&mut self) { self.truncate(0) }
 }
 
+#[allow(missing_doc)]
 pub trait OwnedCopyableVector<T:Copy> {
     fn push_all(&mut self, rhs: &const [T]);
     fn grow(&mut self, n: uint, initval: &T);
@@ -2335,6 +2157,7 @@ impl<T:Copy> OwnedCopyableVector<T> for ~[T] {
     }
 }
 
+#[allow(missing_doc)]
 trait OwnedEqVector<T:Eq> {
     fn dedup(&mut self);
 }
@@ -2346,8 +2169,11 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
     }
 }
 
+#[allow(missing_doc)]
 pub trait MutableVector<'self, T> {
     fn mut_slice(self, start: uint, end: uint) -> &'self mut [T];
+    fn mut_iter(self) -> VecMutIterator<'self, T>;
+    fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>;
 
     unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
     unsafe fn unsafe_set(&self, index: uint, val: T);
@@ -2359,6 +2185,24 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
         mut_slice(self, start, end)
     }
 
+    #[inline]
+    fn mut_iter(self) -> VecMutIterator<'self, T> {
+        unsafe {
+            let p = vec::raw::to_mut_ptr(self);
+            VecMutIterator{ptr: p, end: p.offset(self.len()),
+                           lifetime: cast::transmute(p)}
+        }
+    }
+
+    fn mut_rev_iter(self) -> VecMutRevIterator<'self, T> {
+        unsafe {
+            let p = vec::raw::to_mut_ptr(self);
+            VecMutRevIterator{ptr: p.offset(self.len() - 1),
+                              end: p.offset(-1),
+                              lifetime: cast::transmute(p)}
+        }
+    }
+
     #[inline(always)]
     unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
         let pair_ptr: &(*mut T, uint) = transmute(self);
@@ -2386,6 +2230,7 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
 }
 
 /// The internal 'unboxed' representation of a vector
+#[allow(missing_doc)]
 pub struct UnboxedVecRepr {
     fill: uint,
     alloc: uint,
@@ -2401,17 +2246,21 @@ pub mod raw {
     use ptr;
     use sys;
     use unstable::intrinsics;
-    use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, len, with_capacity};
+    use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, with_capacity};
     use util;
 
     /// The internal representation of a (boxed) vector
+    #[allow(missing_doc)]
     pub struct VecRepr {
         box_header: managed::raw::BoxHeaderRepr,
         unboxed: UnboxedVecRepr
     }
 
+    /// The internal representation of a slice
     pub struct SliceRepr {
+        /// Pointer to the base of this slice
         data: *u8,
+        /// The length of the slice
         len: uint
     }
 
@@ -2640,29 +2489,6 @@ impl<A> old_iter::BaseIter<A> for @[A] {
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
-impl<'self,A> old_iter::MutableIter<A> for &'self mut [A] {
-    #[inline(always)]
-    fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool {
-        each_mut(*self, blk)
-    }
-}
-
-// FIXME(#4148): This should be redundant
-impl<A> old_iter::MutableIter<A> for ~[A] {
-    #[inline(always)]
-    fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool {
-        each_mut(*self, blk)
-    }
-}
-
-// FIXME(#4148): This should be redundant
-impl<A> old_iter::MutableIter<A> for @mut [A] {
-    #[inline(always)]
-    fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) -> bool {
-        each_mut(*self, blk)
-    }
-}
-
 impl<'self,A> old_iter::ExtendedIter<A> for &'self [A] {
     pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool {
         old_iter::eachi(self, blk)
@@ -2688,13 +2514,6 @@ impl<'self,A> old_iter::ExtendedIter<A> for &'self [A] {
     }
 }
 
-impl<'self,A> old_iter::ExtendedMutableIter<A> for &'self mut [A] {
-    #[inline(always)]
-    pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) -> bool {
-        eachi_mut(*self, blk)
-    }
-}
-
 // FIXME(#4148): This should be redundant
 impl<A> old_iter::ExtendedIter<A> for ~[A] {
     pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool {
@@ -2813,67 +2632,83 @@ impl<A:Copy + Ord> old_iter::CopyableOrderedIter<A> for @[A] {
     fn max(&self) -> A { old_iter::max(self) }
 }
 
-impl<'self,A:Copy> old_iter::CopyableNonstrictIter<A> for &'self [A] {
-    fn each_val(&const self, f: &fn(A) -> bool) -> bool {
-        let mut i = 0;
-        while i < self.len() {
-            if !f(copy self[i]) { return false; }
-            i += 1;
-        }
-        return true;
+impl<A:Clone> Clone for ~[A] {
+    #[inline]
+    fn clone(&self) -> ~[A] {
+        self.map(|item| item.clone())
     }
 }
 
-// FIXME(#4148): This should be redundant
-impl<A:Copy> old_iter::CopyableNonstrictIter<A> for ~[A] {
-    fn each_val(&const self, f: &fn(A) -> bool) -> bool {
-        let mut i = 0;
-        while i < uniq_len(self) {
-            if !f(copy self[i]) { return false; }
-            i += 1;
+macro_rules! iterator {
+    /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
+    (struct $name:ident -> $ptr:ty, $elem:ty) => {
+        pub struct $name<'self, T> {
+            priv ptr: $ptr,
+            priv end: $ptr,
+            priv lifetime: $elem // FIXME: #5922
         }
-        return true;
-    }
-}
-
-// FIXME(#4148): This should be redundant
-impl<A:Copy> old_iter::CopyableNonstrictIter<A> for @[A] {
-    fn each_val(&const self, f: &fn(A) -> bool) -> bool {
-        let mut i = 0;
-        while i < self.len() {
-            if !f(copy self[i]) { return false; }
-            i += 1;
+    };*/
+    (impl $name:ident -> $elem:ty, $step:expr) => {
+        // could be implemented with &[T] with .slice(), but this avoids bounds checks
+        impl<'self, T> Iterator<$elem> for $name<'self, T> {
+            #[inline]
+            fn next(&mut self) -> Option<$elem> {
+                unsafe {
+                    if self.ptr == self.end {
+                        None
+                    } else {
+                        let old = self.ptr;
+                        self.ptr = self.ptr.offset($step);
+                        Some(cast::transmute(old))
+                    }
+                }
+            }
         }
-        return true;
     }
 }
 
-impl<A:Clone> Clone for ~[A] {
-    #[inline]
-    fn clone(&self) -> ~[A] {
-        self.map(|item| item.clone())
-    }
+//iterator!{struct VecIterator -> *T, &'self T}
+/// An iterator for iterating over a vector
+pub struct VecIterator<'self, T> {
+    priv ptr: *T,
+    priv end: *T,
+    priv lifetime: &'self T // FIXME: #5922
 }
+iterator!{impl VecIterator -> &'self T, 1}
 
-// could be implemented with &[T] with .slice(), but this avoids bounds checks
-pub struct VecIterator<'self, T> {
+//iterator!{struct VecRevIterator -> *T, &'self T}
+/// An iterator for iterating over a vector in reverse
+pub struct VecRevIterator<'self, T> {
     priv ptr: *T,
     priv end: *T,
     priv lifetime: &'self T // FIXME: #5922
 }
+iterator!{impl VecRevIterator -> &'self T, -1}
 
-impl<'self, T> Iterator<&'self T> for VecIterator<'self, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'self T> {
-        unsafe {
-            if self.ptr == self.end {
-                None
-            } else {
-                let old = self.ptr;
-                self.ptr = self.ptr.offset(1);
-                Some(cast::transmute(old))
-            }
-        }
+//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
+/// An iterator for mutating the elements of a vector
+pub struct VecMutIterator<'self, T> {
+    priv ptr: *mut T,
+    priv end: *mut T,
+    priv lifetime: &'self mut T // FIXME: #5922
+}
+iterator!{impl VecMutIterator -> &'self mut T, 1}
+
+//iterator!{struct VecMutRevIterator -> *mut T, &'self mut T}
+/// An iterator for mutating the elements of a vector in reverse
+pub struct VecMutRevIterator<'self, T> {
+    priv ptr: *mut T,
+    priv end: *mut T,
+    priv lifetime: &'self mut T // FIXME: #5922
+}
+iterator!{impl VecMutRevIterator -> &'self mut T, -1}
+
+impl<T> FromIter<T> for ~[T]{
+    #[inline(always)]
+    pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
+        let mut v = ~[];
+        for iter |x| { v.push(x) }
+        v
     }
 }
 
@@ -2968,8 +2803,9 @@ mod tests {
 
     #[test]
     fn test_is_empty() {
-        assert!(is_empty::<int>([]));
-        assert!(!is_empty([0]));
+        let xs: [int, ..0] = [];
+        assert!(xs.is_empty());
+        assert!(![0].is_empty());
     }
 
     #[test]
@@ -3417,39 +3253,6 @@ mod tests {
     }
 
     #[test]
-    fn test_foldl() {
-        // Test on-stack fold.
-        let mut v = ~[1u, 2u, 3u];
-        let mut sum = foldl(0u, v, add);
-        assert_eq!(sum, 6u);
-
-        // Test on-heap fold.
-        v = ~[1u, 2u, 3u, 4u, 5u];
-        sum = foldl(0u, v, add);
-        assert_eq!(sum, 15u);
-    }
-
-    #[test]
-    fn test_foldl2() {
-        fn sub(a: int, b: &int) -> int {
-            a - *b
-        }
-        let v = ~[1, 2, 3, 4];
-        let sum = foldl(0, v, sub);
-        assert_eq!(sum, -10);
-    }
-
-    #[test]
-    fn test_foldr() {
-        fn sub(a: &int, b: int) -> int {
-            *a - b
-        }
-        let v = ~[1, 2, 3, 4];
-        let sum = foldr(v, 0, sub);
-        assert_eq!(sum, -2);
-    }
-
-    #[test]
     fn test_each_empty() {
         for each::<int>([]) |_v| {
             fail!(); // should never be executed
@@ -3477,41 +3280,18 @@ mod tests {
     }
 
     #[test]
-    fn test_each_reverse_empty() {
-        let v: ~[int] = ~[];
-        for v.each_reverse |_v| {
-            fail!(); // should never execute
-        }
+    fn test_each_ret_len0() {
+        let a0 : [int, .. 0] = [];
+        assert_eq!(each(a0, |_p| fail!()), true);
     }
 
     #[test]
-    fn test_each_reverse_nonempty() {
-        let mut i = 0;
-        for each_reverse([1, 2, 3]) |v| {
-            if i == 0 { assert!(*v == 3); }
-            i += *v
-        }
-        assert_eq!(i, 6);
+    fn test_each_ret_len1() {
+        let a1 = [17];
+        assert_eq!(each(a1, |_p| true), true);
+        assert_eq!(each(a1, |_p| false), false);
     }
 
-    #[test]
-    fn test_eachi_reverse() {
-        let mut i = 0;
-        for eachi_reverse([0, 1, 2]) |j, v| {
-            if i == 0 { assert!(*v == 2); }
-            assert_eq!(j, *v as uint);
-            i += *v;
-        }
-        assert_eq!(i, 3);
-    }
-
-    #[test]
-    fn test_eachi_reverse_empty() {
-        let v: ~[int] = ~[];
-        for v.eachi_reverse |_i, _v| {
-            fail!(); // should never execute
-        }
-    }
 
     #[test]
     fn test_each_permutation() {
@@ -3536,33 +3316,6 @@ mod tests {
     }
 
     #[test]
-    fn test_any_and_all() {
-        assert!(any([1u, 2u, 3u], is_three));
-        assert!(!any([0u, 1u, 2u], is_three));
-        assert!(any([1u, 2u, 3u, 4u, 5u], is_three));
-        assert!(!any([1u, 2u, 4u, 5u, 6u], is_three));
-
-        assert!(all([3u, 3u, 3u], is_three));
-        assert!(!all([3u, 3u, 2u], is_three));
-        assert!(all([3u, 3u, 3u, 3u, 3u], is_three));
-        assert!(!all([3u, 3u, 0u, 1u, 2u], is_three));
-    }
-
-    #[test]
-    fn test_any2_and_all2() {
-
-        assert!(any2([2u, 4u, 6u], [2u, 4u, 6u], is_equal));
-        assert!(any2([1u, 2u, 3u], [4u, 5u, 3u], is_equal));
-        assert!(!any2([1u, 2u, 3u], [4u, 5u, 6u], is_equal));
-        assert!(any2([2u, 4u, 6u], [2u, 4u], is_equal));
-
-        assert!(all2([2u, 4u, 6u], [2u, 4u, 6u], is_equal));
-        assert!(!all2([1u, 2u, 3u], [4u, 5u, 3u], is_equal));
-        assert!(!all2([1u, 2u, 3u], [4u, 5u, 6u], is_equal));
-        assert!(!all2([2u, 4u, 6u], [2u, 4u], is_equal));
-    }
-
-    #[test]
     fn test_zip_unzip() {
         let v1 = ~[1, 2, 3];
         let v2 = ~[4, 5, 6];
@@ -3888,6 +3641,10 @@ mod tests {
     #[test]
     fn test_concat() {
         assert_eq!(concat([~[1], ~[2,3]]), ~[1, 2, 3]);
+        assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
+
+        assert_eq!(concat_slices([&[1], &[2,3]]), ~[1, 2, 3]);
+        assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
     }
 
     #[test]
@@ -3895,6 +3652,14 @@ mod tests {
         assert_eq!(connect([], &0), ~[]);
         assert_eq!(connect([~[1], ~[2, 3]], &0), ~[1, 0, 2, 3]);
         assert_eq!(connect([~[1], ~[2], ~[3]], &0), ~[1, 0, 2, 0, 3]);
+        assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
+        assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
+
+        assert_eq!(connect_slices([], &0), ~[]);
+        assert_eq!(connect_slices([&[1], &[2, 3]], &0), ~[1, 0, 2, 3]);
+        assert_eq!(connect_slices([&[1], &[2], &[3]], &0), ~[1, 0, 2, 0, 3]);
+        assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
+        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
     }
 
     #[test]
@@ -4298,113 +4063,6 @@ mod tests {
     #[ignore(windows)]
     #[should_fail]
     #[allow(non_implicitly_copyable_typarams)]
-    fn test_foldl_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do foldl((~0, @0), v) |_a, _b| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            (~0, @0)
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_foldr_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do foldr(v, (~0, @0)) |_a, _b| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            (~0, @0)
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_any_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do any(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_any2_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do any(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_all_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do all(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_alli_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do alli(v) |_i, _elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_all2_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do all2(v, v) |_elt1, _elt2| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
     fn test_find_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
         let mut i = 0;
@@ -4556,6 +4214,40 @@ mod tests {
     }
 
     #[test]
+    fn test_mut_iterator() {
+        use iterator::*;
+        let mut xs = [1, 2, 3, 4, 5];
+        for xs.mut_iter().advance |x| {
+            *x += 1;
+        }
+        assert_eq!(xs, [2, 3, 4, 5, 6])
+    }
+
+    #[test]
+    fn test_rev_iterator() {
+        use iterator::*;
+
+        let xs = [1, 2, 5, 10, 11];
+        let ys = [11, 10, 5, 2, 1];
+        let mut i = 0;
+        for xs.rev_iter().advance |&x| {
+            assert_eq!(x, ys[i]);
+            i += 1;
+        }
+        assert_eq!(i, 5);
+    }
+
+    #[test]
+    fn test_mut_rev_iterator() {
+        use iterator::*;
+        let mut xs = [1u, 2, 3, 4, 5];
+        for xs.mut_rev_iter().enumerate().advance |(i,x)| {
+            *x += i;
+        }
+        assert_eq!(xs, [5, 5, 5, 5, 5])
+    }
+
+    #[test]
     fn test_reverse_part() {
         let mut values = [1,2,3,4,5];
         reverse_part(values,1,4);
@@ -4601,14 +4293,4 @@ mod tests {
         }
         assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]);
     }
-
-    #[test]
-    fn test_each_val() {
-        use old_iter::CopyableNonstrictIter;
-        let mut i = 0;
-        for [1, 2, 3].each_val |v| {
-            i += v;
-        }
-        assert_eq!(i, 6);
-    }
 }