private void PrintTreeWithLevels(Node node, Level level, PathFinder pathFinder)
        {
            Print(node);
            HashKey hashKey = GetPrintHashKey(level, pathFinder);
            if (transpositionTable.ContainsKey(hashKey))
            {
                Node other = transpositionTable[hashKey];
                Log.DebugPrint("table node: {0}", Node.IsEmpty(other) ? -1 : other.ID);
            }
            else
            {
                Log.DebugPrint("not in table");
            }
            Print(level);

            MoveState state = new MoveState();
            state.PrepareToMove(node, ref current);

            foreach (Node child in node.Children)
            {
                state.DoMove(child, ref current);

                PrintTreeWithLevels(child, level, pathFinder);

                state.UndoMove(ref current);
            }

            state.FinishMoving(ref current);
        }
        private void Search(Node node)
        {
            // Check for cancel.
            if (cancelInfo.Cancel)
            {
                return;
            }

            MoveState state = new MoveState();
            state.PrepareToMove(node, ref current);

            int score = Node.MaxScore;
            Node previous = node;
            for (Node child = node.Child; !Node.IsEmpty(child); child = child.Sibling)
            {
                if (child.Terminal)
                {
                    // Another node displaced this node from the transposition table.
                    RemoveDescendants(child);
                    RemoveScore(child);
                    node.Remove(previous, child);
                    nodes.Release(child);
                    continue;
                }

                if (child.Score > scoreLimit)
                {
                    if (child.Score < score)
                    {
                        score = child.Score;
                    }
                    previous = child;
                    continue;
                }

                state.DoMove(child, ref current);

                if (child.Searched)
                {
                    Search(child);
                    if (!child.HasChildren)
                    {
                        node.Remove(previous, child);
                        RemoveScore(child);
                        if (child.InTable)
                        {
                            child.Dormant = true;
                        }
                        else
                        {
                            nodes.Release(child);
                        }
                        goto removed;
                    }
                }
                else
                {
                    // Remove the unsearched score.
#if false
                    int oldScore = child.Score;
#endif
                    RemoveScore(child);

                    // Search the child node.
                    child.Searched = true;

                    if (level.IsComplete)
                    {
                        child.Complete = true;
                        CollectSolution(child);
                        node.Remove(previous, child);
                        child.Dormant = true;
                        RemoveScore(child);
                        goto removed;
                    }

                    if (IsTerminal(ref state, child) || !FindChildren(child))
                    {
                        node.Remove(previous, child);
                        if (child.InTable)
                        {
                            // Node had no children so it is effectively deadlocked.
                            transpositionTable[current.HashKey] = Node.Empty;
                        }
                        RemoveScore(child);
                        nodes.Release(child);
                        goto removed;
                    }

#if false
                    // XXX: This works but doesn't seem to help.
                    if (child.Score == oldScore)
                    {
                        Search(child);
                        if (!child.HasChildren)
                        {
                            node.Remove(nodes, previous, child);
                            RemoveScore(child);
                            if (child.InTable)
                            {
                                child.Dormant = true;
                            }
                            else
                            {
                                child.Release(nodes);
                            }
                            goto removed;
                        }
                    }
#endif
                }

                if (child.Score < score)
                {
                    score = child.Score;
                }

                previous = child;

            removed:

                state.UndoMove(ref current);
            }
            SetScore(node, score);

            state.FinishMoving(ref current);
        }
        private void Search(Node node)
        {
            // Check for cancel.
            if (cancelInfo.Cancel)
            {
                return;
            }

            MoveState state = new MoveState();
            state.PrepareToMove(node, ref current);

            Node previous = node;
            for (Node child = node.Child; !Node.IsEmpty(child); child = child.Sibling)
            {
                if (child.Terminal)
                {
                    // Another node displaced this node from the transposition table.
                    RemoveDescendants(child);
                    node.Remove(previous, child);
                    nodes.Release(child);
                    continue;
                }

                state.DoMove(child, ref current);

                if (child.Searched)
                {
                    Search(child);
                    if (!child.HasChildren)
                    {
                        node.Remove(previous, child);
                        if (child.InTable)
                        {
                            child.Dormant = true;
                        }
                        else
                        {
                            nodes.Release(child);
                        }
                        goto removed;
                    }
                }
                else
                {
                    // Search the child node.
                    child.Searched = true;

                    if (level.IsComplete)
                    {
                        child.Complete = true;
                        CollectSolution(child);
                        node.Remove(previous, child);
                        child.Dormant = true;
                        goto removed;
                    }

                    if (IsTerminal(ref state, child) || !FindChildren(child))
                    {
                        node.Remove(previous, child);
                        if (child.InTable)
                        {
                            // Node had no children so it is effectively deadlocked.
                            transpositionTable[current.HashKey] = Node.Empty;
                        }
                        nodes.Release(child);
                        goto removed;
                    }
                }

                previous = child;

            removed:

                state.UndoMove(ref current);
            }

            state.FinishMoving(ref current);
        }