Inheritance: DialogueNode, IRegisteredDialogueNode
        private void PrintWaitDialogueNode(WaitDialogueNode pWaitNode)
        {
            Indentation();
            _output.Append("WAIT_UNTIL expressions: ");

            foreach (var e in pWaitNode.expressions)
            {
                _output.Append(e.expression + ", ");
            }
            if (pWaitNode.eventName != "")
            {
                _output.Append("LISTEN for event: " + pWaitNode.eventName);
            }
            _output.Append("\n");

            DialogueNode nextNode = _dialogueRunner.GetDialogueNode(_conversation, pWaitNode.nextNode);

            SwitchOnNode(nextNode);
        }
        private void PrintWaitDialogueNode(WaitDialogueNode pWaitNode)
        {
            Indentation();
            _output.Append("WAIT_UNTIL expressions: ");

            foreach(var e in pWaitNode.expressions) {
                _output.Append(e.expression + ", ");
            }
            if(pWaitNode.eventName != "") {
                _output.Append("LISTEN for event: " + pWaitNode.eventName);
            }
            _output.Append("\n");

            DialogueNode nextNode = _dialogueRunner.GetDialogueNode(_conversation, pWaitNode.nextNode);
            SwitchOnNode(nextNode);
        }
        private void PrintWaitDialogueNode(WaitDialogueNode pWaitNode)
        {
            Indentation();
            _output.Append("WAIT_UNTIL "); // + pWaitNode.expression + "\n");

            DialogueNode nextNode = _dialogueRunner.GetDialogueNode(_conversation, pWaitNode.nextNode);
            SwitchOnNode(nextNode);
        }
        private WaitDialogueNode VisitWaitDialogueNode(DialogueNode pPrevious)
        {
                        #if DEBUG_WRITE
            Console.WriteLine("WaitDialogueNode()");
                        #endif

            match(Token.TokenType.WAIT);

            WaitDialogueNode n = _dialogueRunner.Create <WaitDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (start commando)");

            List <ExpressionDialogueNode> expressionNodes = new List <ExpressionDialogueNode>();

            bool hasEventListener = false;

            while (true)
            {
                if (lookAheadType(1) == Token.TokenType.NAME)
                {
                    string   expressionName = "";
                    string[] args           = VisitFunctionCall(out expressionName);

                    ExpressionDialogueNode expressionNode = _dialogueRunner.Create <ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (expression)");
                    expressionNode.expression = expressionName;
                    expressionNode.args       = args;
                    expressionNodes.Add(expressionNode);
                }
                else if (lookAheadType(1) == Token.TokenType.AND)
                {
                    ConsumeCurrentToken();
                }
                else if (lookAheadType(1) == Token.TokenType.LISTEN)
                {
                    if (hasEventListener)
                    {
                        throw new GrimmException(_conversationName + " already has a event listener attached to the wait statement on line " + lookAhead(1).LineNr);
                    }
                    ConsumeCurrentToken();
                    n.eventName      = match(Token.TokenType.NAME).getTokenString();
                    hasEventListener = true;
                                        #if DEBUG_WRITE
                    Console.WriteLine("This WaitDialogueNode has an event called " + n.eventName);
                                        #endif
                }
                else
                {
                    break;
                }
            }

            n.expressions = expressionNodes.ToArray();

            string handleName = "";
            if (lookAheadType(1) == Token.TokenType.BRACKET_LEFT)
            {
                match(Token.TokenType.BRACKET_LEFT);
                Token handleToken = match(Token.TokenType.NAME);
                handleName = handleToken.getTokenString();
                match(Token.TokenType.BRACKET_RIGHT);
            }

            n.handle = handleName;

            if (_loopStack.Count > 0)
            {
                // Add this listening dialogue node to the scope of the loop so that it is automatically removed when the loop ends
                n.scopeNode = _loopStack.Peek().name;
            }

                        #if DEBUG_WRITE
            Console.WriteLine("Added WaitDialogueNode() with name '" + n.name + "'");
                        #endif

            //if(!_dialogueRunner.HasExpression(expressionName)) {
            //throw new GrimmException("There is no '" + expressionName + "' expression registered in the dialogue runner");
            //}

            SilentDialogueNode silentEndNode = _dialogueRunner.Create <SilentDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(silent stop node)");

            AllowLineBreak();

            if (lookAheadType(1) == Token.TokenType.BLOCK_BEGIN)
            {
                _loopStack.Push(n);

                ImmediateNode eventBranchStartNode = _dialogueRunner.Create <ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(waitBranchStartNode)");
                n.branchNode = eventBranchStartNode.name;
                n.hasBranch  = true;
                match(Token.TokenType.BLOCK_BEGIN);
                Nodes(eventBranchStartNode, silentEndNode);
                match(Token.TokenType.BLOCK_END);

                _loopStack.Pop();
            }
            else
            {
                                #if DEBUG_WRITE
                Console.WriteLine("this wait dialogue node had no body");
                                #endif
            }

            AddLinkFromPreviousNode(pPrevious, n);

            return(n);
        }