public void appendChildV(GrammarNodeV child)
        {
            if (child is NonterminalHeadV)
                throw new Exception("An operations children must not be of type NonterminalHeadV.");

            children.Add(child);
        }
        public void visit(UndefinedD undefinedD)
        {
            UndefinedV undefinedV = new UndefinedV(undefinedD, level + 1);
            undefinedD.References.Add(undefinedV);

            current = undefinedV;
        }
        public void visit(TerminalD terminalD)
        {
            // set current, ready for parent
            TerminalV terminalV = new TerminalV(terminalD, level + 1);

            terminalD.References.Add(terminalV);

            current = terminalV;
        }
        public GrammarNodeD AddBefore(NonterminalHeadD nonterminalHeadD, GrammarNodeV grammarNodeV, VADG.Global.SymbolType symbolType)
        {
            GrammarNodeDAddBeforeVisitor visitor = new GrammarNodeDAddBeforeVisitor();
            visitor.Target = grammarNodeV.getReference();
            visitor.SymbolType = symbolType;

            visitor.visit(nonterminalHeadD);

            return visitor.Item;
        }
        public GrammarNodeD AddAfter(NonterminalHeadD nonterminalHeadD, GrammarNodeV target, VADG.Global.SymbolType symbolType)
        {
            GrammarNodeDAddAfterVisitor visitor = new GrammarNodeDAddAfterVisitor();
            visitor.Target = target.getReference();
            visitor.SymbolType = symbolType;

            visitor.visit(nonterminalHeadD);

            return visitor.Item;
        }
        public void insertChildV(int position, GrammarNodeV child)
        {
            if (child is NonterminalHeadV)
                throw new Exception("An operations children must not be of type NonterminalHeadV.");

            if (position < 0)
                throw new Exception("The position was less than zero, cmon, sharpen up!");

            if (position > children.Count)
                throw new Exception("The position was greater than the children array");

            // do it!
            if (position == children.Count)
                appendChildV(child);
            else
                children.Insert(position, child);
        }
        public void visit(NonterminalHeadD nonterminalHeadD)
        {
            //this is the start of the visit, we create a nonterminalheadV - note one in grammar
            // if this is called again then something has gone wrong
            if (current != null)
                throw new Exception("You should only be calling visit on a NonterminalHeadD node once when creating a visualised grammar. Also use the visitor pattern once, then re-initialize");

            // visit rule
            nonterminalHeadD.Rule.accept(this);
            // current should now be a ChoiceLineV with the rest of the visualised grammar

            NonterminalHeadV startSymbolV = nonterminalHeadD.CreateNonterminalHeadV();

            if (!(current is ChoiceLineV))
                throw new Exception("the current node is not of type ChoiceLineV, is the definitive grammar constructed properly?");

            startSymbolV.Rule = (ChoiceLineV)current;

            current = startSymbolV;
        }
        private void Delete(GrammarNodeV itemToDelete)
        {
            model.Functions.Delete(itemToDelete.getReference());

            // if deleting a rule, check it's not the last time it's ever used (poor rule :( )
            GrammarNodeD grammarNodeD = itemToDelete.getReference();
            if (grammarNodeD is NonterminalTailD)
            {
                NonterminalTailD nontTail = grammarNodeD as NonterminalTailD;
                String ruleName = nontTail.Reference.Name;

                // traverse from the startsymbol through the grammar
                // if we never find this rule used, offer to remove the rule from the definitive grammar
                GrammarNodeDExistsVisitor visitor = new GrammarNodeDExistsVisitor(ruleName, VADG.Global.SymbolType.Nonterminal);
                model.DefinitiveGrammar.StartSymbol.accept(visitor);

                if (!visitor.Found)
                {
                    if (OfferDeleteRule != null)
                        OfferDeleteRule(nontTail.Reference);
                }
            }

            view.Functions.Delete(itemToDelete);

            ReDraw();
        }
        public void visit(ConcatenationD concatenationD)
        {
            List<GrammarNodeV> children = new List<GrammarNodeV>();

            foreach (GrammarNodeD child in concatenationD.Children)
            {
                // make children
                child.accept(this);
                children.Add(current);
            }

            ConcatenationV concatenationV = new ConcatenationV(children, concatenationD);
            concatenationD.AddReference(concatenationV);

            current = concatenationV;
        }
        public void visit(NonterminalTailD nonterminalTailD)
        {
            NonterminalTailV nonterminalTailV = new NonterminalTailV(nonterminalTailD, level + 1);

            nonterminalTailD.AddReference(nonterminalTailV);

            current = nonterminalTailV;
        }
        public void visit(ChoiceD choiceD)
        {
            List<GrammarNodeV> children = new List<GrammarNodeV>();

            foreach (GrammarNodeD child in choiceD.Children)
            {
                // make children
                child.accept(this);
                children.Add(current);
            }

            ChoiceV choiceV = new ChoiceV(children, choiceD);
            choiceD.AddReference(choiceV);

            current = choiceV;
        }
 public GrammarNodeVAddBeforeVisitor(GrammarNodeV targetIn, GrammarNodeD itemIn)
 {
     target = targetIn;
     item = itemIn;
 }
 public GrammarNodeVAddAfterVisitor(GrammarNodeV targetIn, GrammarNodeD itemIn)
 {
     target = targetIn;
     item = itemIn;
 }
        public void Delete(GrammarNodeV itemToDelete)
        {
            GrammarNodeVDeleteVisitor visitor = new GrammarNodeVDeleteVisitor(itemToDelete.getReference());

            startSymbol.accept(visitor);
        }