                 return
         }
 
-        XCTAssertFalse(token1.isInKeychain, "Token should not be in keychain: \(token1)");
-        XCTAssertFalse(token2.isInKeychain, "Token should not be in keychain: \(token2)");
-
-        XCTAssertTrue(token1.saveToKeychain(), "Failed to save to keychain: \(token1)");
-
-        XCTAssertTrue(token1.isInKeychain, "Token should be in keychain: \(token1)");
-        XCTAssertFalse(token2.isInKeychain, "Token should not be in keychain: \(token2)");
-
-        XCTAssertTrue(token2.saveToKeychain(), "Failed to save to keychain: \(token2)");
-
-        XCTAssertTrue(token1.isInKeychain, "Token should be in keychain: \(token1)");
-        XCTAssertTrue(token2.isInKeychain, "Token should be in keychain: \(token2)");
-
-        XCTAssertTrue(token1.removeFromKeychain(), "Failed to remove from keychain: \(token1)");
-
-        XCTAssertFalse(token1.isInKeychain, "Token should not be in keychain: \(token1)");
-        XCTAssertTrue(token2.isInKeychain, "Token should be in keychain: \(token2)");
-
-        XCTAssertTrue(token2.removeFromKeychain(), "Failed to remove from keychain: \(token2)");
-
-        XCTAssertFalse(token1.isInKeychain, "Token should not be in keychain: \(token1)");
-        XCTAssertFalse(token2.isInKeychain, "Token should not be in keychain: \(token2)");
-
-        XCTAssertFalse(token1.removeFromKeychain(), "Removing again should fail: \(token1)");
-        XCTAssertFalse(token2.removeFromKeychain(), "Removing again should fail: \(token2)");
+        XCTAssertFalse(token1.isInKeychain, "Token should not be in keychain: \(token1)")
+        XCTAssertFalse(token2.isInKeychain, "Token should not be in keychain: \(token2)")
+
+        XCTAssertTrue(token1.saveToKeychain(), "Failed to save to keychain: \(token1)")
+
+        XCTAssertTrue(token1.isInKeychain, "Token should be in keychain: \(token1)")
+        XCTAssertFalse(token2.isInKeychain, "Token should not be in keychain: \(token2)")
+
+        XCTAssertTrue(token2.saveToKeychain(), "Failed to save to keychain: \(token2)")
+
+        XCTAssertTrue(token1.isInKeychain, "Token should be in keychain: \(token1)")
+        XCTAssertTrue(token2.isInKeychain, "Token should be in keychain: \(token2)")
+
+        XCTAssertTrue(token1.removeFromKeychain(), "Failed to remove from keychain: \(token1)")
+
+        XCTAssertFalse(token1.isInKeychain, "Token should not be in keychain: \(token1)")
+        XCTAssertTrue(token2.isInKeychain, "Token should be in keychain: \(token2)")
+
+        XCTAssertTrue(token2.removeFromKeychain(), "Failed to remove from keychain: \(token2)")
+
+        XCTAssertFalse(token1.isInKeychain, "Token should not be in keychain: \(token1)")
+        XCTAssertFalse(token2.isInKeychain, "Token should not be in keychain: \(token2)")
+
+        XCTAssertFalse(token1.removeFromKeychain(), "Removing again should fail: \(token1)")
+        XCTAssertFalse(token2.removeFromKeychain(), "Removing again should fail: \(token2)")
     }
 
     func _tokenFromArray(tokens: [OTPToken], withKeychainItemRef keychainItemRef: NSData) -> OTPToken? {
-        XCTAssertNotNil(tokens, "Can't find a token in a nil array.");
-        XCTAssertNotNil(keychainItemRef, "Can't find a token with a nil keychain ref.");
-
-        var foundToken: OTPToken? = nil;
-        for token in tokens {
-            if foundToken != nil {
-                XCTAssertNotEqual(token.keychainItemRef, keychainItemRef, "Found two tokens with identical keychain refs!\n\(foundToken)\n\(token)");
-            }
-            if let tokenRef = token.keychainItemRef
-                where tokenRef.isEqualToData(keychainItemRef) {
-                    foundToken = token;
-            }
-        }
-        return foundToken;
+        let matchingTokens = tokens.filter({ $0.keychainItemRef == keychainItemRef })
+        XCTAssert((matchingTokens.count <= 1),
+            "Found more than one matching token: \(matchingTokens)")
+        return matchingTokens.first
     }
 
     func testAllTokensInKeychain() {


        let tokens = OTPToken.allTokensInKeychain()

        XCTAssertNotNil(_tokenFromArray(tokens, withKeychainItemRef: token1.keychainItemRef!), "Token not recovered from keychain: \(token1)");
        XCTAssertNotNil(_tokenFromArray(tokens, withKeychainItemRef: token2.keychainItemRef!), "Token not recovered from keychain: \(token2)");
        XCTAssertNotNil(_tokenFromArray(tokens, withKeychainItemRef: token3.keychainItemRef!), "Token not recovered from keychain: \(token3)");
        
        let keychainRef1 = token1.keychainItemRef;
        let keychainRef2 = token2.keychainItemRef;
        let keychainRef3 = token3.keychainItemRef;
        
        token1.removeFromKeychain()
        token2.removeFromKeychain()
        token3.removeFromKeychain()
        
        let tokensRemaining = OTPToken.allTokensInKeychain()
        
        XCTAssertNil(_tokenFromArray(tokensRemaining, withKeychainItemRef: keychainRef1!), "Token not removed from keychain: \(token1)");
        XCTAssertNil(_tokenFromArray(tokensRemaining, withKeychainItemRef: keychainRef2!), "Token not removed from keychain: \(token2)");
        XCTAssertNil(_tokenFromArray(tokensRemaining, withKeychainItemRef: keychainRef3!), "Token not removed from keychain: \(token3)");
    }
}

