diff --git a/src/bytes.rs b/src/bytes.rs
index 07b66383f531c4f2e75b0acd1caf8f967483d5bc..d4cf64445e5f85d8e5fda4daf02e3b9ee0882342 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -1,23 +1,134 @@
-use {IntoBuf, ByteBuf, SliceBuf};
+use {IntoBuf, BufMut};
 
 use std::{cmp, fmt, mem, ops, slice, ptr};
 use std::cell::{Cell, UnsafeCell};
+use std::io::Cursor;
 use std::sync::Arc;
 
-/// A reference counted slice of bytes.
+/// A reference counted contiguous slice of memory.
+///
+/// `Bytes` is an efficient container for storing and operating on continguous
+/// slices of memory. It is intended for use primarily in networking code, but
+/// could have applications elsewhere as well.
+///
+/// `Bytes` values facilitate zero-copy network programming by allowing multiple
+/// `Bytes` objects to point to the same underlying memory. This is managed by
+/// using a reference count to track when the memory is no longer needed and can
+/// be freed.
+///
+/// ```
+/// use bytes::Bytes;
+///
+/// let mem = Bytes::from_slice(b"Hello world");
+/// let a = mem.slice(0, 5);
+///
+/// assert_eq!(&a[..], b"Hello");
+///
+/// let b = mem.drain_to(6);
+///
+/// assert_eq!(&mem[..], b"world");
+/// assert_eq!(&b[..], b"Hello ");
+/// ```
+///
+/// # Memory layout
+///
+/// The `Bytes` struct itself is fairly small, limited to a pointer to the
+/// memory and 4 `usize` fields used to track information about which segment of
+/// the underlying memory the `Bytes` handle has access to.
+///
+/// The memory layout looks like this:
+///
+/// ```text
+/// +-------+
+/// | Bytes |
+/// +-------+
+///  /      \_____
+/// |              \
+/// v               v
+/// +-----+------------------------------------+
+/// | Arc |         |      Data     |          |
+/// +-----+------------------------------------+
+/// ```
+///
+/// `Bytes` keeps both a pointer to the shared `Arc` containing the full memory
+/// slice and a pointer to the start of the region visible by the handle.
+/// `Bytes` also tracks the length of its view into the memory.
+///
+/// # Sharing
+///
+/// The memory itself is reference counted, and multiple `Bytes` objects may
+/// point to the same region. Each `Bytes` handle point to different sections within
+/// the memory region, and `Bytes` handle may or may not have overlapping views
+/// into the memory.
+///
+///
+/// ```text
+///
+///    Arc ptrs                   +---------+
+///    ________________________ / | Bytes 2 |
+///   /                           +---------+
+///  /          +-----------+     |         |
+/// |_________/ |  Bytes 1  |     |         |
+/// |           +-----------+     |         |
+/// |           |           | ___/ data     | tail
+/// |      data |      tail |/              |
+/// v           v           v               v
+/// +-----+---------------------------------+-----+
+/// | Arc |     |           |               |     |
+/// +-----+---------------------------------+-----+
+/// ```
+///
+/// # Mutating
+///
+/// While `Bytes` handles may potentially represent overlapping views of the
+/// underlying memory slice and may not be mutated, `BytesMut` handles are
+/// guaranteed to be the only handle able to view that slice of memory. As such,
+/// `BytesMut` handles are able to mutate the underlying memory. Note that
+/// holding a unique view to a region of memory does not mean that there are not
+/// other `Bytes` and `BytesMut` handles with disjoint views of the underlying
+/// memory.
+///
+/// # Inline bytes.
+///
+/// As an opitmization, when the slice referenced by a `Bytes` or `BytesMut`
+/// handle is small enough [1], `Bytes` will avoid the allocation by inlining
+/// the slice directly in the handle. In this case, a clone is no longer
+/// "shallow" and the data will be copied.
+///
+/// [1] Small enough: 24 bytes on 64 bit systems, 12 on 32 bit systems.
 ///
-/// A `Bytes` is an immutable sequence of bytes. Given that it is guaranteed to
-/// be immutable, `Bytes` is `Sync`, `Clone` is shallow (ref count increment),
-/// and all operations only update views into the underlying data without
-/// requiring any copies.
 pub struct Bytes {
     inner: Inner,
 }
 
-/// A unique reference to a slice of bytes.
+/// A unique reference to a continuous slice of memory.
+///
+/// `BytesMut` represents a unique view into a potentially shared memory region.
+/// Given the uniqueness guarantee, owners of `BytesMut` handles are able to
+/// mutate the memory.
+///
+/// For more detail, see [Bytes](struct.Bytes.html).
+///
+/// ```
+/// use bytes::{BytesMut, BufMut};
+///
+/// let mut buf = BytesMut::with_capacity(64);
 ///
