     - 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

    }
    
    
    /**
    helper method to check wether the string begins with another given string
    
    - Parameter str: prefix string to compare
    
    - Returns: boolean indicating wether the prefix matches or not
    */
    func beginsWith (str: String) -> Bool {
        if let range = self.rangeOfString(str) {
            return range.startIndex == self.startIndex
        }
        return false
    }
    
    
    
    func isLuhnValid() -> Bool {
        guard self.isNumeric() else {
            return false
        }
        let reversedInts = self.characters.reverse().map { Int(String($0)) }
        return reversedInts.enumerate().reduce(0) { (sum, val) in
            let odd = val.index % 2 == 1
            return sum + (odd ? (val.element! == 9 ? 9 : (val.element! * 2) % 9) : val.element!)
            } % 10 == 0
    }
    
    
    
    func isNumeric() -> Bool {
        return Double(self) != nil
    }


}
