public PartialRoute DeepCopy()
            {
                PartialRoute _DeepCopy = new PartialRoute();

                _DeepCopy.partialRoute = partialRoute;                //No deeper copy needed since partial route won't be changed
                foreach (GeocacheRoutingInformation geocacheRoutingInfo in GeocachesInReach)
                {
                    _DeepCopy.GeocachesInReach.Add(new GeocacheRoutingInformation(geocacheRoutingInfo));
                }
                return(_DeepCopy);
            }
        private RouteData FillRouteWithGeocachesUntilMaxDistanceIsReached(RouteData CompleteRouteData)
        {
            Fileoperations.Routerlog.AddSubSection("Entered filling route with geocaches");
            //TODO Make MaxDistance to meters as well
            ///////////////////////////////////////////////////////////////////////////////////////
            //TAKE CARE RouteDistance is in m, MaxDistance in km!!!
            ////////////////////////////////////////////////////////////////////////////////

            GeocacheRoutingInformation GeocacheToAdd = null;

            do
            {
                //Values
                GeocacheToAdd = null;
                Route RouteToInsertIn        = null;
                int   IndexOfRouteToInsertIn = -1;

                #region Filter Geocaches

                /*Remove all Caches that definitely are not in Range (estimated distance, which is the shortest possible distance, bigger than distance set).
                 * Meanwhile find best rated geocache and the route it is the closest to.
                 * Only allow apercentage of the distance set, as the roads are most definitely not straight.
                 * For the case they are, there is another routine that picks up the caches that are directly on the route.
                 */
                Parallel.For(0, CompleteRouteData.partialRoutes.Count, CurrentPartialRouteIndex =>
                {
                    PartialRoute CurrentPartialRoute = CompleteRouteData.partialRoutes[CurrentPartialRouteIndex];
                    List <GeocacheRoutingInformation> GeocachesToRemove = new List <GeocacheRoutingInformation>();
                    foreach (GeocacheRoutingInformation CurrentGeocache in CurrentPartialRoute.GeocachesInReach)
                    {
                        if (CurrentGeocache.EstimatedExtraDistance > (CompleteRouteData.Profile.MaxDistance * 1000 - CompleteRouteData.TotalDistance))
                        {
                            GeocachesToRemove.Add(CurrentGeocache);
                        }
                        else if (CompleteRouteData.GeocachesOnRoute().Contains(CurrentGeocache.geocache))
                        {
                            GeocachesToRemove.Add(CurrentGeocache);
                        }
                        else if (CurrentGeocache.EstimatedExtraDistance < CompleteRouteData.Profile.MaxDistance * 1000 - CompleteRouteData.TotalDistance)
                        {
                            /* If no cache is set as next geocache to insert
                             * If the cache we stumbled accross has more routingpoints than the old cache
                             */
                            if (GeocacheToAdd == null || CurrentGeocache.RoutingPoints > GeocacheToAdd.RoutingPoints)
                            {
                                lock (GeocacheToAddLocker)                                 //Since one can't lock GeocacheToAdd directly, since it is not the same object that is locked and unlocked
                                {
                                    GeocacheToAdd = CurrentGeocache;
                                }
                                lock (RouteToInsertInLocker)                                 //See above
                                {
                                    RouteToInsertIn = CurrentPartialRoute.partialRoute;
                                }
                                IndexOfRouteToInsertIn = CurrentPartialRouteIndex;
                            }
                        }
                    }

                    //Remove all geocaches that can't be reached or are already used
                    foreach (GeocacheRoutingInformation Geocache_Info in GeocachesToRemove)
                    {
                        CurrentPartialRoute.GeocachesInReach.Remove(Geocache_Info);
                    }
                });
                #endregion
                //Won't be able to fit a geocache in
                if (CompleteRouteData.TotalTime + CompleteRouteData.Profile.TimePerGeocache * 60 > CompleteRouteData.Profile.MaxTime * 60)
                {
                    GeocacheToAdd = null;
                }

                if (GeocacheToAdd != null)
                {
                    Result <Tuple <Route, Route> > RoutingResult = GetPartialRoutes(CompleteRouteData, RouteToInsertIn, GeocacheToAdd.ResolvedCoordinates);

                    if (!RoutingResult.IsError)
                    {
                        float NewDistance          = CompleteRouteData.TotalDistance - RouteToInsertIn.TotalDistance + RoutingResult.Value.Item1.TotalDistance + RoutingResult.Value.Item2.TotalDistance;
                        float NewTimeWithGeocaches = CompleteRouteData.TotalTime - RouteToInsertIn.TotalTime + RoutingResult.Value.Item1.TotalTime + RoutingResult.Value.Item2.TotalTime + (CompleteRouteData.GeocachesOnRoute().Count + 1) * CompleteRouteData.Profile.TimePerGeocache * 60;
                        float NewRoutePoints       = CompleteRouteData.TotalPoints + GeocacheToAdd.geocache.Rating;

                        //calculate in meters
                        if (NewDistance < CompleteRouteData.Profile.MaxDistance * 1000 && NewTimeWithGeocaches < CompleteRouteData.Profile.MaxTime * 60)
                        {
                            Debug.WriteLine("Added " + GeocacheToAdd.geocache);
                            CompleteRouteData = ReplaceRoute(CompleteRouteData, RoutingResult.Value.Item1, RoutingResult.Value.Item2, IndexOfRouteToInsertIn);
                            CompleteRouteData.AddGeocacheOnRoute(GeocacheToAdd.geocache);
                            CompleteRouteData.TotalPoints = NewRoutePoints;                            //Overwrites the addition automatically made in the lne before, to make sure the
                            DisplayPreliminaryRoute(CompleteRouteData);
                        }
                        else
                        {
                            Debug.WriteLine("Made calculation for nothing. Route was longer in distance or time than allowed");
                            CompleteRouteData.partialRoutes[IndexOfRouteToInsertIn].GeocachesInReach.Remove(GeocacheToAdd);                            //As the geocache doesn't help from this route
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Routing was errounous. Island detection score:" + FailedRouteCalculations);
                        CompleteRouteData.partialRoutes[IndexOfRouteToInsertIn].GeocachesInReach.Remove(GeocacheToAdd);                        //Since trying to route to it results in an error
                    }
                }
            } while (FailedRouteCalculations < FailedRouteCalculationsLimit && GeocacheToAdd != null);

            return(CompleteRouteData);
        }