Merge pull request #718 from djones6/json_dataperf

diff --git a/CoreFoundation/Locale.subproj/CFLocale.c b/CoreFoundation/Locale.subproj/CFLocale.c
index b502faf..69dda52 100644
--- a/CoreFoundation/Locale.subproj/CFLocale.c
+++ b/CoreFoundation/Locale.subproj/CFLocale.c
@@ -280,7 +280,12 @@
 
 
 #if DEPLOYMENT_TARGET_MACOSX
+// Specify a default locale on Mac for Swift
+#if DEPLOYMENT_RUNTIME_SWIFT
+#define FALLBACK_LOCALE_NAME CFSTR("en_US")
+#else
 #define FALLBACK_LOCALE_NAME CFSTR("")
+#endif /* DEPLOYMENT_RUNTIME_SWIFT */
 #elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define FALLBACK_LOCALE_NAME CFSTR("en_US")
 #elif DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
diff --git a/Docs/Status.md b/Docs/Status.md
index 6c0eb68..e3b8d0b 100644
--- a/Docs/Status.md
+++ b/Docs/Status.md
@@ -53,10 +53,10 @@
     | `URLProtectionSpace`         | Unimplemented   | None          |                                                                                                                    |
     | `URLProtocol`                | Unimplemented   | None          |                                                                                                                    |
     | `URLProtocolClient`          | Unimplemented   | None          |                                                                                                                    |
-    | `NSURLRequest`               | Mostly Complete | Incomplete    | `NSCoding` remains unimplemented                                                                                   |
-    | `NSMutableURLRequest`        | Mostly Complete | Incomplete    | `NSCoding` remains unimplemented                                                                                   |
-    | `URLResponse`                | Mostly Complete | Incomplete    | `NSCoding` remains unimplemented                                                                                   |
-    | `NSHTTPURLResponse`          | Mostly Complete | Substantial   | `NSCoding` remains unimplemented                                                                                   |
+    | `NSURLRequest`               | Mostly Complete | Incomplete    |                                                                                                                    |
+    | `NSMutableURLRequest`        | Mostly Complete | Incomplete    |                                                                                                                    |
+    | `URLResponse`                | Mostly Complete | Incomplete    |                                                                                                                    |
+    | `NSHTTPURLResponse`          | Mostly Complete | Substantial   |                                                                                                                    |
     | `NSURL`                      | Mostly Complete | Substantial   | `NSCoding` with non-keyed-coding archivers, `checkResourceIsReachable()`, and resource values remain unimplemented |
     | `NSURLQueryItem`             | Mostly Complete | N/A           | `NSCoding` remains unimplemented                                                                                   |
     | `URLResourceKey`             | Complete        | N/A           |                                                                                                                    |
diff --git a/Foundation/NSData.swift b/Foundation/NSData.swift
index 7c368a2..80a07fa 100644
--- a/Foundation/NSData.swift
+++ b/Foundation/NSData.swift
@@ -217,7 +217,12 @@
     }
     
     open var bytes: UnsafeRawPointer {
-        return UnsafeRawPointer(CFDataGetBytePtr(_cfObject))
+        guard let bytePtr = CFDataGetBytePtr(_cfObject) else {
+            //This could occure on empty data being encoded.
+            //TODO: switch with nil when signature is fixed
+            return UnsafeRawPointer(bitPattern: 0xf00deadb0c0)! //would not result in 'nil unwrapped optional'
+        }
+        return UnsafeRawPointer(bytePtr)
     }
 
     
diff --git a/Foundation/NSFileHandle.swift b/Foundation/NSFileHandle.swift
old mode 100644
new mode 100755
index 8596e66..dcc3e5d
--- a/Foundation/NSFileHandle.swift
+++ b/Foundation/NSFileHandle.swift
@@ -214,11 +214,49 @@
     open class var standardError: FileHandle {
         return _stderrFileHandle
     }
-    
+
+    internal static var _nulldeviceFileHandle: FileHandle = {
+        class NullDevice: FileHandle {
+            override var availableData: Data {
+                return Data()
+            }
+
+            override func readDataToEndOfFile() -> Data {
+                return Data()
+            }
+
+            override func readData(ofLength length: Int) -> Data {
+                return Data()
+            }
+
+            override func write(_ data: Data) {}
+
+            override var offsetInFile: UInt64 {
+                return 0
+            }
+
+            override func seekToEndOfFile() -> UInt64 {
+                return 0
+            }
+
+            override func seek(toFileOffset offset: UInt64) {}
+
+            override func truncateFile(atOffset offset: UInt64) {}
+
+            override func synchronizeFile() {}
+
+            override func closeFile() {}
+
+            deinit {}
+        }
+
+        return NullDevice(fileDescriptor: -1, closeOnDealloc: false)
+    }()
+
     open class var nullDevice: FileHandle {
-        NSUnimplemented()
+        return _nulldeviceFileHandle
     }
-    
+
     public convenience init?(forReadingAtPath path: String) {
         self.init(path: path, flags: O_RDONLY, createMode: 0)
     }
diff --git a/Foundation/NSJSONSerialization.swift b/Foundation/NSJSONSerialization.swift
index f2ffeaa..cd4aed7 100644
--- a/Foundation/NSJSONSerialization.swift
+++ b/Foundation/NSJSONSerialization.swift
@@ -277,21 +277,21 @@
     }
     
     mutating func serializeJSON(_ obj: Any) throws {
-        
-        if let str = obj as? String {
+
+        switch (obj) {
+        case let str as String:
             try serializeString(str)
-        } else if let num = _SwiftValue.store(obj) as? NSNumber {
-            try serializeNumber(num)
-        } else if let array = obj as? Array<Any> {
+        case let boolValue as Bool:
+            serializeBool(boolValue)
+        case _ where _SwiftValue.store(obj) is NSNumber:
+            try serializeNumber(_SwiftValue.store(obj) as! NSNumber)
+        case let array as Array<Any>:
             try serializeArray(array)
-        } else if let dict = obj as? Dictionary<AnyHashable, Any> {
+        case let dict as Dictionary<AnyHashable, Any>:
             try serializeDictionary(dict)
-        } else if let null = obj as? NSNull {
+        case let null as NSNull:
             try serializeNull(null)
-        } else if let boolVal = obj as? Bool {
-            try serializeNumber(NSNumber(value: boolVal))
-        }
-        else {
+        default:
             throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Invalid object cannot be serialized"])
         }
     }
@@ -326,15 +326,26 @@
         writer("\"")
     }
 
+    func serializeBool(_ bool: Bool) {
+        switch bool {
+        case true:
+            writer("true")
+        case false:
+            writer("false")
+        }
+    }
+
     mutating func serializeNumber(_ num: NSNumber) throws {
         if num.doubleValue.isInfinite || num.doubleValue.isNaN {
             throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Number cannot be infinity or NaN"])
         }
         
-        // Cannot detect type information (e.g. bool) as there is no objCType property on NSNumber in Swift
-        // So, just print the number
-
-        writer(_serializationString(for: num))
+        switch num._objCType {
+        case .Bool:
+            serializeBool(num.boolValue)
+        default:
+            writer(_serializationString(for: num))
+        }
     }
 
     mutating func serializeArray(_ array: [Any]) throws {
diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift
index 14bec84..5f75de8 100644
--- a/Foundation/NSNumber.swift
+++ b/Foundation/NSNumber.swift
@@ -200,7 +200,9 @@
     // This layout MUST be the same as CFNumber so that they are bridgeable
     private var _base = _CFInfo(typeID: CFNumberGetTypeID())
     private var _pad: UInt64 = 0
-    
+
+    internal let _objCType: _NSSimpleObjCType
+
     internal var _cfObject: CFType {
         return unsafeBitCast(self, to: CFType.self)
     }
@@ -221,77 +223,95 @@
         }
         return false
     }
