 }
 
 fileprivate extension _STLR.Expression {
-    func rule(with behaviour:Behaviour, and annotations:RuleAnnotations, using symbolTable:SymbolTable<Symbol>)->Rule {
+    func rule(using symbolTable:SymbolTable<Symbol>)->Rule {
         switch self {
         case .sequence(let elements):
-            return elements.sequence(with: behaviour, and: annotations, using: symbolTable)
+            return elements.map({ (element) -> Rule in
+                element.rule(symbolTable: symbolTable)
+            }).sequence
         case .choice(let elements):
-            return elements.choice(with: behaviour, and: annotations, using: symbolTable)
+            return elements.map({ (element) -> Rule in
+                element.rule(symbolTable: symbolTable)
+            }).choice
         case .element(let element):
-            #warning("There is an optimization oppertunity here. If it's a single element with no specific annotations we don't need to wrap in a sequence but can 'merge' and hoist")
-            return [element].sequence(with: behaviour, and: annotations, using: symbolTable)
+            return element.rule(symbolTable: symbolTable)
         }
     }
 }

        return assumed.merge(with: annotations?.ruleAnnotations ?? [:])
    }

    func rule(using symbolTable:SymbolTable<Symbol>)->Rule {
        if symbolTable[hasRule: identifier] {
            return symbolTable[identifier].behaviouralRule
        }
        
        if symbolTable.ast.isLeftHandRecursive(identifier: identifier){
            let rule = BehaviouralRecursiveRule(stubFor: behaviour, with: ruleAnnotations)
            symbolTable[identifier] = Symbol(behaviouralRule: rule)
            rule.surrogateRule = expression.rule(with: behaviour, and: ruleAnnotations, using: symbolTable).reference(behaviour.kind)
            return rule
        } else {
            let rule = expression.rule(with: behaviour, and: ruleAnnotations, using: symbolTable).reference(behaviour.kind)
            symbolTable[identifier] = Symbol(behaviouralRule: rule)
            return rule
        }
    }
}

public extension _STLR.Grammar {

import OysterKit

fileprivate final class Symbol : SymbolType {
    let identifier : String
    private var expression: Rule
    private var baseAnnotations : RuleAnnotations
    private var baseKind : Behaviour.Kind

    static func build(for identifier: String, from grammar: _STLR.Grammar, in symbolTable: SymbolTable<Symbol>) -> Symbol {
        let symbol : Symbol
        let declaration = grammar[identifier]
        if grammar.isLeftHandRecursive(identifier: identifier){
            let recursive = BehaviouralRecursiveRule(stubFor: Behaviour(.scanning), with: [:])
            symbol = Symbol(identifier, with: recursive, baseKind: declaration.behaviour.kind, baseAnnotations: declaration.annotations?.ruleAnnotations ?? [:])
            symbolTable[identifier] = symbol
            recursive.surrogateRule = grammar[identifier].expression.rule(using: symbolTable)
        } else {
            symbol = Symbol(identifier, with: grammar[identifier].expression.rule(using: symbolTable), baseKind: declaration.behaviour.kind, baseAnnotations: declaration.annotations?.ruleAnnotations ?? [:])
            symbolTable[identifier] = symbol
        }
        
        return symbol
    }
    
    init(_ identifier:String, with expression:Rule, baseKind: Behaviour.Kind, baseAnnotations:RuleAnnotations){
        self.identifier = identifier
        self.expression = expression
        self.baseKind = baseKind
        self.baseAnnotations = baseAnnotations
    }
    
    func reference(with behaviour:Behaviour, and instanceAnnotations:RuleAnnotations)->Rule{
        return expression.annotatedWith(baseAnnotations.merge(with: instanceAnnotations)).reference(behaviour.kind).rule(with:behaviour,annotations: nil).scan()
    }
    
    var  rule : Rule {
        return expression.rule(with: Behaviour(baseKind), annotations: baseAnnotations)
    }
}

