     A CerealEncoder handles encoding items into a format that can be stored in a simple format, such as NSData or String.
 */
 public struct CerealEncoder {
-    private var items = [String: String]()
+    private var items: [CoderTreeValue] = []
 
     /**
     Initializes a `CerealEncoder` to store encoded data.
     */
-    public init() { }
-
-    /// Returns all the encoded items as a `String` object.
-    public func toString() -> String {
-        var encodedItems = [String]()
-
-        for (key, item) in items {
-            encodedItems.append("k,\(key.characters.count):\(key):\(item)")
-        }
-
-        let joined = encodedItems.joinWithSeparator(":")
-
-        return joined
+    public init(capacity: Int = 20) {
+        items.reserveCapacity(capacity)
     }
 
     /// Returns all of the encoded items as an `NSData` object.
     public func toData() -> NSData {
-        return toString().dataUsingEncoding(NSUTF8StringEncoding)!
+        var bytes = [UInt8]()
+        bytes.append(CerealCoderTreeValueType.SubTree.rawValue)
+        bytes += countCapacityBytes(self.items)
+        return NSData(bytes: bytes, length: bytes.count)
     }
 
     // MARK: - Single items

     */
    public mutating func encode<ItemKeyType: protocol<RawRepresentable, CerealRepresentable, Hashable>, ItemValueType: protocol<RawRepresentable, CerealRepresentable> where ItemKeyType.RawValue: CerealRepresentable, ItemValueType.RawValue: CerealRepresentable>(items: [[ItemKeyType: ItemValueType]]?, forKey key: String) throws {
        guard let unwrapped = items else { return }
        self.items[key] = try encodeItems(unwrapped)
    }

    /**

    */
    public mutating func encode<ItemType: CerealRepresentable>(items: [ItemType]?, forKey key: String) throws {
        guard let unwrapped = items else { return }
        self.items.append(.PairValue(.StringValue(key), try encodeItems(unwrapped)))
    }

    /**