+
+    open override var objCType: UnsafePointer<Int8> {
+        return UnsafePointer<Int8>(bitPattern: UInt(_objCType.rawValue.value))!
+    }
     
     deinit {
         _CFDeinit(self)
     }
     
     public init(value: Int8) {
+        _objCType = .Char
         super.init()
         _CFNumberInitInt8(_cfObject, value)
     }
     
     public init(value: UInt8) {
+        _objCType = .UChar
         super.init()
         _CFNumberInitUInt8(_cfObject, value)
     }
     
     public init(value: Int16) {
+        _objCType = .Short
         super.init()
         _CFNumberInitInt16(_cfObject, value)
     }
     
     public init(value: UInt16) {
+        _objCType = .UShort
         super.init()
         _CFNumberInitUInt16(_cfObject, value)
     }
     
     public init(value: Int32) {
+        _objCType = .Long
         super.init()
         _CFNumberInitInt32(_cfObject, value)
     }
     
     public init(value: UInt32) {
+        _objCType = .ULong
         super.init()
         _CFNumberInitUInt32(_cfObject, value)
     }
     
     public init(value: Int) {
+        _objCType = .Int
         super.init()
         _CFNumberInitInt(_cfObject, value)
     }
     
     public init(value: UInt) {
+        _objCType = .UInt
         super.init()
         _CFNumberInitUInt(_cfObject, value)
     }
     
     public init(value: Int64) {
+        _objCType = .LongLong
         super.init()
         _CFNumberInitInt64(_cfObject, value)
     }
     
     public init(value: UInt64) {
+        _objCType = .ULongLong
         super.init()
         _CFNumberInitUInt64(_cfObject, value)
     }
     
     public init(value: Float) {
+        _objCType = .Float
         super.init()
         _CFNumberInitFloat(_cfObject, value)
     }
     
     public init(value: Double) {
+        _objCType = .Double
         super.init()
         _CFNumberInitDouble(_cfObject, value)
     }
     
     public init(value: Bool) {
+        _objCType = .Bool
         super.init()
         _CFNumberInitBool(_cfObject, value)
     }
 
     override internal init() {
+        _objCType = .Undef
         super.init()
     }
 
diff --git a/Foundation/NSNumberFormatter.swift b/Foundation/NSNumberFormatter.swift
index d0cf61e..fe319d1 100644
--- a/Foundation/NSNumberFormatter.swift
+++ b/Foundation/NSNumberFormatter.swift
@@ -70,6 +70,9 @@
             
             let obj = CFNumberFormatterCreate(kCFAllocatorSystemDefault, locale._cfObject, numberStyle)!
             _setFormatterAttributes(obj)
+            if let format = _format {
+                CFNumberFormatterSetFormat(obj, format._cfObject)
+            }
             _currentCfFormatter = obj
             return obj
         }
@@ -99,12 +102,13 @@
     open func number(from string: String) -> NSNumber? {
         var range = CFRange(location: 0, length: string.length)
         let number = withUnsafeMutablePointer(to: &range) { (rangePointer: UnsafeMutablePointer<CFRange>) -> NSNumber? in
-            
+
             #if os(OSX) || os(iOS)
-                let result = CFNumberFormatterCreateNumberFromString(kCFAllocatorSystemDefault, _cfFormatter, string._cfObject, rangePointer, CFNumberFormatterOptionFlags.parseIntegersOnly.rawValue)
+                let parseOption = allowsFloats ? 0 : CFNumberFormatterOptionFlags.parseIntegersOnly.rawValue
             #else
-                let result = CFNumberFormatterCreateNumberFromString(kCFAllocatorSystemDefault, _cfFormatter, string._cfObject, rangePointer, CFOptionFlags(kCFNumberFormatterParseIntegersOnly))
+                let parseOption = allowsFloats ? 0 : CFOptionFlags(kCFNumberFormatterParseIntegersOnly)
             #endif
+            let result = CFNumberFormatterCreateNumberFromString(kCFAllocatorSystemDefault, _cfFormatter, string._cfObject, rangePointer, parseOption)
 
             return result?._nsObject
         }
@@ -157,7 +161,7 @@
         _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterPerMillSymbol, value: _percentSymbol?._cfObject)
         _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterInternationalCurrencySymbol, value: _internationalCurrencySymbol?._cfObject)
         _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencyGroupingSeparator, value: _currencyGroupingSeparator?._cfObject)
-        _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterIsLenient, value: kCFBooleanTrue)
+        _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterIsLenient, value: _lenient._cfObject)
         _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterUseSignificantDigits, value: _usesSignificantDigits._cfObject)
         if _usesSignificantDigits {
             _setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinSignificantDigits, value: _minimumSignificantDigits._bridgeToObjectiveC()._cfObject)
@@ -182,7 +186,7 @@
             switch newValue {
             case .none, .ordinal, .spellOut:
                 _usesSignificantDigits = false
-                
+
             case .currency, .currencyPlural, .currencyISOCode, .currencyAccounting:
                 _usesSignificantDigits = false
                 _usesGroupingSeparator = true
@@ -838,10 +842,10 @@
     
     //
     
-    internal var _format: String = "#;0;#"
+    internal var _format: String?
     open var format: String {
         get {
-            return _format
+            return _format ?? "#;0;#"
         }
         set {
             _reset()
diff --git a/Foundation/NSPredicate.swift b/Foundation/NSPredicate.swift
index 083782b..3aada9c 100644
--- a/Foundation/NSPredicate.swift
+++ b/Foundation/NSPredicate.swift
@@ -15,8 +15,8 @@
     private enum PredicateKind {
         case boolean(Bool)
         case block((Any?, [String : Any]?) -> Bool)
-        // TODO: case for init(format:argumentArray:)
-        // TODO: case for init(fromMetadataQueryString:)
+        case format(String)
+        case metadataQuery(String)
     }
 
     private let kind: PredicateKind
@@ -26,11 +26,33 @@
     }
     
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        guard aDecoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        let encodedBool = aDecoder.decodeBool(forKey: "NS.boolean.value")
+        self.kind = .boolean(encodedBool)
+        
+        super.init()
     }
     
     open func encode(with aCoder: NSCoder) {
-        NSUnimplemented()
+        guard aCoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        //TODO: store kind key for .boolean, .format, .metadataQuery
+        
+        switch self.kind {
+        case .boolean(let value):
+            aCoder.encode(value, forKey: "NS.boolean.value")
+        case .block:
+            preconditionFailure("NSBlockPredicate cannot be encoded or decoded.")
+        case .format:
+            NSUnimplemented()
+        case .metadataQuery:
+            NSUnimplemented()
+        }
     }
     
     open override func copy() -> Any {
@@ -38,7 +60,38 @@
     }
     
     open func copy(with zone: NSZone? = nil) -> Any {
-        NSUnimplemented()
+        switch self.kind {
+        case .boolean(let value):
+            return NSPredicate(value: value)
+        case .block(let block):
+            return NSPredicate(block: block)
+        case .format:
+            NSUnimplemented()
+        case .metadataQuery:
+            NSUnimplemented()
+        }
+    }
+    
+    open override func isEqual(_ object: Any?) -> Bool {
+        if let other = object as? NSPredicate {
+            if other === self {
+                return true
+            } else {
+                switch (other.kind, self.kind) {
+                case (.boolean(let otherBool), .boolean(let selfBool)):
+                    return otherBool == selfBool
+                case (.format, .format):
+                    NSUnimplemented()
+                case (.metadataQuery, .metadataQuery):
+                    NSUnimplemented()
+                default:
+                    // NSBlockPredicate returns false even for copy
+                    return false
+                }
+            }
+        }
+        
+        return false
     }
     
     // Parse predicateFormat and return an appropriate predicate
@@ -58,7 +111,21 @@
         super.init()
     }
     
