/// <summary>
        /// Route ploan for downstream exits
        /// </summary>
        /// <param name="downstreamPoints"></param>
        /// <param name="goal"></param>
        private void DetermineDownstreamPointRouteTimes(List <DownstreamPointOfInterest> downstreamPoints, INavigableNode goal, ArbiterWay aw)
        {
            // so, for each exit downstream we need to plan from the end of each interconnect to the goal
            foreach (DownstreamPointOfInterest dpoi in downstreamPoints)
            {
                // check if exit
                if (dpoi.IsExit)
                {
                    // current best time
                    double bestCurrent = Double.MaxValue;
                    List <INavigableNode> bestRoute        = null;
                    ArbiterInterconnect   bestInterconnect = null;

                    // fake node
                    FakeExitNode fen = new FakeExitNode(dpoi.PointOfInterest);

                    // init fields
                    double timeCost;
                    List <INavigableNode> routeNodes;

                    // plan
                    this.Plan(fen, goal, out routeNodes, out timeCost);

                    bestCurrent      = timeCost;
                    bestRoute        = routeNodes;
                    bestInterconnect = routeNodes.Count > 1 ? fen.GetEdge(routeNodes[1]) : null;

                    // plan from each interconnect to find the best time from exit

                    /*foreach (ArbiterInterconnect ai in dpoi.PointOfInterest.Exits)
                     * {
                     *      // init fields
                     *      double timeCost;
                     *      List<INavigableNode> routeNodes;
                     *
                     *      // plan
                     *      this.Plan(ai.End, goal, out routeNodes, out timeCost);
                     *
                     *      // check
                     *      if (timeCost < bestCurrent)
                     *      {
                     *              bestCurrent = timeCost;
                     *              bestRoute = routeNodes;
                     *              bestInterconnect = ai;
                     *      }
                     * }*/

                    // set best
                    dpoi.RouteTime = bestCurrent;
                    dpoi.BestRoute = bestRoute;
                    dpoi.BestExit  = bestInterconnect;
                }
            }
        }
        /// <summary>
        /// Route ploan for downstream exits
        /// </summary>
        /// <param name="downstreamPoints"></param>
        /// <param name="goal"></param>
        private void RouteTimes(List <DownstreamPointOfInterest> downstreamPoints, INavigableNode goal)
        {
            // check if we are planning over the correct goal
            if (this.currentTimes.Key != CoreCommon.Mission.MissionCheckpoints.Peek().CheckpointNumber ||
                this.currentTimes.Value == null)
            {
                // create new lookup
                this.currentTimes = new KeyValuePair <int, Dictionary <ArbiterWaypointId, DownstreamPointOfInterest> >(
                    CoreCommon.Mission.MissionCheckpoints.Peek().CheckpointNumber, new Dictionary <ArbiterWaypointId, DownstreamPointOfInterest>());
            }

            // so, for each exit downstream we need to plan from the end of each interconnect to the goal
            foreach (DownstreamPointOfInterest dpoi in downstreamPoints)
            {
                // container flag
                bool contains = this.currentTimes.Value.ContainsKey(dpoi.PointOfInterest.WaypointId);

                // check if exit
                if (dpoi.IsExit && !contains)
                {
                    // fake node
                    FakeExitNode fen = new FakeExitNode(dpoi.PointOfInterest);

                    // init fields
                    double timeCost;
                    List <INavigableNode> routeNodes;

                    // plan
                    this.Plan(fen, goal, out routeNodes, out timeCost);

                    // set best
                    dpoi.RouteTime = timeCost;
                    dpoi.BestRoute = routeNodes;
                    dpoi.BestExit  = routeNodes.Count > 1 ? fen.GetEdge(routeNodes[1]) : null;

                    // add to keepers
                    this.currentTimes.Value.Add(dpoi.PointOfInterest.WaypointId, dpoi.Clone());
                }
                else if (dpoi.IsExit && contains)
                {
                    DownstreamPointOfInterest tmp = this.currentTimes.Value[dpoi.PointOfInterest.WaypointId];

                    if (tmp.BestExit == null)
                    {
                        ArbiterOutput.Output("NAV RouteTimes: Removing exit with no valid route: " + dpoi.PointOfInterest.WaypointId.ToString());

                        // remove
                        this.currentTimes.Value.Remove(dpoi.PointOfInterest.WaypointId);
                        dpoi.PointOfInterest = (ArbiterWaypoint)CoreCommon.RoadNetwork.ArbiterWaypoints[dpoi.PointOfInterest.WaypointId];

                        // fake node
                        FakeExitNode fen = new FakeExitNode(dpoi.PointOfInterest);

                        // init fields
                        double timeCost;
                        List <INavigableNode> routeNodes;

                        // plan
                        this.Plan(fen, goal, out routeNodes, out timeCost);

                        // set best
                        dpoi.RouteTime = timeCost;
                        dpoi.BestRoute = routeNodes;
                        dpoi.BestExit  = routeNodes.Count > 1 ? fen.GetEdge(routeNodes[1]) : null;

                        // add to keepers
                        this.currentTimes.Value.Add(dpoi.PointOfInterest.WaypointId, dpoi);
                    }
                    else
                    {
                        dpoi.RouteTime = tmp.RouteTime;
                        dpoi.BestRoute = tmp.BestRoute;
                        dpoi.BestExit  = tmp.BestExit;
                    }
                }
            }
        }