/// <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();

            // 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!");
                    }
                }
            }

            if (_referenceRouter != null)
            { // do crazy verification!
                Router 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);
                            }
                        }
                    }
                }
            }
        }
        /// <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();

            // 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!");
                    }
                }
            }
        }