-    open var predicateFormat: String  { NSUnimplemented() } // returns the format string of the predicate
+    open var predicateFormat: String {
+        switch self.kind {
+        case .boolean(let value):
+            return value ? "TRUEPREDICATE" : "FALSEPREDICATE"
+        case .block:
+            // TODO: Bring NSBlockPredicate's predicateFormat to macOS's Foundation version
+            // let address = unsafeBitCast(block, to: Int.self)
+            // return String(format:"BLOCKPREDICATE(%2X)", address)
+            return "BLOCKPREDICATE"
+        case .format:
+            NSUnimplemented()
+        case .metadataQuery:
+            NSUnimplemented()
+        }
+    }
     
     open func withSubstitutionVariables(_ variables: [String : Any]) -> Self { NSUnimplemented() } // substitute constant values for variables
     
@@ -76,6 +143,10 @@
             return value
         case let .block(block):
             return block(object, bindings)
+        case .format:
+            NSUnimplemented()
+        case .metadataQuery:
+            NSUnimplemented()
         }
     } // single pass evaluation substituting variables from the bindings dictionary for any variable expressions encountered
     
diff --git a/Foundation/NSPropertyList.swift b/Foundation/NSPropertyList.swift
index 7ea248a..5141c42 100644
--- a/Foundation/NSPropertyList.swift
+++ b/Foundation/NSPropertyList.swift
@@ -44,10 +44,11 @@
 #else
         let fmt = CFPropertyListFormat(format.rawValue)
 #endif
-        return CFPropertyListIsValid(unsafeBitCast(_SwiftValue.store(plist), to: CFPropertyList.self), fmt)
+        let plistObj = _SwiftValue.store(plist)
+        return CFPropertyListIsValid(plistObj, fmt)
     }
