 
 
 enum ByteMatcherEntry {
+  case EatWhileLowerCase
   case EatWhileDigit
   case Next
   case SkipToEnd


  struct EmptyParams: ByteMatcherEntryData {
    var entry: ByteMatcherEntry
    var optional: Bool
  }


  struct UInt8Param: ByteMatcherEntryData {
    var entry: ByteMatcherEntry
    var optional: Bool
    var c: UInt8
  }


  struct BytesParam: ByteMatcherEntryData {
    var entry: ByteMatcherEntry
    var optional: Bool
    var bytes: [UInt8]
  }


  struct UInt8FnParam: ByteMatcherEntryData {
    var entry: ByteMatcherEntry
    var optional: Bool
    var fn: (c: UInt8) -> Bool
  }


  struct CtxFnParam: ByteMatcherEntryData {
    var entry: ByteMatcherEntry
    var optional: Bool
    var fn: (inout ctx: ByteStream) -> Bool
  }


  struct FirstCharTableParam: ByteMatcherEntryData {
    var entry: ByteMatcherEntry
    var optional: Bool
    var table: FirstCharTable
  }



  mutating func doMatch() -> Bool {
    for data in list {
      if !doDataMatch(data) { // No success.
        return false
      }
    }
    return true
  }

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

  mutating func eatWhileLowerCase() {
    add(.EatWhileLowerCase)
  }

  mutating func eatWhileDigit() {
    add(.EatWhileDigit)
  }

  mutating func next() {
    add(.Next)
  }

  mutating func skipToEnd() {
    add(.SkipToEnd)
  }

  mutating func matchEos() {
    add(.MatchEos)
  }

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

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

  mutating func eatString(string: String) {
    eatBytes(string.bytes)
  }

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

  mutating func eatUntilString(string: String) {
    eatUntilBytes(string.bytes)
  }

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

  mutating func eatUntilIncludingString(string: String) {
    eatUntilIncludingBytes(string.bytes)
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