-/// A `BytesMut` is a unique handle to a slice of bytes allowing mutation of
-/// the underlying bytes.
+/// buf.put_u8(b'h');
+/// buf.put_u8(b'e');
+/// buf.put_str("llo");
+///
+/// assert_eq!(&buf[..], b"hello");
+///
+/// // Freeze the buffer so that it can be shared
+/// let a = buf.freeze();
+///
+/// // This does not allocate, instead `b` points to the same memory.
+/// let b = a.clone();
+///
+/// assert_eq!(&a[..], b"hello");
+/// assert_eq!(&b[..], b"hello");
+/// ```
 pub struct BytesMut {
     inner: Inner
 }
@@ -208,18 +319,18 @@ impl Bytes {
 }
 
 impl IntoBuf for Bytes {
-    type Buf = SliceBuf<Self>;
+    type Buf = Cursor<Self>;
 
     fn into_buf(self) -> Self::Buf {
-        SliceBuf::new(self)
+        Cursor::new(self)
     }
 }
 
 impl<'a> IntoBuf for &'a Bytes {
-    type Buf = SliceBuf<Self>;
+    type Buf = Cursor<Self>;
 
     fn into_buf(self) -> Self::Buf {
-        SliceBuf::new(self)
+        Cursor::new(self)
     }
 }
 