-    
-    open class func data(fromPropertyList plist: AnyObject, format: PropertyListFormat, options opt: WriteOptions) throws -> Data {
+
+    open class func data(fromPropertyList plist: Any, format: PropertyListFormat, options opt: WriteOptions) throws -> Data {
         var error: Unmanaged<CFError>? = nil
         let result = withUnsafeMutablePointer(to: &error) { (outErr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> CFData? in
 #if os(OSX) || os(iOS)
@@ -56,7 +57,8 @@
             let fmt = CFPropertyListFormat(format.rawValue)
 #endif
             let options = CFOptionFlags(opt)
-            return CFPropertyListCreateData(kCFAllocatorSystemDefault, plist, fmt, options, outErr)
+            let plistObj = _SwiftValue.store(plist)
+            return CFPropertyListCreateData(kCFAllocatorSystemDefault, plistObj, fmt, options, outErr)
         }
         if let res = result {
             return res._swiftObject
@@ -64,7 +66,7 @@
             throw error!.takeRetainedValue()._nsObject
         }
     }
-    
+
     /// - Experiment: Note that the return type of this function is different than on Darwin Foundation (Any instead of AnyObject). This is likely to change once we have a more complete story for bridging in place.
     open class func propertyList(from data: Data, options opt: ReadOptions = [], format: UnsafeMutablePointer<PropertyListFormat>?) throws -> Any {
         var fmt = kCFPropertyListBinaryFormat_v1_0
diff --git a/Foundation/NSURLRequest.swift b/Foundation/NSURLRequest.swift
index 7081e0f..a044297 100644
--- a/Foundation/NSURLRequest.swift
+++ b/Foundation/NSURLRequest.swift
@@ -156,11 +156,101 @@
     }
     
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        guard aDecoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        if let encodedURL = aDecoder.decodeObject(forKey: "NS.url") as? NSURL {
+            self.url = encodedURL._swiftObject
+        }
+        
+        if let encodedHeaders = aDecoder.decodeObject(forKey: "NS._allHTTPHeaderFields") as? NSDictionary {
+            self._allHTTPHeaderFields = encodedHeaders.reduce([String : String]()) { result, item in
+                var result = result
+                if let key = item.key as? NSString,
+                    let value = item.value as? NSString {
+                    result[key._swiftObject] = value._swiftObject
+                }
+                return result
+            }
+        }
+        
+        if let encodedDocumentURL = aDecoder.decodeObject(forKey: "NS.mainDocumentURL") as? NSURL {
+            self.mainDocumentURL = encodedDocumentURL._swiftObject
+        }
+        
+        if let encodedMethod = aDecoder.decodeObject(forKey: "NS.httpMethod") as? NSString {
+            self.httpMethod = encodedMethod._swiftObject
+        }
+        
+        let encodedCachePolicy = aDecoder.decodeObject(forKey: "NS._cachePolicy") as! NSNumber
+        self._cachePolicy = CachePolicy(rawValue: encodedCachePolicy.uintValue)!
+        
+        let encodedTimeout = aDecoder.decodeObject(forKey: "NS._timeoutInterval") as! NSNumber
+        self._timeoutInterval = encodedTimeout.doubleValue
+
+        let encodedHttpBody: Data? = aDecoder.withDecodedUnsafeBufferPointer(forKey: "NS.httpBody") {
+            guard let buffer = $0 else { return nil }
+            return Data(buffer: buffer)
+        }
+        
+        if let encodedHttpBody = encodedHttpBody {
+            self._body = .data(encodedHttpBody)
+        }
+        
+        let encodedNetworkServiceType = aDecoder.decodeObject(forKey: "NS._networkServiceType") as! NSNumber
+        self._networkServiceType = NetworkServiceType(rawValue: encodedNetworkServiceType.uintValue)!
+        
+        let encodedCellularAccess = aDecoder.decodeObject(forKey: "NS._allowsCellularAccess") as! NSNumber
+        self._allowsCellularAccess = encodedCellularAccess.boolValue
+        
+        let encodedHandleCookies = aDecoder.decodeObject(forKey: "NS._httpShouldHandleCookies") as! NSNumber
+        self._httpShouldHandleCookies = encodedHandleCookies.boolValue
+        
+        let encodedUsePipelining = aDecoder.decodeObject(forKey: "NS._httpShouldUsePipelining") as! NSNumber
+        self._httpShouldUsePipelining = encodedUsePipelining.boolValue
     }
     
     open func encode(with aCoder: NSCoder) {
-        NSUnimplemented()
+        guard aCoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        aCoder.encode(self.url?._bridgeToObjectiveC(), forKey: "NS.url")
+        aCoder.encode(self._allHTTPHeaderFields?._bridgeToObjectiveC(), forKey: "NS._allHTTPHeaderFields")
+        aCoder.encode(self.mainDocumentURL?._bridgeToObjectiveC(), forKey: "NS.mainDocumentURL")
+        aCoder.encode(self.httpMethod?._bridgeToObjectiveC(), forKey: "NS.httpMethod")
+        aCoder.encode(self._cachePolicy.rawValue._bridgeToObjectiveC(), forKey: "NS._cachePolicy")
+        aCoder.encode(self._timeoutInterval._bridgeToObjectiveC(), forKey: "NS._timeoutInterval")
+        if let httpBody = self.httpBody?._bridgeToObjectiveC() {
+            let bytePtr = httpBody.bytes.bindMemory(to: UInt8.self, capacity: httpBody.length)
+            aCoder.encodeBytes(bytePtr, length: httpBody.length, forKey: "NS.httpBody")
+        }
+        //On macOS input stream is not encoded.
+        aCoder.encode(self._networkServiceType.rawValue._bridgeToObjectiveC(), forKey: "NS._networkServiceType")
+        aCoder.encode(self._allowsCellularAccess._bridgeToObjectiveC(), forKey: "NS._allowsCellularAccess")
+        aCoder.encode(self._httpShouldHandleCookies._bridgeToObjectiveC(), forKey: "NS._httpShouldHandleCookies")
+        aCoder.encode(self._httpShouldUsePipelining._bridgeToObjectiveC(), forKey: "NS._httpShouldUsePipelining")
+    }
+    
+    open override func isEqual(_ object: Any?) -> Bool {
+        //On macOS this fields do not determine the result:
+        //allHTTPHeaderFields
+        //timeoutInterval
+        //httBody
+        //networkServiceType
+        //httpShouldUsePipelining
+        if let other = object as? NSURLRequest {
+            return other === self
+                || (other.url == self.url
+                    && other.mainDocumentURL == self.mainDocumentURL
+                    && other.httpMethod == self.httpMethod
+                    && other._cachePolicy == self._cachePolicy
+                    && other.httpBodyStream == self.httpBodyStream
+                    && other._allowsCellularAccess == self._allowsCellularAccess
+                    && other._httpShouldHandleCookies == self._httpShouldHandleCookies)
+        }
+        return false
     }
     
     /// Indicates that NSURLRequest implements the NSSecureCoding protocol.
@@ -289,7 +379,7 @@
 /// example.
 open class NSMutableURLRequest : NSURLRequest {
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        super.init(coder: aDecoder)
     }
     
     public convenience init(url: URL) {
diff --git a/Foundation/NSURLResponse.swift b/Foundation/NSURLResponse.swift
index e74f9f1..e39bfcf 100644
--- a/Foundation/NSURLResponse.swift
+++ b/Foundation/NSURLResponse.swift
@@ -23,11 +23,39 @@
     }
     
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        guard aDecoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        if let encodedUrl = aDecoder.decodeObject(forKey: "NS.url") as? NSURL {
+            self.url = encodedUrl._swiftObject
+        }
+        
+        if let encodedMimeType = aDecoder.decodeObject(forKey: "NS.mimeType") as? NSString {
+            self.mimeType = encodedMimeType._swiftObject
+        }
+        
+        self.expectedContentLength = aDecoder.decodeInt64(forKey: "NS.expectedContentLength")
+        
+        if let encodedEncodingName = aDecoder.decodeObject(forKey: "NS.textEncodingName") as? NSString {
+            self.textEncodingName = encodedEncodingName._swiftObject
+        }
+        
+        if let encodedFilename = aDecoder.decodeObject(forKey: "NS.suggestedFilename") as? NSString {
+            self.suggestedFilename = encodedFilename._swiftObject
+        }
     }
     
     open func encode(with aCoder: NSCoder) {
-        NSUnimplemented()
+        guard aCoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        aCoder.encode(self.url?._bridgeToObjectiveC(), forKey: "NS.url")
+        aCoder.encode(self.mimeType?._bridgeToObjectiveC(), forKey: "NS.mimeType")
+        aCoder.encode(self.expectedContentLength, forKey: "NS.expectedContentLength")
+        aCoder.encode(self.textEncodingName?._bridgeToObjectiveC(), forKey: "NS.textEncodingName")
+        aCoder.encode(self.suggestedFilename?._bridgeToObjectiveC(), forKey: "NS.suggestedFilename")
     }
     
     open override func copy() -> Any {
@@ -135,7 +163,27 @@
     }
     
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        guard aDecoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        self.statusCode = aDecoder.decodeInteger(forKey: "NS.statusCode")
+        
+        if let encodedHeaders = aDecoder.decodeObject(forKey: "NS.allHeaderFields") as? NSDictionary {
+            self.allHeaderFields = encodedHeaders._swiftObject
+        } else {
+            self.allHeaderFields = [:]
+        }
+        
+        super.init(coder: aDecoder)
+    }
+    
+    open override func encode(with aCoder: NSCoder) {
+        super.encode(with: aCoder) //Will fail if .allowsKeyedCoding == false
+        
+        aCoder.encode(self.statusCode, forKey: "NS.statusCode")
+        aCoder.encode(self.allHeaderFields._bridgeToObjectiveC(), forKey: "NS.allHeaderFields")
+        
     }
     
     /// The HTTP status code of the receiver.
