     case classField     = 0x4 // A concrete class field: syntax e.g. `c1`
     case tailElements   = 0x5 // A tail allocated element of a class: syntax `ct`
     case anyValueFields = 0x6 // Any number of any value fields (struct, tuple, enum): syntax `v**`
-    case anyClassField  = 0x7 // Any class field, including tail elements: syntax `c*`
-    
+
     // "Large" kinds: starting from here the low 3 bits must be 1.
     // This and all following kinds (we'll add in the future) cannot have a field index.
+    case anyClassField  = 0x7 // Any class field, including tail elements: syntax `c*`    
     case anything       = 0xf // Any number of any fields: syntax `**`
 
     public var isValueField: Bool {

  /// The physical representation of the path. The path components are stored in
  /// reverse order: the first path component is stored in the lowest bits (LSB),
  /// the last component is stored in the highest bits (MSB).
  /// Each pass component consists of zero or more "index-overflow" bytes followed
  /// by the "index-kind" main byte (from LSB to MSB).
  ///
  /// index overflow byte:    bit-nr:  | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

      let result = lhs.matches(pattern: rhs)
      precondition(result == expect)
    }

    func predicates() {
      testPredicate("v**.c3", \.topMatchesAnyValueField, expect: true)
      testPredicate("**",     \.topMatchesAnyValueField, expect: true)
      testPredicate("s0.c3",  \.topMatchesAnyValueField, expect: false)

      testPredicate("v**", \.hasNoClassProjection, expect: true)
      testPredicate("c0",  \.hasNoClassProjection, expect: false)
      testPredicate("1",   \.hasNoClassProjection, expect: true)
      testPredicate("**",  \.hasNoClassProjection, expect: false)

      testPredicate("v**",           \.hasClassProjection, expect: false)
      testPredicate("v**.c0.s1.v**", \.hasClassProjection, expect: true)
      testPredicate("c0.**",         \.hasClassProjection, expect: true)
      testPredicate("c0.c1",         \.hasClassProjection, expect: true)
      testPredicate("ct",            \.hasClassProjection, expect: true)
      testPredicate("s0",            \.hasClassProjection, expect: false)
    }

    func testPredicate(_ pathStr: String, _ property: (SmallProjectionPath) -> Bool, expect: Bool) {
      var parser = StringParser(pathStr)
      let path = try! parser.parseProjectionPathFromSIL()
      let result = property(path)
      precondition(result == expect)
    }
    
    func path2path() {
      testPath2Path("s0.e2.3.c4.s1", { $0.popAllValueFields() }, expect: "c4.s1")
      testPath2Path("v**.c4.s1",     { $0.popAllValueFields() }, expect: "c4.s1")
      testPath2Path("**",            { $0.popAllValueFields() }, expect: "**")

      testPath2Path("s0.e2.3.c4.s1.e2.v**.**", { $0.popLastClassAndValuesFromTail() }, expect: "s0.e2.3.c4.s1.e2.v**.**")
      testPath2Path("s0.c2.3.c4.s1",           { $0.popLastClassAndValuesFromTail() }, expect: "s0.c2.3")
      testPath2Path("v**.c*.s1",               { $0.popLastClassAndValuesFromTail() }, expect: "v**")
      testPath2Path("s1.ct.v**",               { $0.popLastClassAndValuesFromTail() }, expect: "s1")
      testPath2Path("c0.c1.c2",                { $0.popLastClassAndValuesFromTail() }, expect: "c0.c1")
      testPath2Path("**",                      { $0.popLastClassAndValuesFromTail() }, expect: "**")
    }

    func testPath2Path(_ pathStr: String, _ transform: (SmallProjectionPath) -> SmallProjectionPath, expect: String) {
      var parser = StringParser(pathStr)
      let path = try! parser.parseProjectionPathFromSIL()
      var expectParser = StringParser(expect)
      let expectPath = try! expectParser.parseProjectionPathFromSIL()
      let result = transform(path)
      precondition(result == expectPath)
    }
  }
}
