public static Map solver(Search search, Map map, Stopwatch stopwatch)
        {
            actorpos = new int[16, 16];
            boxpos   = new int[16, 16];

            search.addToFrontier(map);

            int i = -1;

            while (search.frontierSize() > 0)
            {
                i++;
                if (i == 10000)
                {
                    Console.Error.Write("Time:  {0:0.000}\t Explored: {1}\t Frontier: {2}\n", stopwatch.Elapsed.TotalSeconds, search.exploredSize() - search.frontierSize(), search.frontierSize());
                    i = 0;
                }
                Map smap = search.getFromFrontier();

                Actor ac = smap.getActor(0);
                Node  n  = smap.getbox(0);
                System.Console.WriteLine("" + ac.x + " " + ac.y + " " + n.x + " " + n.y);
                actorpos[ac.x, ac.y]++;
                boxpos[n.x, n.y]++;

                /*
                 * if (smap.isGoal()) { return smap; }
                 *
                 * Heuristic h2 = new BFS(smap);
                 *
                 * Search search2 = new Search(h2);
                 *
                 * //Console.Error.WriteLine("Initialized after {0:0.000}", stopwatch.Elapsed.TotalSeconds);
                 *
                 * Map finalmap = solver2(search2, smap, stopwatch);
                 * if (finalmap == null)
                 * {
                 *  Console.Error.WriteLine("Frontier was emptied! No solution found. Explored: {0}", search.exploredSize());
                 *  return null;
                 * }
                 * else
                 * {
                 *  MLInput mlin = new MLInput(smap);
                 *  mlin.run(finalmap.steps);
                 *
                 * }*/
                if (smap.isGoal())
                {
                    return(smap);
                }

                HashSet <act>[] actionlist = smap.getAllActions();


                IEnumerator <act>[] enumerators = new IEnumerator <act> [actionlist.Count()];
                for (int j = 0; j < actionlist.Count(); j++)
                {
                    enumerators[j] = actionlist[j].GetEnumerator();
                    enumerators[j].MoveNext();
                }
                bool run = true;
                while (run)
                {
                    act[] actions = new act[enumerators.Count()];
                    for (int j = 0; j < enumerators.Count(); j++)
                    {
                        actions[j] = enumerators[j].Current;
                    }
                    int k = 0;
                    while (!enumerators[k].MoveNext())
                    {
                        enumerators[k].Reset();
                        enumerators[k].MoveNext();
                        k++;
                        if (k == enumerators.Count())
                        {
                            run = false; break;
                        }
                    }
                    Map nmap = new Map(smap);
                    if (nmap.PerformActions(actions))
                    {
                        //if (nmap.isGoal()) { return nmap; }
                        search.addToFrontier(nmap);
                    }
                }


                /*foreach (HashSet<act> actorlist in actionlist)
                 * {
                 *  foreach (act action in actorlist)
                 *  {
                 *
                 *      act[] actions = new act[1];
                 *      actions[0] = action;
                 *      if (nmap.PerformActions(actions))
                 *      {
                 *          if (nmap.isGoal()) { return nmap; }
                 *          search.addToFrontier(nmap);
                 *      }
                 *  }
                 * }*/
            }

            return(null);
        }
        public static LinkedList <act[]> restoreactions(Map map)
        {
            LinkedList <act[]> actions;

            if (map.parent != null)
            {
                actions = restoreactions(map.parent);
            }
            else
            {
                actions = new LinkedList <act[]>(); return(actions);
            }

            Actor[] actors       = map.getActors();
            Actor[] parentactors = map.parent.getActors();

            int actorcount = actors.Count();

            act[] actiongroup = new act[actorcount];

            for (int i = 0; i < actorcount; i++)
            {
                if (actors[i].y < parentactors[i].y)
                {
                    actiongroup[i] = new act(Interact.MOVE, Direction.N);
                }
                else if (actors[i].y > parentactors[i].y)
                {
                    actiongroup[i] = new act(Interact.MOVE, Direction.S);
                }
                else if (actors[i].x < parentactors[i].x)
                {
                    actiongroup[i] = new act(Interact.MOVE, Direction.W);
                }
                else if (actors[i].x > parentactors[i].x)
                {
                    actiongroup[i] = new act(Interact.MOVE, Direction.E);
                }
                else
                {
                    actiongroup[i] = new act(Interact.WAIT);
                }
                int box;
                if (map.parent.isBox(actors[i].x, actors[i].y, actors[i].getcolor(), out box))
                {
                    Node newbox = map.parent.getbox(box);
                    Node oldbox = map.getbox(box);
                    if (oldbox.y < newbox.y)
                    {
                        actiongroup[i] = new act(Interact.PUSH, actiongroup[i].dir, Direction.N, box);
                    }
                    else if (oldbox.y > newbox.y)
                    {
                        actiongroup[i] = new act(Interact.PUSH, actiongroup[i].dir, Direction.S, box);
                    }
                    else if (oldbox.x < newbox.x)
                    {
                        actiongroup[i] = new act(Interact.PUSH, actiongroup[i].dir, Direction.W, box);
                    }
                    else if (oldbox.x > newbox.x)
                    {
                        actiongroup[i] = new act(Interact.PUSH, actiongroup[i].dir, Direction.E, box);
                    }
                }
                else if (map.isBox(parentactors[i].x, parentactors[i].y, parentactors[i].getcolor(), out box))
                {
                    Node newbox = map.parent.getbox(box);
                    Node oldbox = map.getbox(box);

                    // Opposite directions for pull. It's what the server wants!
                    if (oldbox.y < newbox.y)
                    {
                        actiongroup[i] = new act(Interact.PULL, actiongroup[i].dir, Direction.S, box);
                    }
                    else if (oldbox.y > newbox.y)
                    {
                        actiongroup[i] = new act(Interact.PULL, actiongroup[i].dir, Direction.N, box);
                    }
                    else if (oldbox.x < newbox.x)
                    {
                        actiongroup[i] = new act(Interact.PULL, actiongroup[i].dir, Direction.E, box);
                    }
                    else if (oldbox.x > newbox.x)
                    {
                        actiongroup[i] = new act(Interact.PULL, actiongroup[i].dir, Direction.W, box);
                    }
                }
            }

            actions.AddLast(actiongroup);
            return(actions);
        }