diff --git a/TestFoundation/TestNSArray.swift b/TestFoundation/TestNSArray.swift
index 132747b..c905e52 100644
--- a/TestFoundation/TestNSArray.swift
+++ b/TestFoundation/TestNSArray.swift
@@ -500,7 +500,7 @@
     }
     
     private func createTestFile(_ path: String, _contents: Data) -> String? {
-        let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().uuidString + "/"
+        let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         do {
             try FileManager.default.createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
             if FileManager.default.createFile(atPath: tempDir + "/" + path, contents: _contents, attributes: nil) {
diff --git a/TestFoundation/TestNSBundle.swift b/TestFoundation/TestNSBundle.swift
index e427992..8e40179 100644
--- a/TestFoundation/TestNSBundle.swift
+++ b/TestFoundation/TestNSBundle.swift
@@ -108,7 +108,7 @@
     
     private func _setupPlayground() -> String? {
         // Make sure the directory is uniquely named
-        let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().uuidString + "/"
+        let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         
         do {
             try FileManager.default.createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
@@ -179,7 +179,7 @@
     }
     
     func test_bundleWithInvalidPath(){
-        let bundleInvalid = Bundle(path: "/tmp/test.playground")
+        let bundleInvalid = Bundle(path: NSTemporaryDirectory() + "test.playground")
         XCTAssertNil(bundleInvalid)
     }
     
diff --git a/TestFoundation/TestNSDictionary.swift b/TestFoundation/TestNSDictionary.swift
index 002a119..ff415ef 100644
--- a/TestFoundation/TestNSDictionary.swift
+++ b/TestFoundation/TestNSDictionary.swift
@@ -205,7 +205,7 @@
     }
 
     private func createTestFile(_ path: String, _contents: Data) -> String? {
-        let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().uuidString + "/"
+        let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         do {
             try FileManager.default.createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
             if FileManager.default.createFile(atPath: tempDir + "/" + path, contents: _contents,
diff --git a/TestFoundation/TestNSFileHandle.swift b/TestFoundation/TestNSFileHandle.swift
old mode 100644
new mode 100755
index 69a74cc..93357ff
--- a/TestFoundation/TestNSFileHandle.swift
+++ b/TestFoundation/TestNSFileHandle.swift
@@ -19,6 +19,7 @@
     static var allTests : [(String, (TestNSFileHandle) -> () throws -> ())] {
         return [
                    ("test_pipe", test_pipe),
+                   ("test_nullDevice", test_nullDevice),
         ]
     }
 
@@ -38,4 +39,23 @@
             XCTAssertEqual(output, input)
         }
     }
+
+    func test_nullDevice() {
+        let fh = FileHandle.nullDevice
+
+        XCTAssertEqual(fh.fileDescriptor, -1)
+        fh.closeFile()
+        fh.seek(toFileOffset: 10)
+        XCTAssertEqual(fh.offsetInFile, 0)
+        XCTAssertEqual(fh.seekToEndOfFile(), 0)
+        XCTAssertEqual(fh.readData(ofLength: 15).count, 0)
+        fh.synchronizeFile()
+
+        fh.write(Data(bytes: [1,2]))
+        fh.seek(toFileOffset: 0)
+        XCTAssertEqual(fh.availableData.count, 0)
+        fh.write(Data(bytes: [1,2]))
+        fh.seek(toFileOffset: 0)
+        XCTAssertEqual(fh.readDataToEndOfFile().count, 0)
+    }
 }
diff --git a/TestFoundation/TestNSFileManager.swift b/TestFoundation/TestNSFileManager.swift
index b0c9afd..1bdffd3 100644
--- a/TestFoundation/TestNSFileManager.swift
+++ b/TestFoundation/TestNSFileManager.swift
@@ -38,7 +38,7 @@
     
     func test_createDirectory() {
         let fm = FileManager.default
-        let path = "/tmp/testdir\(NSUUID().uuidString)"
+        let path = NSTemporaryDirectory() + "testdir\(NSUUID().uuidString)"
         
         ignoreError { try fm.removeItem(atPath: path) }
         
@@ -63,7 +63,7 @@
     
     func test_createFile() {
         let fm = FileManager.default
-        let path = "/tmp/testfile\(NSUUID().uuidString)"
+        let path = NSTemporaryDirectory() + "testfile\(NSUUID().uuidString)"
         
         ignoreError { try fm.removeItem(atPath: path) }
         
@@ -83,8 +83,8 @@
 
     func test_moveFile() {
         let fm = FileManager.default
-        let path = "/tmp/testfile\(NSUUID().uuidString)"
-        let path2 = "/tmp/testfile2\(NSUUID().uuidString)"
+        let path = NSTemporaryDirectory() + "testfile\(NSUUID().uuidString)"
+        let path2 = NSTemporaryDirectory() + "testfile2\(NSUUID().uuidString)"
 
         func cleanup() {
             ignoreError { try fm.removeItem(atPath: path) }
@@ -114,7 +114,7 @@
     
     func test_fileAttributes() {
         let fm = FileManager.default
-        let path = "/tmp/test_fileAttributes\(NSUUID().uuidString)"
+        let path = NSTemporaryDirectory() + "test_fileAttributes\(NSUUID().uuidString)"
 
         ignoreError { try fm.removeItem(atPath: path) }
         
@@ -161,7 +161,7 @@
     }
     
     func test_setFileAttributes() {
-        let path = "/tmp/test_setFileAttributes\(NSUUID().uuidString)"
+        let path = NSTemporaryDirectory() + "test_setFileAttributes\(NSUUID().uuidString)"
         let fm = FileManager.default
         
         ignoreError { try fm.removeItem(atPath: path) }
@@ -189,10 +189,10 @@
     func test_pathEnumerator() {
         let fm = FileManager.default
         let testDirName = "testdir\(NSUUID().uuidString)"
-        let basePath = "/tmp/\(testDirName)"
-        let itemPath = "/tmp/\(testDirName)/item"
-        let basePath2 = "/tmp/\(testDirName)/path2"
-        let itemPath2 = "/tmp/\(testDirName)/path2/item"
+        let basePath = NSTemporaryDirectory() + "\(testDirName)"
+        let itemPath = NSTemporaryDirectory() + "\(testDirName)/item"
+        let basePath2 = NSTemporaryDirectory() + "\(testDirName)/path2"
+        let itemPath2 = NSTemporaryDirectory() + "\(testDirName)/path2/item"
         
         ignoreError { try fm.removeItem(atPath: basePath) }
         
@@ -222,8 +222,8 @@
     func test_directoryEnumerator() {
         let fm = FileManager.default
         let testDirName = "testdir\(NSUUID().uuidString)"
-        let path = "/tmp/\(testDirName)"
-        let itemPath = "/tmp/\(testDirName)/item"
+        let path = NSTemporaryDirectory() + "\(testDirName)"
+        let itemPath = NSTemporaryDirectory() + "\(testDirName)/item"
         
         ignoreError { try fm.removeItem(atPath: path) }
         
@@ -244,8 +244,8 @@
             XCTFail()
         }
         
-        let subDirPath = "/tmp/\(testDirName)/testdir2"
-        let subDirItemPath = "/tmp/\(testDirName)/testdir2/item"
+        let subDirPath = NSTemporaryDirectory() + "\(testDirName)/testdir2"
+        let subDirItemPath = NSTemporaryDirectory() + "\(testDirName)/testdir2/item"
         do {
             try fm.createDirectory(atPath: subDirPath, withIntermediateDirectories: false, attributes: nil)
             let _ = fm.createFile(atPath: subDirItemPath, contents: Data(), attributes: nil)
@@ -320,9 +320,9 @@
     func test_contentsOfDirectoryAtPath() {
         let fm = FileManager.default
         let testDirName = "testdir\(NSUUID().uuidString)"
-        let path = "/tmp/\(testDirName)"
-        let itemPath1 = "/tmp/\(testDirName)/item"
-        let itemPath2 = "/tmp/\(testDirName)/item2"
+        let path = NSTemporaryDirectory() + "\(testDirName)"
+        let itemPath1 = NSTemporaryDirectory() + "\(testDirName)/item"
+        let itemPath2 = NSTemporaryDirectory() + "\(testDirName)/item2"
         
         ignoreError { try fm.removeItem(atPath: path) }
         
@@ -363,11 +363,11 @@
     
     func test_subpathsOfDirectoryAtPath() {
         let fm = FileManager.default
-        let path = "/tmp/testdir"
-        let path2 = "/tmp/testdir/sub"
-        let itemPath1 = "/tmp/testdir/item"
-        let itemPath2 = "/tmp/testdir/item2"
-        let itemPath3 = "/tmp/testdir/sub/item3"
+        let path = NSTemporaryDirectory() + "testdir"
+        let path2 = NSTemporaryDirectory() + "testdir/sub"
+        let itemPath1 = NSTemporaryDirectory() + "testdir/item"
+        let itemPath2 = NSTemporaryDirectory() + "testdir/item2"
+        let itemPath3 = NSTemporaryDirectory() + "testdir/sub/item3"
                 
         ignoreError { try fm.removeItem(atPath: path) }
         
diff --git a/TestFoundation/TestNSJSONSerialization.swift b/TestFoundation/TestNSJSONSerialization.swift
index d40a1c0..3ce12e8 100644
--- a/TestFoundation/TestNSJSONSerialization.swift
+++ b/TestFoundation/TestNSJSONSerialization.swift
@@ -777,7 +777,7 @@
         
         // Cannot generate "true"/"false" currently
         json = [NSNumber(value:false),NSNumber(value:true)]
-        XCTAssertEqual(try trySerialize(json), "[0,1]")
+        XCTAssertEqual(try trySerialize(json), "[false,true]")
     }
     
     func test_serialize_stringEscaping() {
@@ -931,16 +931,18 @@
     
     func test_booleanJSONObject() {
         do {
-            let mydata = try JSONSerialization.data(withJSONObject: [true])
-            XCTAssertEqual(String(data: mydata, encoding: String.Encoding.utf8), "[1]")
+            let objectLikeBoolArray = try JSONSerialization.data(withJSONObject: [true, NSNumber(value: false), NSNumber(value: true)] as Array<Any>)
+            XCTAssertEqual(String(data: objectLikeBoolArray, encoding: .utf8), "[true,false,true]")
+            let valueLikeBoolArray = try JSONSerialization.data(withJSONObject: [false, true, false])
+            XCTAssertEqual(String(data: valueLikeBoolArray, encoding: .utf8), "[false,true,false]")
         } catch {
             XCTFail("Failed during serialization")
         }
-        XCTAssertTrue(JSONSerialization.isValidJSONObject([1]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([true]))
     }
 
     private func createTestFile(_ path: String,_contents: Data) -> String? {
-        let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().uuidString + "/"
+        let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         do {
             try FileManager.default.createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
             if FileManager.default.createFile(atPath: tempDir + "/" + path, contents: _contents,
diff --git a/TestFoundation/TestNSLocale.swift b/TestFoundation/TestNSLocale.swift
index 3d18791..f83edf3 100644
--- a/TestFoundation/TestNSLocale.swift
+++ b/TestFoundation/TestNSLocale.swift
@@ -19,9 +19,24 @@
     static var allTests: [(String, (TestNSLocale) -> () throws -> Void)] {
         return [
             ("test_constants", test_constants),
+            ("test_Identifier", test_Identifier),
             ("test_copy", test_copy)
         ]
     }
+
+    func test_Identifier() {
+        // Current locale identifier should not be empty
+        // Or things like NSNumberFormatter spellOut style won't work
+        XCTAssertFalse(Locale.current.identifier.isEmpty)
+
+        let enUSID = "en_US"
+        let locale = Locale(identifier: enUSID)
+        XCTAssertEqual(enUSID, locale.identifier)
+
+        let deDEID = "de_DE"
+        let germanLocale = Locale(identifier: deDEID)
+        XCTAssertEqual(deDEID, germanLocale.identifier)
+    }
     
     func test_constants() {
         XCTAssertEqual(NSCurrentLocaleDidChangeNotification, "kCFLocaleCurrentLocaleDidChangeNotification",
diff --git a/TestFoundation/TestNSNumberFormatter.swift b/TestFoundation/TestNSNumberFormatter.swift
index 9511770..222b3d2 100644
--- a/TestFoundation/TestNSNumberFormatter.swift
+++ b/TestFoundation/TestNSNumberFormatter.swift
@@ -53,7 +53,9 @@
             ("test_lenient", test_lenient),
             ("test_minimumSignificantDigits", test_minimumSignificantDigits),
             ("test_maximumSignificantDigits", test_maximumSignificantDigits),
-            ("test_stringFor", test_stringFor)
+            ("test_stringFor", test_stringFor),
+            ("test_numberFrom", test_numberFrom),
+            //("test_en_US_initialValues", test_en_US_initialValues)
         ]
     }
     
@@ -68,11 +70,15 @@
         XCTAssertEqual(formattedString, "T 42_00")
          */
     }
-    
+
     func test_decimalSeparator() {
         let numberFormatter = NumberFormatter()
         numberFormatter.numberStyle = .decimal
-        numberFormatter.decimalSeparator = "-"
+
+        let separator = "-"
+        numberFormatter.decimalSeparator = separator
+        XCTAssertEqual(numberFormatter.decimalSeparator, separator)
+
         let formattedString = numberFormatter.string(from: 42.42)
         XCTAssertEqual(formattedString, "42-42")
     }
@@ -147,14 +153,28 @@
     }
     
     func test_plusSignSymbol() {
-        //FIXME: How do we show the plus sign from a NSNumberFormatter?
+        // ex. 1.0E+1 in scientific notation
+        let numberFormatter = NumberFormatter()
+        let format = "#E+0"
+        numberFormatter.format = format
+        XCTAssertEqual(numberFormatter.format, format)
 
-//        let numberFormatter = NumberFormatter()
-//        numberFormatter.plusSign = "πŸ‘"
-//        let formattedString = numberFormatter.stringFromNumber(42)
-//        XCTAssertEqual(formattedString, "πŸ‘42")
+        let sign = "πŸ‘"
+        numberFormatter.plusSign = sign
+        XCTAssertEqual(numberFormatter.plusSign, sign)
+
+        let formattedString = numberFormatter.string(from: 420000000000000000)
+        XCTAssertNotNil(formattedString)
+        XCTAssertEqual(formattedString, "4.2EπŸ‘17")
+
+        // Verify a negative exponent does not have the πŸ‘
+        let noPlusString = numberFormatter.string(from: -0.420)
+        XCTAssertNotNil(noPlusString)
+        if let fmt = noPlusString {
+            XCTAssertFalse(fmt.contains(sign), "Expected format of -0.420 (-4.2E-1) shouldn't have a plus sign which was set as \(sign)")
+        }
     }
-    
+
     func test_currencySymbol() {
         // Disabled due to [SR-250]
         /*
@@ -316,14 +336,30 @@
         */
     }
 
-    //FIXME: Something is wrong with numberFromString implementation, I don't know exactly why, but it's not working.
     func test_lenient() {
-//        let numberFormatter = NumberFormatter()
-//        numberFormatter.numberStyle = .CurrencyStyle
-//        let nilNumberBeforeLenient = numberFormatter.numberFromString("42")
+        let numberFormatter = NumberFormatter()
+        // Not lenient by default
+        XCTAssertFalse(numberFormatter.isLenient)
+
+        // Lenient allows wrong style -- not lenient here
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.numberStyle, .spellOut)
+//        let nilNumber = numberFormatter.number(from: "2.22")
+        // FIXME: Not nil on Linux?
+        //XCTAssertNil(nilNumber)
+        // Lenient allows wrong style
+        numberFormatter.isLenient = true
+        XCTAssertTrue(numberFormatter.isLenient)
+        let number = numberFormatter.number(from: "2.22")
+        XCTAssertEqual(number, 2.22)
+
+        // TODO: Add some tests with currency after [SR-250] resolved
+//        numberFormatter.numberStyle = .currency
+//        let nilNumberBeforeLenient = numberFormatter.number(from: "42")
+//
 //        XCTAssertNil(nilNumberBeforeLenient)
-//        numberFormatter.lenient = true
-//        let numberAfterLenient = numberFormatter.numberFromString("42.42")
+//        numberFormatter.isLenient = true
+//        let numberAfterLenient = numberFormatter.number(from: "42.42")
 //        XCTAssertEqual(numberAfterLenient, 42.42)
     }
     
@@ -353,7 +389,76 @@
         XCTAssertEqual(numberFormatter.string(for: NSNumber(value: 99.1))!, "99")
         XCTAssertNil(numberFormatter.string(for: "NaN"))
         XCTAssertNil(numberFormatter.string(for: NSString(string: "NaN")))
+
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.string(for: 234), "two hundred thirty-four")
+        XCTAssertEqual(numberFormatter.string(for: 2007), "two thousand seven")
+        XCTAssertEqual(numberFormatter.string(for: 3), "three")
+        XCTAssertEqual(numberFormatter.string(for: 0.3), "zero point three")
+
+        numberFormatter.locale = Locale(identifier: "zh_CN")
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.string(from: 11.4), "十一点四")
+
+        numberFormatter.locale = Locale(identifier: "fr_FR")
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.string(from: 11.4), "onze virgule quatre")
+
     }
-  
+
+    func test_numberFrom() {
+        let numberFormatter = NumberFormatter()
+        XCTAssertEqual(numberFormatter.number(from: "10"), 10)
+        XCTAssertEqual(numberFormatter.number(from: "3.14"), 3.14)
+        XCTAssertEqual(numberFormatter.number(from: "0.01"), 0.01)
+        XCTAssertEqual(numberFormatter.number(from: ".01"), 0.01)
+
+        // These don't work unless lenient/style set
+        numberFormatter.numberStyle = .decimal
+        XCTAssertEqual(numberFormatter.number(from: "1,001"), 1001)
+        XCTAssertEqual(numberFormatter.number(from: "1,050,001"), 1050001)
+
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.number(from: "two thousand and seven"), 2007)
+        XCTAssertEqual(numberFormatter.number(from: "one point zero"), 1.0)
+        XCTAssertEqual(numberFormatter.number(from: "one hundred million"), 1E8)
+
+        numberFormatter.locale = Locale(identifier: "zh_CN")
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.number(from: "十一点四"), 11.4)
+
+        numberFormatter.locale = Locale(identifier: "fr_FR")
+        numberFormatter.numberStyle = .spellOut
+        XCTAssertEqual(numberFormatter.number(from: "onze virgule quatre"), 11.4)
+    }
+
+    func test_en_US_initialValues() {
+        // Symbols should be extractable
+        // At one point, none of this passed!
+
+        let numberFormatter = NumberFormatter();
+        numberFormatter.locale = Locale(identifier: "en_US")
+
+        // TODO: Check if this is true for all versions...
+        XCTAssertEqual(numberFormatter.format, "#;0;#")
+
+        XCTAssertEqual(numberFormatter.plusSign, "+")
+        XCTAssertEqual(numberFormatter.minusSign, "-")
+        XCTAssertEqual(numberFormatter.decimalSeparator, ".")
+        XCTAssertEqual(numberFormatter.groupingSeparator, ",")
+        XCTAssertEqual(numberFormatter.nilSymbol, "")
+        XCTAssertEqual(numberFormatter.notANumberSymbol, "NaN")
+        XCTAssertEqual(numberFormatter.positiveInfinitySymbol, "+∞")
+        XCTAssertEqual(numberFormatter.negativeInfinitySymbol, "-∞")
+        XCTAssertEqual(numberFormatter.positivePrefix, "")
+        XCTAssertEqual(numberFormatter.negativePrefix, "-")
+        XCTAssertEqual(numberFormatter.positiveSuffix, "")
+        XCTAssertEqual(numberFormatter.negativeSuffix, "")
+        XCTAssertEqual(numberFormatter.percentSymbol, "%")
+        XCTAssertEqual(numberFormatter.perMillSymbol, "‰")
+        XCTAssertEqual(numberFormatter.exponentSymbol, "E")
+        XCTAssertEqual(numberFormatter.groupingSeparator, ",")
+        XCTAssertEqual(numberFormatter.paddingCharacter, "*")
+    }
 }
 
diff --git a/TestFoundation/TestNSPredicate.swift b/TestFoundation/TestNSPredicate.swift
index 4275d9a..641d605 100644
--- a/TestFoundation/TestNSPredicate.swift
+++ b/TestFoundation/TestNSPredicate.swift
@@ -27,6 +27,8 @@
             ("test_filterNSMutableSet", test_filterNSMutableSet),
             ("test_filterNSOrderedSet", test_filterNSOrderedSet),
             ("test_filterNSMutableOrderedSet", test_filterNSMutableOrderedSet),
+            ("test_NSCoding", test_NSCoding),
+            ("test_copy", test_copy),
         ]
     }
 
@@ -94,4 +96,15 @@
         expectedOrderedSet.addObjects(from: expectedArray)
         XCTAssertEqual(expectedOrderedSet, orderedSet)
     }
+    
+    func test_NSCoding() {
+        let predicateA = NSPredicate(value: true)
+        let predicateB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: predicateA)) as! NSPredicate
+        XCTAssertEqual(predicateA, predicateB, "Archived then unarchived uuid must be equal.")
+    }
+    
+    func test_copy() {
+        let predicate = NSPredicate(value: true)
+        XCTAssert(predicate.isEqual(predicate.copy()))
+    }
 }
