/// <summary>
        /// Called left before the contraction.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="edges"></param>
        void pre_processor_OnBeforeContractionEvent(uint vertex, List <Edge <CHEdgeData> > edges)
        {
            // create a new CHRouter
            var router = new CHRouter();

            // calculate all the routes between the neighbours of the contracted vertex.
            var pathsBeforeContraction = new Dictionary <uint, Dictionary <uint, PathSegment <long> > >();

            _pathsBeforeContraction.Add(vertex, pathsBeforeContraction);
            foreach (var from in edges)
            {
                // initialize the from-list.
                var fromList = new PathSegmentVisitList();
                fromList.UpdateVertex(new PathSegment <long>(from.Neighbour));

                // initalize the from dictionary.
                var fromDic = new Dictionary <uint, PathSegment <long> >();
                pathsBeforeContraction[from.Neighbour] = fromDic;
                foreach (var to in edges)
                {
                    // initialize the to-list.
                    var toList = new PathSegmentVisitList();
                    toList.UpdateVertex(new PathSegment <long>(to.Neighbour));

                    // calculate the route.
                    fromDic[to.Neighbour] = router.Calculate(_data, _interpreter,
                                                             Vehicle.Car, fromList, toList, double.MaxValue, null);;
                }
            }
        }
        /// <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
            var router = new CHRouter(_data);

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

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

                    // calculate the route.
                    PathSegment <long> route = router.Calculate(_data, _interpreter,
                                                                OsmSharp.Routing.Vehicle.Car, fromList, toList, double.MaxValue);
                    fromDic[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
            var 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.
                var fromList = new PathSegmentVisitList();
                fromList.UpdateVertex(new PathSegment <long>(from.Key));

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

                    // calculate the route.
                    PathSegment <long> route = router.Calculate(_data, _interpreter, OsmSharp.Routing.Vehicle.Car, fromList, toList, double.MaxValue);
                    if ((fromDic[to.Key] == null && route != null) ||
                        (fromDic[to.Key] != null && route == null) ||
                        ((fromDic[to.Key] != null && route != null) && fromDic[to.Key] != route))
                    { // the route match!
                        Assert.Fail("Routes are different before/after contraction!");
                    }
                }
            }
        }
        /// <summary>
        /// Called right after the contraction.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="edges"></param>
        void pre_processor_OnAfterContractionEvent(uint vertex, List <Edge <CHEdgeData> > edges)
        {
            // get dictionary for vertex.
            var pathsBeforeContraction = _pathsBeforeContraction[vertex];

            // create a new CHRouter
            var router = new CHRouter();

            // calculate all the routes between the neighbours of the contracted vertex.
            foreach (var from in edges)
            {
                // initialize the from-list.
                var fromList = new PathSegmentVisitList();
                fromList.UpdateVertex(new PathSegment <long>(from.Neighbour));

                // initalize the from dictionary.
                var fromDic = pathsBeforeContraction[from.Neighbour];
                foreach (var to in edges)
                {
                    // initialize the to-list.
                    var toList = new PathSegmentVisitList();
                    toList.UpdateVertex(new PathSegment <long>(to.Neighbour));

                    // calculate the route.
                    var route = router.Calculate(_data, _interpreter, Vehicle.Car, fromList, toList, double.MaxValue, null);
                    if ((fromDic[to.Neighbour] == null && route != null) ||
                        (fromDic[to.Neighbour] != null && route == null))
                    { // the route match!
                        Assert.Fail("Routes are different before/after contraction!");
                    }
                    else if (fromDic[to.Neighbour] != null && route != null)
                    {
                        this.ComparePaths(fromDic[to.Neighbour], route);
                    }
                }
            }

            if (_referenceRouter != null)
            { // do crazy verification!
                var chRouter = Router.CreateCHFrom(_data, router, new OsmRoutingInterpreter());

                // loop over all nodes and resolve their locations.
                var resolvedReference = new RouterPoint[_data.VertexCount - 1];
                var resolved          = new RouterPoint[_data.VertexCount - 1];
                for (uint idx = 1; idx < _data.VertexCount; idx++)
                { // resolve each vertex.
                    float latitude, longitude;
                    if (_data.GetVertex(idx, out latitude, out longitude))
                    {
                        resolvedReference[idx - 1] = _referenceRouter.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude));
                        resolved[idx - 1]          = chRouter.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude));
                    }

                    Assert.IsNotNull(resolvedReference[idx - 1]);
                    Assert.IsNotNull(resolved[idx - 1]);

                    Assert.AreEqual(resolvedReference[idx - 1].Location.Latitude,
                                    resolved[idx - 1].Location.Latitude, 0.0001);
                    Assert.AreEqual(resolvedReference[idx - 1].Location.Longitude,
                                    resolved[idx - 1].Location.Longitude, 0.0001);
                }

                // limit tests to a fixed number.
                int maxTestCount   = 100;
                int testEveryOther = (resolved.Length * resolved.Length) / maxTestCount;
                testEveryOther = System.Math.Max(testEveryOther, 1);

                // check all the routes having the same weight(s).
                for (int fromIdx = 0; fromIdx < resolved.Length; fromIdx++)
                {
                    for (int toIdx = 0; toIdx < resolved.Length; toIdx++)
                    {
                        int testNumber = fromIdx * resolved.Length + toIdx;
                        if (testNumber % testEveryOther == 0)
                        {
                            Route referenceRoute = _referenceRouter.Calculate(Vehicle.Car,
                                                                              resolvedReference[fromIdx], resolvedReference[toIdx]);
                            Route route = chRouter.Calculate(Vehicle.Car,
                                                             resolved[fromIdx], resolved[toIdx]);

                            if (referenceRoute != null)
                            {
                                Assert.IsNotNull(referenceRoute);
                                Assert.IsNotNull(route);
                                this.CompareRoutes(referenceRoute, route);
                            }
                        }
                    }
                }
            }

            _pathsBeforeContraction.Remove(vertex);
        }