/// <summary>
        /// Creates a new visit list by copying an existing visit list.
        /// </summary>
        /// <param name="source"></param>
        public PathSegmentVisitList(PathSegmentVisitList source)
        {
            _visit_list = new SortedList<double, Dictionary<long, PathSegment<long>>>();
            _visited = new Dictionary<long, double>();

            foreach (KeyValuePair<double, Dictionary<long, PathSegment<long>>> pair in source._visit_list)
            {
                Dictionary<long, PathSegment<long>> dic = new Dictionary<long, PathSegment<long>>();
                foreach (KeyValuePair<long, PathSegment<long>> path_pair in pair.Value)
                {
                    dic.Add(path_pair.Key, path_pair.Value);
                }
                _visit_list.Add(pair.Key, dic);
            }

            foreach (KeyValuePair<long, double> pair in source._visited)
            {
                _visited.Add(pair.Key, pair.Value);
            }
        }
        /// <summary>
        /// Called left before the contraction.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="edges"></param>
        void pre_processor_OnBeforeContractionEvent(uint vertex, KeyValuePair<uint, CHEdgeData>[] edges)
        {
            // create a new CHRouter
            CHRouter router = new CHRouter(_data);

            // calculate all the routes between the neighbours of the contracted vertex.
            _paths_before_contraction =
                new Dictionary<uint, Dictionary<uint, PathSegment<long>>>();
            foreach (KeyValuePair<uint, CHEdgeData> from in edges)
            {
                // initialize the from-list.
                PathSegmentVisitList from_list = new PathSegmentVisitList();
                from_list.UpdateVertex(new PathSegment<long>(from.Key));

                // initalize the from dictionary.
                Dictionary<uint, PathSegment<long>> from_dic = new Dictionary<uint, PathSegment<long>>();
                _paths_before_contraction[from.Key] = from_dic;
                foreach (KeyValuePair<uint, CHEdgeData> to in edges)
                {
                    // initialize the to-list.
                    PathSegmentVisitList to_list = new PathSegmentVisitList();
                    to_list.UpdateVertex(new PathSegment<long>(to.Key));

                    // calculate the route.
                    PathSegment<long> route = router.Calculate(_data, _interpreter, OsmSharp.Routing.VehicleEnum.Car, from_list, to_list, double.MaxValue);
                    from_dic[to.Key] = route;
                }
            }
        }
        /// <summary>
        /// Called right after the contraction.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="edges"></param>
        void pre_processor_OnAfterContractionEvent(uint vertex, KeyValuePair<uint, CHEdgeData>[] edges)
        {
            // create a new CHRouter
            CHRouter router = new CHRouter(_data);

            // calculate all the routes between the neighbours of the contracted vertex.
            foreach (KeyValuePair<uint, CHEdgeData> from in edges)
            {
                // initialize the from-list.
                PathSegmentVisitList from_list = new PathSegmentVisitList();
                from_list.UpdateVertex(new PathSegment<long>(from.Key));

                // initalize the from dictionary.
                Dictionary<uint, PathSegment<long>> from_dic = _paths_before_contraction[from.Key];
                foreach (KeyValuePair<uint, CHEdgeData> to in edges)
                {
                    // initialize the to-list.
                    PathSegmentVisitList to_list = new PathSegmentVisitList();
                    to_list.UpdateVertex(new PathSegment<long>(to.Key));

                    // calculate the route.
                    PathSegment<long> route = router.Calculate(_data, _interpreter, OsmSharp.Routing.VehicleEnum.Car, from_list, to_list, double.MaxValue);
                    if ((from_dic[to.Key] == null && route != null) ||
                        (from_dic[to.Key] != null && route == null) ||
                        ((from_dic[to.Key] != null && route != null) && from_dic[to.Key] != route))
                    { // the route match!
                        Assert.Fail("Routes are different before/after contraction!");
                    }
                }
            }
        }