diff --git a/TestFoundation/TestNSStream.swift b/TestFoundation/TestNSStream.swift
index f2daf43..8bb4c5c 100644
--- a/TestFoundation/TestNSStream.swift
+++ b/TestFoundation/TestNSStream.swift
@@ -118,7 +118,7 @@
     }
     
     func test_InputStreamInvalidPath() {
-        let fileStream: InputStream = InputStream(fileAtPath: "/tmp/file.txt")!
+        let fileStream: InputStream = InputStream(fileAtPath: NSTemporaryDirectory() + "file.txt")!
         XCTAssertEqual(Stream.Status.notOpen, fileStream.streamStatus)
         fileStream.open()
         XCTAssertEqual(Stream.Status.error, fileStream.streamStatus)
@@ -217,7 +217,7 @@
     }
     
     private func createTestFile(_ path: String, _contents: Data) -> String? {
-        let tempDir = "/tmp/TestFoundation_Playground_" + NSUUID().uuidString + "/"
+        let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         do {
             try FileManager.default.createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
             if FileManager.default.createFile(atPath: tempDir + "/" + path, contents: _contents,
diff --git a/TestFoundation/TestNSString.swift b/TestFoundation/TestNSString.swift
index ebb8fab..362e075 100644
--- a/TestFoundation/TestNSString.swift
+++ b/TestFoundation/TestNSString.swift
@@ -419,11 +419,11 @@
     
     func test_completePathIntoString() {
         let fileNames = [
-            "/tmp/Test_completePathIntoString_01",
-            "/tmp/test_completePathIntoString_02",
-            "/tmp/test_completePathIntoString_01.txt",
-            "/tmp/test_completePathIntoString_01.dat",
-            "/tmp/test_completePathIntoString_03.DAT"
+            NSTemporaryDirectory() + "Test_completePathIntoString_01",
+            NSTemporaryDirectory() + "test_completePathIntoString_02",
+            NSTemporaryDirectory() + "test_completePathIntoString_01.txt",
+            NSTemporaryDirectory() + "test_completePathIntoString_01.dat",
+            NSTemporaryDirectory() + "test_completePathIntoString_03.DAT"
         ]
         
         guard ensureFiles(fileNames) else {
@@ -432,7 +432,7 @@
         }
 
         let tmpPath = { (path: String) -> String in
-            return "/tmp/\(path)"
+            return NSTemporaryDirectory() + "\(path)"
         }
 
         do {
@@ -463,9 +463,9 @@
         }
         
         let fileNames2 = [
-            "/tmp/ABC/",
-            "/tmp/ABCD/",
-            "/tmp/abcde"
+            NSTemporaryDirectory() + "ABC/",
+            NSTemporaryDirectory() + "ABCD/",
+            NSTemporaryDirectory() + "abcde"
         ]
         
         guard ensureFiles(fileNames2) else {
@@ -571,7 +571,7 @@
         
         // Next check has no sense on Linux due to case sensitive file system.
         #if os(OSX)
-        guard ensureFiles(["/tmp/ABC/temp.txt"]) else {
+        guard ensureFiles([NSTemporaryDirectory() + "ABC/temp.txt"]) else {
             XCTAssert(false, "Could not create temp files for testing.")
             return
         }
diff --git a/TestFoundation/TestNSURL.swift b/TestFoundation/TestNSURL.swift
index 87409b5..b174390 100644
--- a/TestFoundation/TestNSURL.swift
+++ b/TestFoundation/TestNSURL.swift
@@ -352,7 +352,7 @@
     
     func test_URLByResolvingSymlinksInPath() {
         let files = [
-            "/tmp/ABC/test_URLByResolvingSymlinksInPath"
+            NSTemporaryDirectory() + "ABC/test_URLByResolvingSymlinksInPath"
         ]
         
         guard ensureFiles(files) else {
diff --git a/TestFoundation/TestNSURLRequest.swift b/TestFoundation/TestNSURLRequest.swift
index 5dde4ef..b9b0353 100644
--- a/TestFoundation/TestNSURLRequest.swift
+++ b/TestFoundation/TestNSURLRequest.swift
@@ -27,6 +27,9 @@
             ("test_mutableCopy_1", test_mutableCopy_1),
             ("test_mutableCopy_2", test_mutableCopy_2),
             ("test_mutableCopy_3", test_mutableCopy_3),
+            ("test_NSCoding_1", test_NSCoding_1),
+            ("test_NSCoding_2", test_NSCoding_2),
+            ("test_NSCoding_3", test_NSCoding_3)
         ]
     }
     
@@ -203,4 +206,38 @@
         XCTAssertEqual(originalRequest.url, urlA)
         XCTAssertNil(originalRequest.allHTTPHeaderFields)
     }
+    
+    func test_NSCoding_1() {
+        let url = URL(string: "https://apple.com")!
+        let requestA = NSURLRequest(url: url)
+        let requestB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: requestA)) as! NSURLRequest
+        XCTAssertEqual(requestA, requestB, "Archived then unarchived url request must be equal.")
+    }
+    
+    func test_NSCoding_2() {
+        let url = URL(string: "https://apple.com")!
+        let requestA = NSMutableURLRequest(url: url)
+        //Also checks crash on NSData.bytes
+        requestA.httpBody = Data()
+        let requestB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: requestA)) as! NSURLRequest
+        XCTAssertEqual(requestA, requestB, "Archived then unarchived url request must be equal.")
+        //Check `.httpBody` as it is not checked in `isEqual(_:)`
+        XCTAssertEqual(requestB.httpBody, requestA.httpBody)
+    }
+    
+    func test_NSCoding_3() {
+        let url = URL(string: "https://apple.com")!
+        let urlForDocument = URL(string: "http://ibm.com")!
+        
+        let requestA = NSMutableURLRequest(url: url)
+        requestA.mainDocumentURL = urlForDocument
+        //Also checks crash on NSData.bytes
+        requestA.httpBody = Data(bytes: [1, 2, 3])
+        let requestB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: requestA)) as! NSURLRequest
+        XCTAssertEqual(requestA, requestB, "Archived then unarchived url request must be equal.")
+        //Check `.httpBody` as it is not checked in `isEqual(_:)`
+        XCTAssertNotNil(requestB.httpBody)
+        XCTAssertEqual(3, requestB.httpBody!.count)
+        XCTAssertEqual(requestB.httpBody, requestA.httpBody)
+    }
 }
