   }
 }
 
+public protocol _UnicodeEncodingBase {
+  /// The basic unit of encoding
+  associatedtype CodeUnit : UnsignedInteger, FixedWidthInteger
+  
+  /// A valid scalar value as represented in this encoding
+  associatedtype EncodedScalar : BidirectionalCollection
+    where EncodedScalar.Iterator.Element == CodeUnit
+
+  /// The replacement character U+FFFD as represented in this encoding
+  static var encodedReplacementScalar : EncodedScalar { get }
+
+  /// Returns true if `x` only appears in this encoding as the representation of
+  /// a complete scalar value.
+  static func _isScalar(_ x: CodeUnit) -> Bool
+
+  /// Convert from encoded to encoding-independent representation
+  static func decode(_ content: Self.EncodedScalar) -> UnicodeScalar
+}
+
+
 public protocol UnicodeDecoder {
+  associatedtype Encoding : _UnicodeEncodingBase
+  
   associatedtype CodeUnit : UnsignedInteger, FixedWidthInteger
   associatedtype Buffer : Collection
   

  }
}

public protocol UnicodeEncoding {
  associatedtype CodeUnit
  
  associatedtype ForwardDecoder : UnicodeDecoder
    where ForwardDecoder.CodeUnit == CodeUnit

}

extension Unicode.UTF16 : UnicodeEncoding {
  public typealias EncodedScalar = _UIntBuffer<UInt32, UInt16>

  public static var encodedReplacementScalar : EncodedScalar {
    fatalError()
  }

  public static func _isScalar(_ x: CodeUnit) -> Bool  {
    return x & 0xf800 != 0xd800
  }

  public static func decode(_ content: EncodedScalar) -> UnicodeScalar {
    fatalError()
  }
  
  public struct ForwardDecoder {
    public typealias Buffer = _UIntBuffer<UInt32, UInt16>
    public init() { buffer = Buffer() }
