         
         self.encoder.codingPath.append(key)
         defer { self.encoder.codingPath.removeLast() }
-        let keyPath = encoder.codingPath.path
-        try encoder.writeEncodable(value, for: keyPath)
+        try encoder.writeEncodable(value)
     }
     
     func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: K) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {


internal extension PredicateEncoder.Encoder {
    
    func write(_ value: Value, for keyPath: String) {
        values[keyPath] = value
        log?("Did encode \(value.type) value for keyPath \"\(keyPath)\"")
    }
    
    func writeEncodable <T: Encodable> (_ value: T, for keyPath: String) throws {
        
        if let data = value as? Data {
            write(.data(data), for: keyPath)
        } else if let uuid = value as? UUID {
            write(.uuid(uuid), for: keyPath)
        } else if let date = value as? Date {
            write(.date(date), for: keyPath)
        } else {
            // encode using Encodable, container should write directly.
            try value.encode(to: self)

    /// The path of coding keys taken to get to this point in encoding.
    let codingPath: [CodingKey]
    
    // MARK: - Initialization
    
    init(referencing encoder: PredicateEncoder.Encoder) {
        self.encoder = encoder
        self.codingPath = encoder.codingPath
    }
    
    // MARK: - Methods
    
    /// The number of elements encoded into the container.
    private(set) var count: Int = 0
    
    func encodeNil() throws { append(.null) }
    
    func encode(_ value: Bool) throws { append(value) }
    
    func encode(_ value: String) throws { append(value) }
    
    func encode(_ value: Double) throws { append(value) }
    
    func encode(_ value: Float) throws { append(value) }
    
    func encode(_ value: Int) throws { append(Int64(value)) }
    
    func encode(_ value: Int8) throws { append(value) }
    
    func encode(_ value: Int16) throws { append(value) }
    
    func encode(_ value: Int32) throws { append(value) }
    
    func encode(_ value: Int64) throws { append(value) }
    
    func encode(_ value: UInt) throws { append(UInt64(value)) }
    
    func encode(_ value: UInt8) throws { append(value) }
    
    func encode(_ value: UInt16) throws { append(value) }
    
    func encode(_ value: UInt32) throws { append(value) }
    
    func encode(_ value: UInt64) throws { append(value) }
    
    func encode <T: Encodable> (_ value: T) throws {
        let key = IndexCodingKey(index: count)
        self.encoder.codingPath.append(key)
        defer { self.encoder.codingPath.removeLast() }
        try encoder.writeEncodable(value)
        count += 1
    }
    
    func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
        fatalError()
    }
    
    func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
        fatalError()
    }
    
    func superEncoder() -> Encoder {
        fatalError()
    }
    
    // MARK: - Private Methods
    
    private func append<T: PredicateValue>(_ value: T) {
        append(value.predicateValue)
    }
    
    private func append(_ value: Value) {
        let key = IndexCodingKey(index: count)
        self.encoder.codingPath.append(key)
        defer { self.encoder.codingPath.removeLast() }
        encoder.write(value)
        count += 1
    }
}

internal struct IndexCodingKey: CodingKey, Equatable, Hashable {
    
    let index: Int
    
    init(index: Int) {
        self.index = index
    }
    
    var stringValue: String {
        return index.description
    }
    
    init?(stringValue: String) {
        guard let index = UInt(stringValue)
            else { return nil }
        self.init(index: Int(index))
    }
    
    var intValue: Int? {
        return index
    }
    
    init?(intValue: Int) {
        self.init(index: intValue)
    }
}