diff --git a/TestFoundation/TestNSURLResponse.swift b/TestFoundation/TestNSURLResponse.swift
index 9e67ffa..dfece22 100644
--- a/TestFoundation/TestNSURLResponse.swift
+++ b/TestFoundation/TestNSURLResponse.swift
@@ -29,6 +29,7 @@
             ("test_suggestedFilename_2", test_suggestedFilename_2),
             ("test_suggestedFilename_3", test_suggestedFilename_3),
             ("test_copywithzone", test_copyWithZone),
+            ("test_NSCoding", test_NSCoding),
         ]
     }
     
@@ -91,6 +92,19 @@
         let res = URLResponse(url: url, mimeType: "txt", expectedContentLength: 0, textEncodingName: nil)
         XCTAssertTrue(res.isEqual(res.copy() as! NSObject))
     }
+    
+    func test_NSCoding() {
+        let url = URL(string: "https://apple.com")!
+        let responseA = URLResponse(url: url, mimeType: "txt", expectedContentLength: 0, textEncodingName: nil)
+        let responseB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: responseA)) as! URLResponse
+        
+        //On macOS unarchived Archived then unarchived `URLResponse` is not equal.
+        XCTAssertEqual(responseA.url, responseB.url, "Archived then unarchived url response must be equal.")
+        XCTAssertEqual(responseA.mimeType, responseB.mimeType, "Archived then unarchived url response must be equal.")
+        XCTAssertEqual(responseA.expectedContentLength, responseB.expectedContentLength, "Archived then unarchived url response must be equal.")
+        XCTAssertEqual(responseA.textEncodingName, responseB.textEncodingName, "Archived then unarchived url response must be equal.")
+        XCTAssertEqual(responseA.suggestedFilename, responseB.suggestedFilename, "Archived then unarchived url response must be equal.")
+    }
 }
 
 
