     - Returns: true if the string is a valid credit card number
     */
     func isCardNumberValid() -> Bool {
+        
         let network = self.cardNetwork()
-        let strippedSelfCount = self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).characters.count
+        let strippedSelf = self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
+        
+        guard strippedSelf.isLuhnValid() else { return false }
+
+        let strippedSelfCount = strippedSelf.characters.count
+        
         switch network {
         case .UATP, .AMEX:
             return strippedSelfCount == 15

    */
    func cardNetwork() -> CardNetwork {
        
        // Card Networks that only have one prefix
        switch self {
        case _ where self.beginsWith("1"):
            return .UATP
        case _ where self.beginsWith("4"):
            return .Visa(.Unknown)
        case _ where self.beginsWith("62"):
            return .ChinaUnionPay
        case _ where self.beginsWith("636"):
            return .InterPayment
        case _ where self.beginsWith("5019"):
            return .Dankort
        default:
            break

        // Card Networks with multiple different prefix
        // AMEX begins with 34 & 37
        for prefix in ["34", "37"] {
            if strippedSelf.beginsWith(prefix) {
                return .AMEX
            }
        }
        
        // MasterCard begins with 51 - 55
        for prefix in (51...55).map({ String($0) }) {
            if strippedSelf.beginsWith(prefix) {
                return .MasterCard(.Unknown)
            }
        }
        
        // future MasterCard range 2221-2720
        for prefix in (2221...2720).map({ String($0) }) {
            if strippedSelf.beginsWith(prefix) {
                return .MasterCard(.Unknown)
            }
        }
        
        // Maestro has 50, 56-69
        for prefix in [56...69].map({ String($0) }) {
            if strippedSelf.beginsWith(prefix) {
                return .Maestro
            }
        }
        
        // Diners Club 300-305 / 309 & 36, 38, 39
        for prefix in (300...305).map({ String($0) }) + ["36", "38", "39", "309"] {
            if strippedSelf.beginsWith(prefix) {
                return .DinersClub
            }
        }
        
        // Discover 644-649
        for prefix in (644...649).map({ String($0) }) + ["65", "6011"] + (622126...622925).map({ String($0) }) {
            if strippedSelf.beginsWith(prefix) {
                return .Discover
            }
        }
        
        // InstaPayment
        for prefix in (637...639).map({ String($0) }) {
            if strippedSelf.beginsWith(prefix) {
                return .InstaPayment
            }
        }
        
        // JCB 3528-3589
        for prefix in (3528...3589).map({ String($0) }) {
            if strippedSelf.beginsWith(prefix) {
                return .JCB
            }
        }
