/// <summary>
        /// Crawls this instance.
        /// </summary>
        /// <returns>The solution if found</returns>
        /// <remarks>We have to override this so we can synchonize the forward and reverse crawlers</remarks>
        public override BaseNode Crawl()
        {
            if (!this.reversed)
            {
                BaseNode solution = null;

                while ((!this.IsQueueEmpty() || !reverseCrawler.IsQueueEmpty()) && solution == null)
                {
                    this.EvaluateAndExpandNode(this.PopQueue());
                    reverseCrawler.Crawl();

                    // If there exists a node that both crawlers have found where, combined, a solution is found; that is our winner.
                    List <BaseNode> similarNodes = this.ExploredSet.Where(en => reverseCrawler.ExploredSet.Any(rcEn => rcEn.Key == en.Key)).ToList();
                    foreach (BaseNode similarNode in similarNodes)
                    {
                        foreach (BaseNode possibleSolution in this.reverseCrawler.ExploredSet.Where(en => en.Key == similarNode.Key))
                        {
                            List <Move> movesToGoal = TreeHelpers.ActionTracker(possibleSolution);
                            movesToGoal.Reverse();
                            movesToGoal = TreeHelpers.ReflectMoves(movesToGoal);

                            int          x             = similarNode.X;
                            int          y             = similarNode.Y;
                            List <int[]> newChildState = new List <int[]>();
                            similarNode.CrateLocations.ForEach(state => newChildState.Add(new int[] { state[0], state[1] }));

                            this.MoveToCurrentNode(movesToGoal, ref x, ref y, ref newChildState);

                            if (IsWinningState(newChildState))
                            {
                                return(InvertNodeHeritage(similarNode, possibleSolution.Parent));
                            }
                        }
                    }
                }

                return(solution);
            }
            else
            {
                // If we are the reversed solution, we just need to take the normal steps and return if we found a solution.
                // all the Bi-Directional stuff is done in the non-reversed loop.
                BaseNode reverseSolution;
                reverseSolution = this.EvaluateAndExpandNode(this.PopQueue());
                return(reverseSolution);
            }
        }