 
 protocol ByteMatcherEntryData {
   var entry: ByteMatcherEntry { get }
-  var optional: Bool { get }
 }
 
 


  mutating func doMatch() -> Bool {
    for data in list {
      let b = doDataMatch(data)
      if !b && !data.optional { // No success and not optional.
        return false
      }
    }
    return true
  }

  mutating func add(entry: ByteMatcherEntry, optional: Bool) {
    list.append(EmptyParams(entry: entry, optional: optional))
  }

  mutating func eatWhileDigit(optional: Bool = false) {
    add(.EatWhileDigit, optional: optional)
  }

  mutating func next(optional: Bool = false) {
    add(.Next, optional: optional)
  }

  mutating func skipToEnd() {
    add(.SkipToEnd, optional: false)
  }

  mutating func matchEos() {
    add(.MatchEos, optional: false)
  }

  mutating func eatOne(c: UInt8, optional: Bool = false) {
    list.append(UInt8Param(entry: .EatOne, optional: optional, c: c))
  }

  mutating func eatUntilOne(c: UInt8, optional: Bool = false) {
    list.append(UInt8Param(entry: .EatUntilOne, optional: optional, c: c))
  }

  mutating func eatString(string: String, optional: Bool = false) {
    eatBytes(string.bytes, optional: optional)
  }

  mutating func eatBytes(bytes: [UInt8], optional: Bool = false) {
    list.append(BytesParam(entry: .EatBytes, optional: optional, bytes: bytes))
  }

  mutating func eatUntilString(string: String, optional: Bool = false) {
    eatUntilBytes(string.bytes)
  }

  mutating func eatUntilBytes(bytes: [UInt8], optional: Bool = false) {
    list.append(BytesParam(entry: .EatUntilBytes, optional: optional,
        bytes: bytes))
  }

  mutating func eatUntilIncludingString(string: String,
      optional: Bool = false) {
    eatUntilIncludingBytes(string.bytes)
  }

  mutating func eatUntilIncludingBytes(bytes: [UInt8], optional: Bool = false) {
    list.append(BytesParam(entry: .EatUntilIncludingBytes, optional: optional,
        bytes: bytes))
  }

  mutating func eatUntil(optional: Bool = false, fn: (c: UInt8) -> Bool) {
    list.append(UInt8FnParam(entry: .EatUntil, optional: optional, fn: fn))
  }

  mutating func eatOn(optional: Bool = false,
      fn: (inout ctx: ByteStream) -> Bool) {
    list.append(CtxFnParam(entry: .EatOn, optional: optional, fn: fn))
  }

  mutating func eatStringFromList(list: [String], optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatBytesFromList(list: [[UInt8]], optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatOneNotFromStrings(list: [String], optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatOneNotFromTable,
        optional: optional, table: a))
  }

  mutating func eatOneNotFromBytes(list: [[UInt8]], optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatOneNotFromTable,
        optional: optional, table: a))
  }

  mutating func eatOneFromStrings(list: [String], optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatOneFromTable,
        optional: optional, table: a))
  }

  mutating func eatOneFromBytes(list: [[UInt8]], optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatOneFromTable,
        optional: optional, table: a))
  }

  mutating func eatUntilIncludingStringFromList(list: [String],
      optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(
        entry: .EatUntilIncludingBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatUntilIncludingBytesFromList(list: [[UInt8]],
      optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(
        entry: .EatUntilIncludingBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatWhileStringFromList(list: [String],
      optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatWhileBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatWhileBytesFromList(list: [[UInt8]],
      optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatWhileBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatUntilStringFromList(list: [String],
      optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatUntilBytesFromTable,
        optional: optional, table: a))
  }

  mutating func eatUntilBytesFromList(list: [[UInt8]],
      optional: Bool = false) {
    let a = ByteStream.makeFirstCharTable(list)
    self.list.append(FirstCharTableParam(entry: .EatUntilBytesFromTable,
        optional: optional, table: a))
  }

}

    switch data.entry {
      case .EatWhileDigit:
        return stream.eatWhileDigit()
      case .EatWhileLowerCase:
        return stream.eatWhileLowerCase()
      case .SkipToEnd:
        return stream.skipToEnd()
      case .MatchEos:
