 // MARK: - DefaultStoreType
 
 public protocol DefaultStoreType {
+    
     associatedtype Default: DefaultConvertible
-    
-    var key: String { get }
   
     func set(value: Default)
     func get() -> Default?

// MARK: -

public final class DefaultsStore<Default: DefaultConvertible>: DefaultStoreType {
    public let key: String
    
    private let defaults = NSUserDefaults.standardUserDefaults()
    
    public init(key: String) {
        self.key = key
    }
    
    public func set(value: Default) {
        let obj = value.serialize()
        defaults.setObject(obj, forKey: key)
    }
    
    public func get() -> Default? {
        guard let obj = defaults.objectForKey(key) else { return nil }
        return Default(obj)
    }
    
    public func remove() {
        defaults.removeObjectForKey(key)
    }
}

// MARK: -

public final class DictionaryStore<Default: DefaultConvertible>: DefaultStoreType {
    public let key: String
    
    private var dictionary: [String: AnyObject] = [:]

    
    public init(key: String) {
        self.key = key
    }
    
    public func set(value: Default) {
        let obj = value.serialize()
        dictionary[key] = obj
    }
    
    public func get() -> Default? {
        guard let obj = dictionary[key] else { return nil }
        return Default(obj)
    }
    
    public func remove() {
        dictionary[key] = nil
    }
}

/// Represents objects that can type-safely be interacted with DefaultStoreType
public protocol DefaultConvertible {
    
    static var key: String { get }
    
    /// Desirialize AnyObject to adopted object.
    /// The argument "object" is intended to be passed from DefaultStoreType
    init?(_ object: AnyObject)
