private static ScriptResult RunNode(ScriptNode script,
                                            Stack <NodeStackItem> nodestack,
                                            NodeStackItem current,
                                            ProgramCounter programIndex,
                                            ProgramData programData) // TODO Change
        {
            // Only execute container nodes:
            if (current.Node.NodeType == NodeType.Script ||
                current.Node.NodeType == NodeType.Page ||
                current.Node.NodeType == NodeType.OptionsChoice ||
                current.Node.NodeType == NodeType.Option ||
                current.Node.NodeType == NodeType.OnceOnly ||
                current.Node.NodeType == NodeType.ConditionalTrue ||
                current.Node.NodeType == NodeType.ConditionalFalse ||
                current.Node.NodeType == NodeType.BlockNode ||
                current.Node.NodeType == NodeType.ParallelNode ||
                current.Node.NodeType == NodeType.ConditionalIf
                )
            {
                // Run the children
                if (current.Index >= current.Node.Children.Count)
                {
                    nodestack.Pop();
                    return(ScriptResult.Running);
                }

                var childNode = current.Node.Children[current.Index];
                if (childNode.NodeType == NodeType.Page)
                {
                    nodestack.Push(new NodeStackItem(current.Node.Children[0], 0));
                    return(ScriptResult.Running);
                }

                var returnResult = childNode.Run(ref programIndex, ref programData);
                if (returnResult == NodeRunResult.Await)
                {
                    // return and then re-enter on this node
                    return(ScriptResult.Yielded);
                }

                // Result filter
                if (returnResult == NodeRunResult.NextCommand)
                {
                    current.Index += 1;
                    if (current.Index >= current.Node.Children.Count)
                    {
                        LevelUp(nodestack);
                        return(ScriptResult.Running);
                    }
                    return(ScriptResult.Running);
                }
                else if (returnResult == NodeRunResult.PushPage)
                {
                    nodestack.Push(new NodeStackItem(childNode, current.Index)); // Add a CallNode so we know where to return to.
                    var pageNode = script.FindPageByName(programIndex.ReturnRegisterString);
                    nodestack.Push(new NodeStackItem(pageNode, 0));              // Our new target PageNode
                    return(ScriptResult.Running);
                }
                else if (returnResult == NodeRunResult.PopPage)
                {
                    LevelUp(nodestack);
                    return(ScriptResult.Running);
                }
                else if (returnResult == NodeRunResult.PushChildN)
                {
                    nodestack.Push(new NodeStackItem(childNode, programIndex.ReturnRegisterInt32)); // Push current node to return to
                    return(ScriptResult.Running);
                }
                else if (returnResult == NodeRunResult.PushChildFirst)
                {
                    nodestack.Push(new NodeStackItem(childNode, 0)); // Push current node to return to
                    return(ScriptResult.Running);
                }
                else if (returnResult == NodeRunResult.PushChildTrue)
                {
                    // TODO Find childnode that is true rather than assume first
                    nodestack.Push(new NodeStackItem(childNode, 0)); // Push current node to return to
                    return(ScriptResult.Running);
                }
                else if (returnResult == NodeRunResult.PushChildFalse)
                {
                    // TODO Find childnode that is false rather than assume second
                    nodestack.Push(new NodeStackItem(childNode, 1));
                    return(ScriptResult.Running);
                }

                else if (returnResult == NodeRunResult.PushParallel)
                {
                    // Add all block children to a new parallel stack

                    for (int i = childNode.Children.Count - 1; i >= 0; i--)
                    {
                        var pstack = new Stack <NodeStackItem>(); // TODO From pool

                        var c = childNode.Children[i];
                        pstack.Push(new NodeStackItem(c, 0));
                        programIndex.ParallelStack.Add(pstack);
                    }

                    // Go to the next node when we are ready
                    current.Index += 1;
                    if (current.Index >= current.Node.Children.Count)
                    {
                        LevelUp(nodestack);
                        return(ScriptResult.Running);
                    }
                    return(ScriptResult.Running);
                }
                else
                {
                    Console.WriteLine("TODO Implement Return Result: " + returnResult);
                    return(ScriptResult.Running);
                }
            }
            else
            {
                Console.WriteLine("TODO Implement NodeType: " + current.Node.NodeType);
            }

            return(ScriptResult.Running);
        }