import Security.SecItem
import OneTimePasswordLegacy

let kValidSecret: [UInt8] = [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f ]

let kValidTokenURL = NSURL(string: "otpauth://totp/L%C3%A9on?algorithm=SHA256&digits=8&period=45&secret=AAAQEAYEAUDAOCAJBIFQYDIOB4")!

class OTPTokenPersistenceTests: XCTestCase {
    func testTokenWithKeychainDictionary() {
        let secret = NSData(bytes: kValidSecret, length: kValidSecret.count)
        let urlStringWithoutSecret = "otpauth://totp/L%C3%A9on?algorithm=SHA256&digits=8&period=45"
        guard let urlData = urlStringWithoutSecret.dataUsingEncoding(NSUTF8StringEncoding),
            let keychainItemRef = NSData(base64EncodedString: "Z2VucAAAAAAAAAAQ",
                options: [.IgnoreUnknownCharacters]) else {
                    XCTFail("Failed to construct keychain data")
                    return
        }

        let keychainDictionary = [
            kSecAttrGeneric as String: urlData,
            kSecValueData as String: secret,
            kSecValuePersistentRef as String: keychainItemRef,
        ]
        guard let token = OTPToken.tokenWithKeychainDictionary(keychainDictionary) else {
                XCTFail("Failed to construct token from keychain dictionary")
                return
        }

        XCTAssertEqual(token.type, OTPTokenType.Timer)
        XCTAssertEqual(token.name, "Léon")
        XCTAssertEqual(token.algorithm, OTPAlgorithm.SHA256)
        XCTAssertEqualWithAccuracy(token.period, 45, accuracy: DBL_EPSILON)
        XCTAssertEqual(token.digits, 8)

        XCTAssertEqual(token.secret, secret)

        XCTAssertEqual(token.keychainItemRef, keychainItemRef)
        XCTAssertTrue(token.isInKeychain)

        // Test failure case
        let noToken = OTPToken.tokenWithKeychainDictionary([:])
        XCTAssertNil(noToken, "Token should be nil: \(noToken)")
    }

    func testTokenWithKeychainItemRef() {
