     }
     
     func decode<T>(_ value: Primitive?) throws -> T? where T : Decodable {
-        guard let value = value else {
+        guard let value = value, !(value is NSNull) else {
             return nil
         }
         
         if T.self == ObjectId.self {
             let id = try BSON.unwrap(unwrap(value), codingPath: codingPath) as ObjectId as! T
             return id
+        } else if T.self == Date.self {
+            let date = try BSON.unwrap(unwrap(value), codingPath: codingPath) as Date as! T
+            return date
+        } else if T.self == Document.self {
+            let document = try BSON.unwrap(unwrap(value), codingPath: codingPath) as Document as! T
+            return document
         }
         
         let decoder = _BSONDecoder(target: .storedPrimitive(value))

    
    // MARK: - Value conversion
    func unwrap<T : Primitive>(_ value: Primitive?) throws -> T? {
        guard let primitiveValue = value else {
            return nil
        }
        


import Foundation

// MARK: - Codable Conformance

fileprivate struct DocumentCodingKey : CodingKey {
    let intValue: Int? = nil
    var stringValue: String
    
    init?(intValue: Int) {
        return nil
    }
    
    init?(stringValue: String) {
        self.stringValue = stringValue
    }
    
    init(_ string: String) {
        self.stringValue = string
    }
}

extension ObjectId : Codable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        
        if let container = container as? _BSONSingleValueEncodingContainer {
            container.encoder.target.primitive = self
            return
        }
        
        try container.encode(self.hexString)
    }
    
    public init(from decoder: Decoder) throws {
        let singleValueContainer = try decoder.singleValueContainer()
        
        if let container = singleValueContainer as? _BSONSingleValueDecodingContainer {
            guard let id = container.decoder.target.primitive as? ObjectId else {
                throw DecodingError.typeMismatch(ObjectId.self, DecodingError.Context(codingPath: container.decoder.codingPath, debugDescription: "Expected ObjectId but got \(String(describing: container.decoder.target.primitive ?? nil))"))
            }
            
            self = id
            return
        }
        
        let string = try singleValueContainer.decode(String.self)
        self = try ObjectId(string)
    }
}

extension Document : Codable {
    public func encode(to encoder: Encoder) throws {
        throw EncodingError.invalidValue(self, EncodingError.Context(codingPath: encoder.codingPath, debugDescription: "Document can only be encoded by BSONEncoder."))
    }
    
    public init(from decoder: Decoder) throws {
        throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Document can only be decoded by BSONDecoder."))
    }
}

// MARK: - Helpers

// These primitives cannot be added to the document using a subscript
fileprivate protocol _BSONFakePrimitive {}
extension Dictionary : _BSONFakePrimitive {}
extension Array : _BSONFakePrimitive {}

// MARK: - Encoding

public class BSONEncoder {
    
