     }
 }
 
+private extension UnboxFormatter {
+    func makeTransform() -> UnboxTransform<UnboxFormattedType> {
+        return {
+            guard let rawValue = $0 as? UnboxRawValueType else {
+                return nil
+            }
+            
+            return self.format(unboxedValue: rawValue)
+        }
+    }
+    
+    func makeCollectionTransform<C: UnboxableCollection>(allowInvalidElements: Bool) -> UnboxTransform<C> where C.UnboxValue == UnboxFormattedType {
+        return {
+            guard let collection = $0 as? C.UnboxRawCollection else {
+                return nil
+            }
+            
+            return try C.unbox(collection: collection,
+                               allowInvalidElements: allowInvalidElements,
+                               transform: self.makeTransform())
+        }
+    }
+}
+
 private extension Unboxer {
     static func unboxer(from data: Data, context: Any?) throws -> Unboxer {
         do {

        return try? unbox(keyPath: keyPath, context: context, allowInvalidElements: allowInvalidElements)
    }
    
    /// Unbox a required value that can be formatted using a formatter
    public func unbox<T: UnboxableWithFormatter, F: UnboxFormatter>(key: String, isKeyPath: Bool = true, formatter: F) throws -> T where F.UnboxFormattedType == T {
        return try UnboxValueResolver<F.UnboxRawValueType>(self).resolveRequiredValueForKey(key: key, isKeyPath: isKeyPath, transform: {
            return formatter.format(unboxedValue: $0)
        })
    }
    
    /// Unbox an optional value that can be formatted using a formatter
    public func unbox<T: UnboxableWithFormatter, F: UnboxFormatter>(key: String, isKeyPath: Bool = true, formatter: F) -> T? where F.UnboxFormattedType == T {
        return UnboxValueResolver<F.UnboxRawValueType>(self).resolveOptionalValueForKey(key: key, isKeyPath: isKeyPath, transform: {
            return formatter.format(unboxedValue: $0)
        })
    }
    
    /// Unbox a required Array containing values that can be formatted using a formatter (optionally allowing invalid elements)
    public func unbox<T: UnboxableWithFormatter, F: UnboxFormatter>(key: String, isKeyPath: Bool = true, formatter: F, allowInvalidElements: Bool = false) throws -> [T] where F.UnboxFormattedType == T {
        return try UnboxValueResolver<[F.UnboxRawValueType]>(self).resolveRequiredValueForKey(key: key, isKeyPath: isKeyPath, transform: { array in
            if allowInvalidElements {
                return array.flatMap {
                    formatter.format(unboxedValue: $0)
                }
            } else {
                var formattedArray = [T]()
                
                for value in array {
                    guard let formattedValue = formatter.format(unboxedValue: value) else {
                        return nil
                    }
                    
                    formattedArray.append(formattedValue)
                }
                
                return formattedArray
            }
        })
    }
    
    /// Unbox an optional Array containing values that can be formatted using a formatter (optionally allowing invalid elements)
    public func unbox<T: UnboxableWithFormatter, F: UnboxFormatter>(key: String, isKeyPath: Bool = true, formatter: F, allowInvalidElements: Bool = false) -> [T]? where F.UnboxFormattedType == T {
        return UnboxValueResolver<[F.UnboxRawValueType]>(self).resolveOptionalValueForKey(key: key, isKeyPath: isKeyPath, transform: { (array) -> [T]? in
            if allowInvalidElements {
                return array.flatMap({ formatter.format(unboxedValue: $0) })
            } else {
                var formattedArray = [T]()
                
                for value in array {
                    guard let formattedValue = formatter.format(unboxedValue: value) else {
                        return nil
                    }
                    
                    formattedArray.append(formattedValue)
                }
                
                return formattedArray
            }
        })
    }
}


    public static func transform(unboxedKey: String) -> String? {
        return unboxedKey
    }
}

/// Extension making DateFormatter usable as a UnboxFormatter
