/// <summary>Returns an <c>IPath</c> for the optimal path from coordinates <c>start</c> to <c>goal</c>.</summary>
        /// <param name="start">Coordinates for the <c>last</c> step on the desired path.</param>
        /// <param name="goal">Coordinates for the <c>first</c> step on the desired path.</param>
        /// <param name="stepCost">Cost to extend path by hex at <c>coords</c> from hex at direction <c>hexside</c>.</param>
        /// <param name="landmarks"><c>LandmarkCollection</c> of landmarks available for heuristic calculation.</param>
        static PathHalves FindDirectedPath(
            IHex start, IHex goal,
            Func <IHex, Hexside, int> stepCost,
            LandmarkCollection landmarks
            )
        {
            if (start == null)
            {
                throw new ArgumentNullException("start");
            }
            if (goal == null)
            {
                throw new ArgumentNullException("goal");
            }
            if (stepCost == null)
            {
                throw new ArgumentNullException("stepCost");
            }
            if (landmarks == null)
            {
                throw new ArgumentNullException("landmarks");
            }

            TraceFlags.FindPathDetail.Trace(true,
                                            "Fwd: Find path from {0} to {1}:", start.Coords, goal.Coords);

            var closed     = new HashSet <HexCoords>();
            var pathHalves = new PathHalves();

            var pathfinderFwd = new PathfinderFwd(start, goal, stepCost, landmarks,
                                                  closed, pathHalves.SetBestSoFar, () => pathHalves.BestSoFar);
            var pathfinderRev = new PathfinderRev(start, goal, stepCost, landmarks,
                                                  closed, pathHalves.SetBestSoFar, () => pathHalves.BestSoFar);

            pathfinderFwd.Partner = pathfinderRev;
            var pathfinder = pathfinderRev.Partner
                                 = pathfinderFwd;

            while (!pathfinder.IsFinished())
            {
                pathfinder = pathfinder.Partner;
            }

            return(pathHalves);
        }
        /// <summary>Returns an <c>IPath</c> for the optimal path from coordinates <c>start</c> to <c>goal</c>.</summary>
        /// <param name="start">Coordinates for the <c>last</c> step on the desired path.</param>
        /// <param name="goal">Coordinates for the <c>first</c> step on the desired path.</param>
        /// <param name="stepCost">Cost to extend path by hex at <c>coords</c> from hex at direction <c>hexside</c>.</param>
        /// <param name="landmarks"><c>LandmarkCollection</c> of landmarks available for heuristic calculation.</param>
        static PathHalves FindDirectedPath(
          IHex start, IHex goal,
          Func<IHex, Hexside, double> stepCost,
          LandmarkCollection landmarks
        )
        {
            if (start == null) throw new ArgumentNullException("start");
            if (goal == null) throw new ArgumentNullException("goal");
            if (stepCost == null) throw new ArgumentNullException("stepCost");
            if (landmarks == null) throw new ArgumentNullException("landmarks");

            var closed = new HashSet<HexCoords>();
            var pathHalves = new PathHalves();

            var pathfinderFwd = new PathfinderFwd(start, goal, stepCost, landmarks,
                                closed, pathHalves.SetBestSoFar, () => pathHalves.BestSoFar);
            var pathfinderRev = new PathfinderRev(start, goal, stepCost, landmarks,
                                closed, pathHalves.SetBestSoFar, () => pathHalves.BestSoFar);

            pathfinderFwd.Partner = pathfinderRev;
            var pathfinder = pathfinderRev.Partner
                                  = pathfinderFwd;
            while (!pathfinder.IsFinished()) pathfinder = pathfinder.Partner;

            return pathHalves;
        }