       }
    }
    public var onStateChange: ((State) -> Void)?
+   open var modelReadOnlyKeys: [Key] { return [] }
+   open var modelReadWriteKeys: [Key] { return [] }
+   open var modelWriteOnlyKeys: [Key] { return [] }
+   open var viewReadOnlyKeys: [Key] { return [] }
+   open var viewReadWriteKeys: [Key] { return [] }
+   open var viewWriteOnlyKeys: [Key] { return [] }
    
    // MARK: Public
    public func value<T>(for key: Key, default defaultValue: T?) -> T? {


public protocol StringConductionModelType: StringBindable {
   // MARK: – Keys
   var modelKeyStrings: [String] { get }
   var viewKeyStrings: [String] { get }
   
   func bindings(for keyString: String) -> [Binding]
}

public protocol ConductionModelType: Bindable, StringConductionModelType {
   // MARK: – Keys
   var modelKeys: [Key] { get }
   var viewKeys: [Key] { get }
   
   // MARK: - Bindings
   func bindings(for key: Key) -> [Binding]
}

public extension ConductionModelType {
   var modelKeyStrings: [String] {
      return modelKeys.map { return $0.rawValue }
   }
   var viewKeyStrings: [String] {
      return viewKeys.map { return $0.rawValue }
   }
   
   func bindings(for keyString: String) -> [Binding] {
      guard let key = Key(rawValue: keyString) else { return [] }
      return bindings(for: key)
   }
}

public protocol ConductionModelState {

   open func set(conductedValue: Any?, for key: Key) throws {}
   
   // MARK: - ConductionModelType Protocol
   open var modelReadKeys: [Key] { return modelReadOnlyKeys + modelReadWriteKeys }
   open var modelWriteKeys: [Key] { return modelReadWriteKeys + modelWriteOnlyKeys }
   open var viewReadKeys: [Key] { return viewReadOnlyKeys + viewReadWriteKeys }
   open var viewWriteKeys: [Key] { return viewReadWriteKeys + viewWriteOnlyKeys }
   
   public func bindings(for key: Key) -> [Binding] {
      let bindings = modelBindings.filter(key: key)
