     
     case _transient = -1, `stringQuote`, `escapedCharacters`, `escapedCharacter`, `stringCharacter`, `terminalBody`, `terminalString`
     
-    func _rule(_ annotations: RuleAnnotations = [ : ])->Rule {
+    func _rule(_ annotations: RuleAnnotations = [ : ])->BehaviouralRule {
         switch self {
         case ._transient:
-            return CharacterSet(charactersIn: "").terminal(token: T._transient)
+            return CharacterSet(charactersIn: "").scan()
         // stringQuote
         case .stringQuote:
-            return "\"".terminal(token: T.stringQuote, annotations: annotations.isEmpty ? [:] : annotations)
+            return "\"".token(T.stringQuote).annotatedWith(annotations)
         // escapedCharacters
         case .escapedCharacters:
             return [
                 T.stringQuote._rule(),
-                "r".terminal(token: T._transient),
-                "n".terminal(token: T._transient),
-                "t".terminal(token: T._transient),
-                "\\".terminal(token: T._transient),
-                ].oneOf(token: T.escapedCharacters)
+                "r".scan(),
+                "n".scan(),
+                "t".scan(),
+                "\\".scan(),
+                ].oneOf.instanceWith(behaviour: Behaviour(.structural(token: self)), annotations: annotations)
         // escapedCharacter
         case .escapedCharacter:
             return [
-                "\\".terminal(token: T._transient),
+                "\\".scan(),
                 T.escapedCharacters._rule(),
-                ].sequence(token: T.escapedCharacter, annotations: annotations.isEmpty ? [ : ] : annotations)
+                ].sequence.instanceWith(behaviour: Behaviour(.structural(token: self)), annotations: annotations)
         // stringCharacter
         case .stringCharacter:
-            return [
+            return -[
                 T.escapedCharacter._rule(),
-                [
-                    T.stringQuote._rule(),
-                    CharacterSet.newlines.terminal(token: T._transient),
-                    ].oneOf(token: T._transient).not(producing: T._transient),
-                ].oneOf(token: T.stringCharacter, annotations: [RuleAnnotation.void : RuleAnnotationValue.set])
+                    ~(![
+                        T.stringQuote._rule(),
+                        CharacterSet.newlines.scan(),
+                    ].oneOf),
+                ].oneOf
         // terminalBody
         case .terminalBody:
-            return T.stringCharacter._rule([RuleAnnotation.void : RuleAnnotationValue.set]).repeated(min: 1, producing: T.terminalBody, annotations: annotations)
+            return T.stringCharacter._rule().instanceWith(with: Behaviour(.skipping, cardinality: .oneOrMore))
         // terminalString
         case .terminalString:
             return [
                 T.stringQuote._rule(),
                 T.terminalBody._rule([RuleAnnotation.error : RuleAnnotationValue.string("Terminals must have at least one character")]),
-                T.stringQuote._rule([RuleAnnotation.error : RuleAnnotationValue.string("Missing terminating quote")]),
-                ].sequence(token: T.terminalString, annotations: annotations.isEmpty ? [ : ] : annotations)
+                T.stringQuote._rule([RuleAnnotation.error : RuleAnnotationValue.string("Missing terminating quote")]) ,
+                ].token(T.terminalString).annotatedWith(annotations)
+
         }
     }
     


class FixValidations: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    //
    // Effect: Rule annotation to report an error on missing terminal string is lost
    //
    func testLostAnnotation(){

        do{
            let _ = try STLRStringTest.parse(source: "\"h")
            XCTFail("Expected unterminated string error" )
        } catch AbstractSyntaxTreeConstructor.ConstructionError.constructionFailed(let errors) {
            XCTAssertEqual(errors.count, 2)
            XCTAssertTrue("\(errors[0])".hasPrefix("Missing terminating quote"))
        } catch {
            XCTFail("Unexpected error \(error)")
        }


import XCTest
@testable import OysterKit
@testable import ExampleLanguages

fileprivate enum STLRStringTest : Int, Token {
    
