Merge pull request #708 from naithar/URLCredentials-NSCoding

diff --git a/Docs/Status.md b/Docs/Status.md
index de77b21..6c0eb68 100644
--- a/Docs/Status.md
+++ b/Docs/Status.md
@@ -47,7 +47,7 @@
     |------------------------------|-----------------|---------------|--------------------------------------------------------------------------------------------------------------------|
     | `URLAuthenticationChallenge` | Unimplemented   | None          |                                                                                                                    |
     | `URLCache`                   | Unimplemented   | None          |                                                                                                                    |
-    | `URLCredential`              | Mostly Complete | Incomplete    | `NSCoding` and `NSCopying` remain unimplemented                                                                    |
+    | `URLCredential`              | Mostly Complete | Incomplete    | `NSCopying` remains unimplemented                                                                                  |
     | `URLCredentialStorage`       | Unimplemented   | None          |                                                                                                                    |
     | `NSURLError*`                | Complete        | N/A           |                                                                                                                    |
     | `URLProtectionSpace`         | Unimplemented   | None          |                                                                                                                    |
diff --git a/Foundation/NSURLCredential.swift b/Foundation/NSURLCredential.swift
index 300126a..32cd075 100644
--- a/Foundation/NSURLCredential.swift
+++ b/Foundation/NSURLCredential.swift
@@ -65,11 +65,32 @@
      */
     
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        guard aDecoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        func bridgeString(_ value: NSString) -> String? {
+            return String._unconditionallyBridgeFromObjectiveC(value)
+        }
+        
+        let encodedUser = aDecoder.decodeObject(forKey: "NS._user") as! NSString
+        self._user = bridgeString(encodedUser)!
+        
+        let encodedPassword = aDecoder.decodeObject(forKey: "NS._password") as! NSString
+        self._password = bridgeString(encodedPassword)!
+        
+        let encodedPersistence = aDecoder.decodeObject(forKey: "NS._persistence") as! NSNumber
+        self._persistence = Persistence(rawValue: encodedPersistence.uintValue)!
     }
     
     open func encode(with aCoder: NSCoder) {
-        NSUnimplemented()
+        guard aCoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        aCoder.encode(self._user._bridgeToObjectiveC(), forKey: "NS._user")
+        aCoder.encode(self._password._bridgeToObjectiveC(), forKey: "NS._password")
+        aCoder.encode(self._persistence.rawValue._bridgeToObjectiveC(), forKey: "NS._persistence")
     }
     
     static public var supportsSecureCoding: Bool {
@@ -84,6 +105,17 @@
         return self 
     }
     
+    open override func isEqual(_ object: Any?) -> Bool {
+        if let other = object as? URLCredential {
+            return other === self
+                || (other._user == self._user
+                    && other._password == self._password
+                    && other._persistence == self._persistence)
+        }
+        
+        return false
+    }
+    
     /*!
         @method persistence
         @abstract Determine whether this credential is or should be stored persistently
diff --git a/TestFoundation/TestNSURLCredential.swift b/TestFoundation/TestNSURLCredential.swift
index 542c857..037b114 100644
--- a/TestFoundation/TestNSURLCredential.swift
+++ b/TestFoundation/TestNSURLCredential.swift
@@ -21,7 +21,8 @@
     static var allTests: [(String, (TestNSURLCredential) -> () throws -> Void)] {
         return [
                    ("test_construction", test_construction),
-                   ("test_copy", test_copy)
+                   ("test_copy", test_copy),
+                   ("test_NSCoding", test_NSCoding)
         ]
     }
     
@@ -39,4 +40,10 @@
         let copy = credential.copy() as! URLCredential
         XCTAssertTrue(copy.isEqual(credential))
     }
+    
+    func test_NSCoding() {
+        let credentialA = URLCredential(user: "swiftUser", password: "swiftPassword", persistence: .forSession)
+        let credentialB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: credentialA)) as! URLCredential
+        XCTAssertEqual(credentialA, credentialB, "Archived then unarchived url credential must be equal.")
+    }
 }