     }
 }
 
+/// Parses NSURLs.
+public func <-- (left: inout URL, right: JSON?) {
+    setLeftIfIsResultNonNil(left: &left, right: right, function: <--)
+}
+
+/// Parses optional NSURLs.
+public func <-- (left: inout URL?, right: JSON?) {
+    var str = ""
+    str <-- right
+    let set = CharacterSet.urlQueryAllowed
+    if let escapedStr = str.addingPercentEncoding(withAllowedCharacters: set),
+        let url = URL(string:escapedStr) {
+        left = url
+    }
+}
+
+/// Parses arrays of plain swift types.
+public func <-- <T>(left: inout [T], right: JSON?) {
+    setLeftIfIsResultNonNil(left:&left, right:right, function: <--)
+}
+
+/// Parses optional arrays of plain swift types.
+public func <-- <T>(left: inout [T]?, right: JSON?) {
+    if let a = right?.data as? [AnyObject] {
+        let tmp: [T] = a.flatMap { var t: T?; parseType(&t, right: JSON($0)); return t }
+        if tmp.count == a.count {
+            left = tmp
+        }
+    }
+}
+
+
+// MARK: - Private methods.
+
+func parseType<T>(_ left: inout T?, right: JSON?) {
+    if let v: T = right?.data as? T {
+        left = v
+    } else if let s = right?.data as? String {
+        parseString(&left, string:s)
+    }
+}
+
+func parseString<T>(_ left: inout T?, string: String) {
+    switch T.self {
+    case is Int.Type: if let v = Int(string) { left = v as? T }
+    case is UInt.Type: if let v = UInt(string) { left = v as? T }
+    case is Double.Type: if let v = Double(string) { left = v as? T }
+    case is Float.Type: if let v = Float(string) { left = v as? T }
+    case is CGFloat.Type: if let v = CGFloat.NativeType(string) { left = CGFloat(v) as? T }
+    case is Bool.Type: if let v = Int(string) { left = Bool(v != 0)  as? T}
+    default:()
+    }
+}
+
 func timeIntervalToDate(_ timeInterval: TimeInterval) -> Date {
     return useReferenceDate
     ? Date(timeIntervalSinceReferenceDate: timeInterval)
     : Date(timeIntervalSince1970: timeInterval)
 }
 
-func parseArray<T>(_ left: inout [T]?, right: JSON?) {
-    if let a = right?.data as? [AnyObject] {
-        let tmp: [T] = a.flatMap { var t: T?; parseType(&t, right: JSON($0)); return t }
-        if tmp.count == a.count {
-            left = tmp
-        }
-    }
-}
-
-func parseUserDefinedType<T: ArrowParsable>(_ left: inout T?, right: JSON?) {
-    if let json = JSON(right?.data) {
-        var t = T.init()
-        t.deserialize(json)
-        left = t
-    }
-}
-
-func parseArrayOfUserDefinedTypes<T: ArrowParsable>(_ left: inout [T]?, right: JSON?) {
-    if let a = right?.data as? [AnyObject] {
-        left = a.map {
-            var t = T.init()
-            if let json = JSON($0) {
-                t.deserialize(json)
-            }
-            return t
-        }
-    }
-}
-
-func setLeftIfIsResultNonNil<T>(left: inout [T], right: JSON?, function:(inout [T]?, JSON?) -> Void) {
-    var temp: [T]? = nil
+func setLeftIfIsResultNonNil<T>(left: inout T, right: JSON?, function: (inout T?, JSON?) -> Void) {
+    var temp: T? = nil
     function(&temp, right)
     if let t = temp {
         left = t


/// Parses user defined custom types.
public func <-- <T: ArrowParsable>(left: inout T, right: JSON?) {
    var temp: T? = nil
    parseUserDefinedType(&temp, right: right)
    if let t = temp {
        left = t
    }
}

/// Parses user defined optional custom types.
public func <-- <T: ArrowParsable>(left: inout T?, right: JSON?) {
    parseUserDefinedType(&left, right: right)
}

/// Parses arrays of user defined custom types.
public func <-- <T: ArrowParsable>(left: inout [T], right: JSON?) {
    setLeftIfIsResultNonNil(left:&left, right:right, function: parseArrayOfUserDefinedTypes)
}

/// Parses optional arrays of user defined custom types.
public func <-- <T: ArrowParsable>(left: inout [T]?, right: JSON?) {
    parseArrayOfUserDefinedTypes(&left, right: right)
}

/// Parses NSDates.
public func <-- (left: inout Date, right: JSON?) {
    var temp: Date? = nil
    parseDate(&temp, right:right)
    if let t = temp {
        left = t
    }
}

/// Parses optional NSDates.
public func <-- (left: inout Date?, right: JSON?) {
    parseDate(&left, right:right)
}

/// Parses NSURLs.
public func <-- (left: inout URL, right: JSON?) {
    var temp: URL? = nil
    parseURL(&temp, right:right)
    if let t = temp {
        left = t
    }
}

/// Parses optional NSURLs.
public func <-- (left: inout URL?, right: JSON?) {
    parseURL(&left, right: right)
}


/// Parses arrays of plain swift types.
public func <-- <T>(left: inout [T], right: JSON?) {
    setLeftIfIsResultNonNil(left:&left, right:right, function: parseArray)
}

/// Parses optional arrays of plain swift types.
public func <-- <T>(left: inout [T]?, right: JSON?) {
    parseArray(&left, right: right)
}


// MARK: - Private methods.

func parseType<T>(_ left: inout T?, right: JSON?) {
    if let v: T = right?.data as? T {
        left = v
    } else if let s = right?.data as? String {
        parseString(&left, string:s)
    }
}

func parseString<T>(_ left: inout T?, string: String) {
    switch T.self {
    case is Int.Type: if let v = Int(string) { left = v as? T }
    case is UInt.Type: if let v = UInt(string) { left = v as? T }
    case is Double.Type: if let v = Double(string) { left = v as? T }
    case is Float.Type: if let v = Float(string) { left = v as? T }
    case is CGFloat.Type: if let v = CGFloat.NativeType(string) { left = CGFloat(v) as? T }
    case is Bool.Type: if let v = Int(string) { left = Bool(v != 0)  as? T}
    default:()
    }
}

func parseURL(_ left: inout URL?, right: JSON?) {
    var str = ""
    str <-- right
    let set = CharacterSet.urlQueryAllowed
    if let escapedStr = str.addingPercentEncoding(withAllowedCharacters: set),
        let url = URL(string:escapedStr) {
        left = url
    }
}

func parseDate(_ left: inout Date?, right: JSON?) {
    // Use custom date format over high level setting when provided
    if let customFormat = right?.jsonDateFormat, let s = right?.data as? String {
        let df = DateFormatter()


/// Parses enums.
public func <-- <T: RawRepresentable>(left: inout T, right: JSON?) {
    setLeftIfIsResultNonNil(left: &left, right: right, function: <--)
}

/// Parses optional enums.