@@ -286,9 +397,31 @@ unsafe impl Sync for Bytes {}
 
 impl BytesMut {
     /// Create a new `BytesMut` with the specified capacity.
+    ///
+    /// The returned `BytesMut` will be able to hold at least `capacity` bytes
+    /// without reallocating. If `capacity` is under `3 * size:of::<usize>()`,
+    /// then `BytesMut` will not allocate.
+    ///
+    /// It is important to note that this function does not specify the length
+    /// of the returned `BytesMut`, but only the capacity.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
+    ///
+    /// let mut bytes = BytesMut::with_capacity(64);
+    ///
+    /// // `bytes` contains no data, even though there is capacity
+    /// assert_eq!(bytes.len(), 0);
+    ///
+    /// bytes.copy_from_slice(b"hello world");
+    ///
+    /// assert_eq!(&bytes[..], b"hello world");
+    /// ```
     #[inline]
-    pub fn with_capacity(cap: usize) -> BytesMut {
-        if cap <= INLINE_CAP {
+    pub fn with_capacity(capacity: usize) -> BytesMut {
+        if capacity <= INLINE_CAP {
             BytesMut {
                 inner: Inner {
                     data: UnsafeCell::new(Data {
@@ -300,7 +433,7 @@ impl BytesMut {
                 }
             }
         } else {
-            BytesMut::from(Vec::with_capacity(cap))
+            BytesMut::from(Vec::with_capacity(capacity))
         }
     }
 
@@ -325,8 +458,9 @@ impl BytesMut {
                 }
             }
         } else {
-            let buf = ByteBuf::from_slice(b);
-            buf.into_inner()
+            let mut buf = BytesMut::with_capacity(bytes.as_ref().len());
+            buf.copy_from_slice(bytes.as_ref());
+            buf
         }
     }
 
@@ -457,6 +591,115 @@ impl BytesMut {
     }
 }
 
+impl BufMut for BytesMut {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        self.capacity() - self.len()
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        let new_len = self.len() + cnt;
+        self.set_len(new_len);
+    }
+
+    #[inline]
+    unsafe fn bytes_mut(&mut self) -> &mut [u8] {
+        let len = self.len();
+        &mut self.as_raw()[len..]
+    }
+
+    #[inline]
+    fn copy_from_slice(&mut self, src: &[u8]) {
+        assert!(self.remaining_mut() >= src.len());
+
+        let len = src.len();
+
+        unsafe {
+            self.bytes_mut()[..len].copy_from_slice(src);
+            self.advance_mut(len);
+        }
+    }
+}
+
+impl IntoBuf for BytesMut {
+    type Buf = Cursor<Self>;
+
+    fn into_buf(self) -> Self::Buf {
+        Cursor::new(self)
+    }
+}
+
+impl<'a> IntoBuf for &'a BytesMut {
+    type Buf = Cursor<&'a BytesMut>;
+
+    fn into_buf(self) -> Self::Buf {
+        Cursor::new(self)
+    }
+}
+
+impl AsRef<[u8]> for BytesMut {
+    fn as_ref(&self) -> &[u8] {
+        self.inner.as_ref()
+    }
+}
+
+impl ops::Deref for BytesMut {
+    type Target = [u8];
+
+    fn deref(&self) -> &[u8] {
+        self.as_ref()
+    }
+}
+
+impl ops::DerefMut for BytesMut {
+    fn deref_mut(&mut self) -> &mut [u8] {
+        self.as_mut()
+    }
+}
+
+impl From<Vec<u8>> for BytesMut {
+    fn from(mut src: Vec<u8>) -> BytesMut {
+        let len = src.len();
+        let cap = src.capacity();
+        let ptr = src.as_mut_ptr();
+
+        mem::forget(src);
+
+        BytesMut {
+            inner: Inner {
+                data: UnsafeCell::new(Data {
+                    ptr: ptr,
+                    len: len,
+                    cap: cap,
+                }),
+                arc: Cell::new(0),
+            },
+        }
+    }
+}
+
+impl<'a> From<&'a [u8]> for BytesMut {
+    fn from(src: &'a [u8]) -> BytesMut {
+        BytesMut::from_slice(src)
+    }
+}
+
+impl PartialEq for BytesMut {
+    fn eq(&self, other: &BytesMut) -> bool {
+        self.inner.as_ref() == other.inner.as_ref()
+    }
+}
+
+impl Eq for BytesMut {
+}
+
+impl fmt::Debug for BytesMut {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(self.inner.as_ref(), fmt)
+    }
+}
+
 /*
  *
  * ===== Inner =====
@@ -795,84 +1038,6 @@ impl Drop for Inner {
 
 unsafe impl Send for Inner {}
 
-impl IntoBuf for BytesMut {
-    type Buf = SliceBuf<Self>;
-
-    fn into_buf(self) -> Self::Buf {
-        SliceBuf::new(self)
-    }
-}
-
-impl<'a> IntoBuf for &'a BytesMut {
-    type Buf = SliceBuf<&'a BytesMut>;
-
-    fn into_buf(self) -> Self::Buf {
-        SliceBuf::new(self)
-    }
-}
-
-impl AsRef<[u8]> for BytesMut {
-    fn as_ref(&self) -> &[u8] {
-        self.inner.as_ref()
-    }
-}
-
-impl ops::Deref for BytesMut {
-    type Target = [u8];
-
-    fn deref(&self) -> &[u8] {
-        self.as_ref()
-    }
-}
-
-impl ops::DerefMut for BytesMut {
-    fn deref_mut(&mut self) -> &mut [u8] {
-        self.as_mut()
-    }
-}
-
-impl From<Vec<u8>> for BytesMut {
-    fn from(mut src: Vec<u8>) -> BytesMut {
-        let len = src.len();
-        let cap = src.capacity();
-        let ptr = src.as_mut_ptr();
-
-        mem::forget(src);
-
-        BytesMut {
-            inner: Inner {
-                data: UnsafeCell::new(Data {
-                    ptr: ptr,
-                    len: len,
-                    cap: cap,
-                }),
-                arc: Cell::new(0),
-            },
-        }
-    }
-}
-
-impl<'a> From<&'a [u8]> for BytesMut {
-    fn from(src: &'a [u8]) -> BytesMut {
-        BytesMut::from_slice(src)
-    }
-}
-
-impl PartialEq for BytesMut {
-    fn eq(&self, other: &BytesMut) -> bool {
-        self.inner.as_ref() == other.inner.as_ref()
-    }
-}
-
-impl Eq for BytesMut {
-}
-
-impl fmt::Debug for BytesMut {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(self.inner.as_ref(), fmt)
-    }
-}
-
 /*
  *
  * ===== PartialEq =====
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index a87413258eb4e420e1469c407a5da8b6128e1d2a..083d92ac55cff979ee8a07d7d394ab554c42d787 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -102,7 +102,7 @@ fn split_off() {
     assert_eq!(hello, &b"hello"[..]);
     assert_eq!(world, &b"world"[..]);
 
-    let mut hello = BytesMut::from_slice(b"helloworld");
+    let hello = BytesMut::from_slice(b"helloworld");
     let world = hello.split_off(5);
 
     assert_eq!(hello, &b"hello"[..]);
@@ -119,13 +119,13 @@ fn split_off_oob() {
 #[test]
 #[should_panic]
 fn split_off_oob_mut() {
-    let mut hello = BytesMut::from_slice(b"helloworld");
+    let hello = BytesMut::from_slice(b"helloworld");
     hello.split_off(25);
 }
 
 #[test]
 fn split_off_uninitialized() {
-    let mut bytes = BytesMut::with_capacity(1024);
+    let bytes = BytesMut::with_capacity(1024);
     let other = bytes.split_off(128);
 
     assert_eq!(bytes.len(), 0);
@@ -168,13 +168,13 @@ fn drain_to_oob() {
 #[test]
 #[should_panic]
 fn drain_to_oob_mut() {
-    let mut hello = BytesMut::from_slice(b"helloworld");
+    let hello = BytesMut::from_slice(b"helloworld");
     hello.drain_to(30);
 }
 
 #[test]
 fn drain_to_uninitialized() {
-    let mut bytes = BytesMut::with_capacity(1024);
+    let bytes = BytesMut::with_capacity(1024);
     let other = bytes.drain_to(128);
 
     assert_eq!(bytes.len(), 0);