@@ -127,6 +141,8 @@
                    ("test_MIMETypeAndCharacterEncoding_1", test_MIMETypeAndCharacterEncoding_1),
                    ("test_MIMETypeAndCharacterEncoding_2", test_MIMETypeAndCharacterEncoding_2),
                    ("test_MIMETypeAndCharacterEncoding_3", test_MIMETypeAndCharacterEncoding_3),
+                   
+                   ("test_NSCoding", test_NSCoding),
         ]
     }
     
@@ -292,4 +308,28 @@
         XCTAssertEqual(sut?.mimeType, "text/html")
         XCTAssertEqual(sut?.textEncodingName, "iso-8859-4")
     }
+    
+    // NSCoding
+    
+    func test_NSCoding() {
+        let url = URL(string: "https://apple.com")!
+        let f = ["Content-Type": "text/HTML; charset=ISO-8859-4"]
+        
+        let responseA = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: f)!
+        let responseB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: responseA)) as! HTTPURLResponse
+        
+        //On macOS unarchived Archived then unarchived `URLResponse` is not equal.
+        XCTAssertEqual(responseA.statusCode, responseB.statusCode, "Archived then unarchived http url response must be equal.")
+        XCTAssertEqual(Array(responseA.allHeaderFields.keys), Array(responseB.allHeaderFields.keys), "Archived then unarchived http url response must be equal.")
+        
+        for key in responseA.allHeaderFields.keys {
+            XCTAssertEqual(responseA.allHeaderFields[key] as? String, responseB.allHeaderFields[key] as? String, "Archived then unarchived http url response must be equal.")
+        }
+        
+        XCTAssertEqual(responseA.url, responseB.url, "Archived then unarchived http url response must be equal.")
+        XCTAssertEqual(responseA.mimeType, responseB.mimeType, "Archived then unarchived http url response must be equal.")
+        XCTAssertEqual(responseA.expectedContentLength, responseB.expectedContentLength, "Archived then unarchived http url response must be equal.")
+        XCTAssertEqual(responseA.textEncodingName, responseB.textEncodingName, "Archived then unarchived http url response must be equal.")
+        XCTAssertEqual(responseA.suggestedFilename, responseB.suggestedFilename, "Archived then unarchived http url response must be equal.")
+    }
 }