     var description: String {
         return "@property \(self.name): \(self.typeDescription)"
     }
+
 }
 
 
-public class SwiftyModel: NSObject {
-
-    public class func keyPathForKeys() -> [String: String]? {
-        return nil
-    }
-
-    public class func dateFormatterForKey(key: String) -> NSDateFormatter? {
-        return self.defaultDateFormatter
-    }
-
-
-    internal var properties: [Property] {
-        if let cachedProperties = self.dynamicType.cachedProperties {
-            return cachedProperties
-        }
-
-        let mirror = reflect(self)
-        if mirror.count <= 1 {
-            return [Property]()
-        }
-
-        var properties = [Property]()
-        for i in 1..<mirror.count {
-            let (name, propertyMirror) = mirror[i]
-
-            let property = Property()
-            property.name = name
-            if toString(propertyMirror.valueType) == "__NSCFNumber" {
-                property.type = NSNumber.self
-            } else {
-                property.type = propertyMirror.valueType
-            }
-            property.defaultValue = propertyMirror.value
-            property.isOptional = propertyMirror.disposition == .Optional
-            properties.append(property)
-        }
-
-        self.dynamicType.cachedProperties = properties
-        return properties
-    }
-
-    internal class var cachedProperties: [Property]? {
-        get {
-            return objc_getAssociatedObject(self, "properties") as? [Property]
-        }
-        set {
-            objc_setAssociatedObject(
-                self,
-                "properties",
-                newValue,
-                objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)
-            )
-        }
-    }
-
-    public class func propertySetterNameForKey(key: String) -> String {
-        if isEmpty(key) {
-            return key
-        }
-        let range = key.startIndex..<advance(key.startIndex, 1)
-        let uppercase = key.substringWithRange(range).uppercaseString
-        let name = "set" + key.stringByReplacingCharactersInRange(range, withString: uppercase) + ":"
-        return name
-    }
-
-
-    public class func fromArray(array: AnyObject?) -> [SwiftyModel] {
-        if let array = array as? [[String: NSObject]] {
-            return array.map { self.init($0) }
-        }
-        return []
-    }
-
-    public convenience init(_ dictionary: AnyObject) {
-        self.init()
-        self.update(dictionary)
-    }
-
-    public func update(dictionary: AnyObject) {
-        if let dictionary = dictionary as? [String: NSObject] {
-            self.setValuesForKeysWithDictionary(dictionary)
-        }
-    }
-
-    public override func setValuesForKeysWithDictionary(keyedValues: [NSObject : AnyObject]) {
-        for (key, value) in keyedValues {
-            if let key = key as? String {
-                self.setValue(value, forKey: key)
-
-                if let keyPaths = self.dynamicType.keyPathForKeys() {
-                    for (property, keyPath) in keyPaths {
-                        if keyPath == key && property != keyPath {
-                            self.setValue(value, forKey: property)
-                        }
-
-                        else if keyPath.hasPrefix(key + ".") {
-                            var dictKeys = keyPath.componentsSeparatedByString(".")
-                            dictKeys.removeAtIndex(0)
-
-                            var valueForKeyPath: AnyObject? = value
-                            while count(dictKeys) > 0 {
-                                let newValue: AnyObject? = valueForKeyPath?[dictKeys.first!]
-                                if newValue == nil {
-                                    break
-                                }
-                                valueForKeyPath = newValue
-                                dictKeys.removeAtIndex(0)
-                            }
-
-                            self.setValue(valueForKeyPath, forKey: property)
-                        }
-                    } // end for
-                } // end if-let keyPaths
-            } // end if-let key
-        }
-    }
-
-    public override func setValue(value: AnyObject?, forKey key: String) {
-        if let property = self.properties.filter({ $0.name == key }).first {
-            let type = property.type
-
-            // if model doesn't have setter method for key
-            if !self.respondsToSelector(Selector(self.dynamicType.propertySetterNameForKey(key))) {
-
-                // if model doesn't have ivar - it's undefined key
-                let ivar = class_getInstanceVariable(self.dynamicType, key)
-                if ivar.hashValue == 0 {
-                    return self.setValue(value, forUndefinedKey: key)
-                }
-
-                // memory address for ivar
-                let address = ObjectIdentifier(self).uintValue + UInt(ivar_getOffset(ivar))
-
-                if type == Int.self || type == Optional<Int>.self {
-                    let pointer = UnsafeMutablePointer<Int?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.integerValue
-                    return
-                }
-
-                if type == Int8.self || type == Optional<Int8>.self {
-                    let pointer = UnsafeMutablePointer<Int8?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.charValue
-                    return
-                }
-
-                if type == Int16.self || type == Optional<Int16>.self {
-                    let pointer = UnsafeMutablePointer<Int16?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.shortValue
-                    return
-                }
-
-                if type == Int32.self || type == Optional<Int32>.self {
-                    let pointer = UnsafeMutablePointer<Int32?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.intValue
-                    return
-                }
-
-                if type == Int64.self || type == Optional<Int64>.self {
-                    let pointer = UnsafeMutablePointer<Int64?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.longLongValue
-                    return
-                }
-
-                if type == UInt.self || type == Optional<UInt>.self {
-                    let pointer = UnsafeMutablePointer<UInt?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedLongValue
-                    return
-                }
-
-                if type == UInt8.self || type == Optional<UInt8>.self {
-                    let pointer = UnsafeMutablePointer<UInt8?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedCharValue
-                    return
-                }
-
-                if type == UInt16.self || type == Optional<UInt16>.self {
-                    let pointer = UnsafeMutablePointer<UInt16?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedShortValue
-                    return
-                }
-                
-                if type == UInt32.self || type == Optional<UInt32>.self {
-                    let pointer = UnsafeMutablePointer<UInt32?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedIntValue
-                    return
-                }
-                
-                if type == UInt64.self || type == Optional<UInt64>.self {
-                    let pointer = UnsafeMutablePointer<UInt64?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedLongLongValue
-                    return
-                }
-
-                if type == Float.self || type == Optional<Float>.self {
-                    let pointer = UnsafeMutablePointer<Float?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.floatValue
-                    return
-                }
-
-                if type == Double.self || type == Optional<Double>.self {
-                    let pointer = UnsafeMutablePointer<Double?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.doubleValue
-                    return
-                }
-
-                if type == CGFloat.self || type == Optional<CGFloat>.self {
-                    let pointer = UnsafeMutablePointer<CGFloat?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value) as? CGFloat
-                    return
-                }
-
-                if type == Bool.self || type == Optional<Bool>.self {
-                    let pointer = UnsafeMutablePointer<Bool?>(bitPattern: address)
-                    pointer.memory = self.dynamicType.numberFromValue(value)?.boolValue
-                    return
-                }
-            }
-
-            // String
-            if type == String.self || type == Optional<String>.self {
-                if let value = value as? String {
-                    super.setValue(value, forKey: key)
-                } else if let value = value as? NSNumber {
-                    super.setValue(value.stringValue, forKey: key)
-                }
-            }
-
-            // Number
-            else if type == NSNumber.self || type == Optional<NSNumber>.self {
-                super.setValue(self.dynamicType.numberFromValue(value), forKey: key)
-            }
-
-            // Date
-            else if type == NSDate.self || type == Optional<NSDate>.self || toString(type) == "__NSDate" {
-                let formatter = self.dynamicType.dateFormatterForKey(key) ?? SwiftyModel.defaultDateFormatter
-                if let stringValue = value as? String, date = formatter.dateFromString(stringValue) {
-                    super.setValue(date, forKey: key)
-                }
-            }
-
-            // URL
-            else if type == NSURL.self || type == Optional<NSURL>.self {
-                if let URLString = value as? String, URL = NSURL(string: URLString) {
-                    super.setValue(URL, forKey: key)
-                }
-            }
-
-            // List
-            else if let modelClass = property.modelClass where property.isArray {
-                if let array = value as? [[String: NSObject]] {
-                    let models = modelClass.fromArray(array)
-                    super.setValue(models, forKey: key)
-                }
-            }
-
-            // Relationship
-            else if let modelClass = property.modelClass {
-                if let dict = value as? [String: NSObject] {
-                    let model = modelClass.init(dict)
-                    super.setValue(model, forKey: key)
-                }
-            }
-
-            // String Enum
-            else if let defaultValue = property.defaultValue as? StringEnum,
-                        stringValue = (value as? String) ?? (value as? NSNumber)?.stringValue {
-                for (raw, string) in defaultValue.rawValues {
-                    if string == stringValue {
-                        super.setValue(raw, forKey: key)
-                        break
-                    }
-                }
-            }
-
-            // Integer Enum
-            else if let enumType = property.type as? SuperEnum.Type {
-                super.setValue(self.dynamicType.numberFromValue(value), forKey: key)
-            }
-
-            // What else?
-            else {
-                println("Else: \(key): \(type) = \(value)")
-            }
-        }
-    }
-
-    override public func setValue(value: AnyObject?, forUndefinedKey key: String) {
-        // implement in subclass if needed
-    }
-
-    override public func valueForKey(key: String) -> AnyObject? {
-        if !self.respondsToSelector(Selector(key)) {
-            let ivar = class_getInstanceVariable(self.dynamicType, key)
-            if let type = self.properties.filter({ $0.name == key }).first?.type where ivar.hashValue != 0 {
-                let address = ObjectIdentifier(self).uintValue + UInt(ivar_getOffset(ivar))
-
-                if type == Int.self || type == Optional<Int>.self {
-                    let pointer = UnsafeMutablePointer<Int?>(bitPattern: address)
-                    return pointer.memory
-                }
-
-                if type == Int8.self || type == Optional<Int8>.self {
-                    let pointer = UnsafeMutablePointer<Int8?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == Int16.self || type == Optional<Int16>.self {
-                    let pointer = UnsafeMutablePointer<Int16?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == Int32.self || type == Optional<Int32>.self {
-                    let pointer = UnsafeMutablePointer<Int32?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == Int64.self || type == Optional<Int64>.self {
-                    let pointer = UnsafeMutablePointer<Int64?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == UInt.self || type == Optional<UInt>.self {
-                    let pointer = UnsafeMutablePointer<UInt?>(bitPattern: address)
-                    return pointer.memory
-                }
-
-                if type == UInt8.self || type == Optional<UInt8>.self {
-                    let pointer = UnsafeMutablePointer<UInt8?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == UInt16.self || type == Optional<UInt16>.self {
-                    let pointer = UnsafeMutablePointer<UInt16?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == UInt32.self || type == Optional<UInt32>.self {
-                    let pointer = UnsafeMutablePointer<UInt32?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == UInt64.self || type == Optional<UInt64>.self {
-                    let pointer = UnsafeMutablePointer<UInt64?>(bitPattern: address)
-                    return pointer.memory as? AnyObject
-                }
-
-                if type == Float.self || type == Optional<Float>.self {
-                    let pointer = UnsafeMutablePointer<Float?>(bitPattern: address)
-                    return pointer.memory
-                }
-
-                if type == Double.self || type == Optional<Double>.self {
-                    let pointer = UnsafeMutablePointer<Double?>(bitPattern: address)
-                    return pointer.memory
-                }
-
-                if type == CGFloat.self || type == Optional<CGFloat>.self {
-                    let pointer = UnsafeMutablePointer<CGFloat?>(bitPattern: address)
-                    return pointer.memory
-                }
-
-                if type == Bool.self || type == Optional<Bool>.self {
-                    let pointer = UnsafeMutablePointer<Bool?>(bitPattern: address)
-                    return pointer.memory
-                }
-            }
-        }
-        return super.valueForKey(key)
-    }
-
-    public func toDictionary(nulls: Bool = false) -> [String: NSObject] {
-        var dictionary = [String: NSObject]()
-        for property in self.properties {
-            if let value: AnyObject = self.valueForKey(property.name) {
-
-                // Model
-                if let model = value as? SwiftyModel {
-                    dictionary[property.name] = model.toDictionary(nulls: nulls)
-                }
-
-                // List
-                else if let models = value as? [SwiftyModel] {
-                    dictionary[property.name] = models.map { $0.toDictionary(nulls: nulls) }
-                }
-
-                // Date
-                else if let date = value as? NSDate {
-                    let formatter = self.dynamicType.dateFormatterForKey(property.name)
-                        ?? SwiftyModel.defaultDateFormatter
-                    dictionary[property.name] = formatter.stringFromDate(date)
-                }
-
-                // URL
-                else if let URL = value as? NSURL {
-                    dictionary[property.name] = URL.absoluteString
-                }
-
-                // String Enum
-                else if let defaultValue = property.defaultValue as? StringEnum {
-                    for (raw, string) in defaultValue.rawValues {
-                        if raw == value as! Int {
-                            dictionary[property.name] = string
-                            break
-                        }
-                    }
-                }
-
-                // Integer Enum
-                else if let enumValue = value as? SuperEnum {
-                    dictionary[property.name] = enumValue.rawValue
-                }
-
-                // Primitive Types
-                else {
-                    dictionary[property.name] = value as? NSObject
-                }
-            } else if nulls {
-                dictionary[property.name] = NSNull()
-            }
-        }
-        return dictionary
-    }
-
-    public class func arrayFromModels(models: [SwiftyModel]) -> [[String: NSObject]] {
-        return models.map { $0.toDictionary() }
-    }
-
-    private struct Shared {
-        static let numberFormatter = NSNumberFormatter()
-        static let dateFormatter = NSDateFormatter()
-    }
-
-    public class func numberFromValue(value: AnyObject?) -> NSNumber? {
-        if let value = value as? NSNumber {
-            return value
-        }
-        if let string = value as? String {
-            Shared.numberFormatter.numberStyle = .DecimalStyle
-            return Shared.numberFormatter.numberFromString(string)
-        }
-        return nil
-    }
-
-    public static let defaultDateFormatter: NSDateFormatter = Shared.dateFormatter
+// MARK: - Operators
+
+public func == (lhs: Any.Type, rhs: Any.Type) -> Bool {
+    return ObjectIdentifier(lhs).hashValue == ObjectIdentifier(rhs).hashValue
 }
+
+public func == (lhs: SuperEnum.Type, rhs: SuperEnum.Type) -> Bool {
+    return toString(lhs) == toString(rhs)
+}

}


internal class Property: Printable {
    var name: String!
    var type: Any.Type!
    var defaultValue: Any?

import Foundation


// MARK: - SwiftyModel

public class SwiftyModel: NSObject {


    // MARK: Initializers

    public convenience init(_ dictionary: AnyObject) {
        self.init()
        self.update(dictionary)
    }

    public class func fromArray(array: AnyObject?) -> [SwiftyModel] {
        if let array = array as? [[String: NSObject]] {
            return array.map { self.init($0) }
        }
        return []
    }


    // MARK: Public Interfaces

    public static var defaultDateFormatter = NSDateFormatter()
    public static var defaultNumberFormatter: NSNumberFormatter = {
        let formatter = NSNumberFormatter()
        formatter.numberStyle = .DecimalStyle
        return formatter
    }()

    public class func keyPathForKeys() -> [String: String]? {
        return nil
    }

    public class func dateFormatterForKey(key: String) -> NSDateFormatter? {
        return self.defaultDateFormatter
    }

    public func update(dictionary: AnyObject) {
        if let dictionary = dictionary as? [String: NSObject] {
            self.setValuesForKeysWithDictionary(dictionary)
        }
    }


    // MARK: Properties

    internal var properties: [Property] {
        if let cachedProperties = self.dynamicType.cachedProperties {
            return cachedProperties
        }

        let mirror = reflect(self)
        if mirror.count <= 1 {
            return [Property]()
        }

        var properties = [Property]()
        for i in 1..<mirror.count {
            let (name, propertyMirror) = mirror[i]

            let property = Property()
            property.name = name
            if toString(propertyMirror.valueType) == "__NSCFNumber" {
                property.type = NSNumber.self
            } else {
                property.type = propertyMirror.valueType
            }
            property.defaultValue = propertyMirror.value
            property.isOptional = propertyMirror.disposition == .Optional
            properties.append(property)
        }

        self.dynamicType.cachedProperties = properties
        return properties
    }

    internal class var cachedProperties: [Property]? {
        get {
            return objc_getAssociatedObject(self, "properties") as? [Property]
        }
        set {
            objc_setAssociatedObject(
                self,
                "properties",
                newValue,
                objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            )
        }
    }


    // MARK: KVC

    public override func setValuesForKeysWithDictionary(keyedValues: [NSObject : AnyObject]) {
        for (key, value) in keyedValues {
            if let key = key as? String {
                self.setValue(value, forKey: key)

                if let keyPaths = self.dynamicType.keyPathForKeys() {
                    for (property, keyPath) in keyPaths {
                        if keyPath == key && property != keyPath {
                            self.setValue(value, forKey: property)
                        }

                        else if keyPath.hasPrefix(key + ".") {
                            var dictKeys = keyPath.componentsSeparatedByString(".")
                            dictKeys.removeAtIndex(0)

                            var valueForKeyPath: AnyObject? = value
                            while count(dictKeys) > 0 {
                                let newValue: AnyObject? = valueForKeyPath?[dictKeys.first!]
                                if newValue == nil {
                                    break
                                }
                                valueForKeyPath = newValue
                                dictKeys.removeAtIndex(0)
                            }

                            self.setValue(valueForKeyPath, forKey: property)
                        }
                    } // end for
                } // end if-let keyPaths
            } // end if-let key
        }
    }

    public override func setValue(value: AnyObject?, forKey key: String) {
        if let property = self.properties.filter({ $0.name == key }).first {
            let type = property.type

            // if model doesn't have setter method for key
            if !self.respondsToSelector(Selector(self.dynamicType.propertySetterNameForKey(key))) {

                // if model doesn't have ivar - it's undefined key
                let ivar = class_getInstanceVariable(self.dynamicType, key)
                if ivar.hashValue == 0 {
                    return self.setValue(value, forUndefinedKey: key)
                }

                // memory address for ivar
                let address = ObjectIdentifier(self).uintValue + UInt(ivar_getOffset(ivar))

                if type == Int.self || type == Optional<Int>.self {
                    let pointer = UnsafeMutablePointer<Int?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.integerValue
                    return
                }

                if type == Int8.self || type == Optional<Int8>.self {
                    let pointer = UnsafeMutablePointer<Int8?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.charValue
                    return
                }

                if type == Int16.self || type == Optional<Int16>.self {
                    let pointer = UnsafeMutablePointer<Int16?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.shortValue
                    return
                }

                if type == Int32.self || type == Optional<Int32>.self {
                    let pointer = UnsafeMutablePointer<Int32?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.intValue
                    return
                }

                if type == Int64.self || type == Optional<Int64>.self {
                    let pointer = UnsafeMutablePointer<Int64?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.longLongValue
                    return
                }

                if type == UInt.self || type == Optional<UInt>.self {
                    let pointer = UnsafeMutablePointer<UInt?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedLongValue
                    return
                }

                if type == UInt8.self || type == Optional<UInt8>.self {
                    let pointer = UnsafeMutablePointer<UInt8?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedCharValue
                    return
                }

                if type == UInt16.self || type == Optional<UInt16>.self {
                    let pointer = UnsafeMutablePointer<UInt16?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedShortValue
                    return
                }
                
                if type == UInt32.self || type == Optional<UInt32>.self {
                    let pointer = UnsafeMutablePointer<UInt32?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedIntValue
                    return
                }
                
                if type == UInt64.self || type == Optional<UInt64>.self {
                    let pointer = UnsafeMutablePointer<UInt64?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.unsignedLongLongValue
                    return
                }

                if type == Float.self || type == Optional<Float>.self {
                    let pointer = UnsafeMutablePointer<Float?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.floatValue
                    return
                }

                if type == Double.self || type == Optional<Double>.self {
                    let pointer = UnsafeMutablePointer<Double?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.doubleValue
                    return
                }

                if type == CGFloat.self || type == Optional<CGFloat>.self {
                    let pointer = UnsafeMutablePointer<CGFloat?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value) as? CGFloat
                    return
                }

                if type == Bool.self || type == Optional<Bool>.self {
                    let pointer = UnsafeMutablePointer<Bool?>(bitPattern: address)
                    pointer.memory = self.dynamicType.numberFromValue(value)?.boolValue
                    return
                }
            }

            // String
            if type == String.self || type == Optional<String>.self {
                if let value = value as? String {
                    super.setValue(value, forKey: key)
                } else if let value = value as? NSNumber {
                    super.setValue(value.stringValue, forKey: key)
                }
            }

            // Number
            else if type == NSNumber.self || type == Optional<NSNumber>.self {
                super.setValue(self.dynamicType.numberFromValue(value), forKey: key)
            }

            // Date
            else if type == NSDate.self || type == Optional<NSDate>.self || toString(type) == "__NSDate" {
                let formatter = self.dynamicType.dateFormatterForKey(key) ?? SwiftyModel.defaultDateFormatter
                if let stringValue = value as? String, date = formatter.dateFromString(stringValue) {
                    super.setValue(date, forKey: key)
                }
            }

            // URL
            else if type == NSURL.self || type == Optional<NSURL>.self {
                if let URLString = value as? String, URL = NSURL(string: URLString) {
                    super.setValue(URL, forKey: key)
                }
            }

            // List
            else if let modelClass = property.modelClass where property.isArray {
                if let array = value as? [[String: NSObject]] {
                    let models = modelClass.fromArray(array)
                    super.setValue(models, forKey: key)
                }
            }

            // Relationship
            else if let modelClass = property.modelClass {
                if let dict = value as? [String: NSObject] {
                    let model = modelClass.init(dict)
                    super.setValue(model, forKey: key)
                }
            }

            // String Enum
            else if let defaultValue = property.defaultValue as? StringEnum,
                        stringValue = (value as? String) ?? (value as? NSNumber)?.stringValue {
                for (raw, string) in defaultValue.rawValues {
                    if string == stringValue {
                        super.setValue(raw, forKey: key)
                        break
                    }
                }
            }

            // Integer Enum
            else if let enumType = property.type as? SuperEnum.Type {
                super.setValue(self.dynamicType.numberFromValue(value), forKey: key)
            }

            // What else?
            else {
                println("Else: \(key): \(type) = \(value)")
            }
        }
    }

    override public func setValue(value: AnyObject?, forUndefinedKey key: String) {
        // implement in subclass if needed
    }

    override public func valueForKey(key: String) -> AnyObject? {
        if !self.respondsToSelector(Selector(key)) {
            let ivar = class_getInstanceVariable(self.dynamicType, key)
            if let type = self.properties.filter({ $0.name == key }).first?.type where ivar.hashValue != 0 {
                let address = ObjectIdentifier(self).uintValue + UInt(ivar_getOffset(ivar))

                if type == Int.self || type == Optional<Int>.self {
                    let pointer = UnsafeMutablePointer<Int?>(bitPattern: address)
                    return pointer.memory
                }

                if type == Int8.self || type == Optional<Int8>.self {
                    let pointer = UnsafeMutablePointer<Int8?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == Int16.self || type == Optional<Int16>.self {
                    let pointer = UnsafeMutablePointer<Int16?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == Int32.self || type == Optional<Int32>.self {
                    let pointer = UnsafeMutablePointer<Int32?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == Int64.self || type == Optional<Int64>.self {
                    let pointer = UnsafeMutablePointer<Int64?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == UInt.self || type == Optional<UInt>.self {
                    let pointer = UnsafeMutablePointer<UInt?>(bitPattern: address)
                    return pointer.memory
                }

                if type == UInt8.self || type == Optional<UInt8>.self {
                    let pointer = UnsafeMutablePointer<UInt8?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == UInt16.self || type == Optional<UInt16>.self {
                    let pointer = UnsafeMutablePointer<UInt16?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == UInt32.self || type == Optional<UInt32>.self {
                    let pointer = UnsafeMutablePointer<UInt32?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == UInt64.self || type == Optional<UInt64>.self {
                    let pointer = UnsafeMutablePointer<UInt64?>(bitPattern: address)
                    return pointer.memory as? AnyObject
                }

                if type == Float.self || type == Optional<Float>.self {
                    let pointer = UnsafeMutablePointer<Float?>(bitPattern: address)
                    return pointer.memory
                }

                if type == Double.self || type == Optional<Double>.self {
                    let pointer = UnsafeMutablePointer<Double?>(bitPattern: address)
                    return pointer.memory
                }

                if type == CGFloat.self || type == Optional<CGFloat>.self {
                    let pointer = UnsafeMutablePointer<CGFloat?>(bitPattern: address)
                    return pointer.memory
                }

                if type == Bool.self || type == Optional<Bool>.self {
                    let pointer = UnsafeMutablePointer<Bool?>(bitPattern: address)
                    return pointer.memory
                }
            }
        }
        return super.valueForKey(key)
    }


    // MARK: Reverse

    public func toDictionary(nulls: Bool = false) -> [String: NSObject] {
        var dictionary = [String: NSObject]()
        for property in self.properties {
            if let value: AnyObject = self.valueForKey(property.name) {

                // Model
                if let model = value as? SwiftyModel {
                    dictionary[property.name] = model.toDictionary(nulls: nulls)
                }

                // List
                else if let models = value as? [SwiftyModel] {
                    dictionary[property.name] = models.map { $0.toDictionary(nulls: nulls) }
                }

                // Date
                else if let date = value as? NSDate {
                    let formatter = self.dynamicType.dateFormatterForKey(property.name)
                        ?? SwiftyModel.defaultDateFormatter
                    dictionary[property.name] = formatter.stringFromDate(date)
                }

                // URL
                else if let URL = value as? NSURL {
                    dictionary[property.name] = URL.absoluteString
                }

                // String Enum
                else if let defaultValue = property.defaultValue as? StringEnum {
                    for (raw, string) in defaultValue.rawValues {
                        if raw == value as! Int {
                            dictionary[property.name] = string
                            break
                        }
                    }
                }

                // Integer Enum
                else if let enumValue = value as? SuperEnum {
                    dictionary[property.name] = enumValue.rawValue
                }

                // Primitive Types
                else {
                    dictionary[property.name] = value as? NSObject
                }
            } else if nulls {
                dictionary[property.name] = NSNull()
            }
        }
        return dictionary
    }

    public class func arrayFromModels(models: [SwiftyModel]) -> [[String: NSObject]] {
        return models.map { $0.toDictionary() }
    }


    // MARK: Utils

    public class func propertySetterNameForKey(key: String) -> String {
        if isEmpty(key) {
            return key
        }
        let range = key.startIndex..<advance(key.startIndex, 1)
        let uppercase = key.substringWithRange(range).uppercaseString
        let name = "set" + key.stringByReplacingCharactersInRange(range, withString: uppercase) + ":"
        return name
    }

    public class func numberFromValue(value: AnyObject?) -> NSNumber? {
        if let value = value as? NSNumber {
            return value
        }
        if let string = value as? String {
            return self.defaultNumberFormatter.numberFromString(string)
        }
        return nil
    }
    
}


// MARK: - SuperEnum

public protocol SuperEnum {
    var rawValue: Int { get }
