/// <summary>
        /// Method gets route directions.
        /// </summary>
        /// <param name="batchRouteResponse">Batch route response.</param>
        /// <param name="routeId">Route id.</param>
        /// <returns>Route directions.</returns>
        private static RouteDirections _FindRouteDirections(
            BatchRouteSolveResponse batchRouteResponse,
            Guid routeId)
        {
            Debug.Assert(batchRouteResponse != null);
            Debug.Assert(batchRouteResponse.Responses != null);

            RouteDirections foundDirs = null;
            foreach (RouteSolveResponse resp in batchRouteResponse.Responses)
            {
                if (resp.Directions != null &&
                    resp.Directions.Length > 0)
                {
                    // we use one request per route, so we get first directions element
                    RouteDirections routeDirs = resp.Directions[0];

                    Guid dirsRouteId = _StringToObjectId(routeDirs.RouteName);
                    if (dirsRouteId == routeId)
                    {
                        foundDirs = routeDirs;
                        break;
                    }
                }
            }

            return foundDirs;
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        public IList<RouteResult> Convert(GPRouteResult gpResult,
            BatchRouteSolveResponse routeResponse,
            SubmitVrpJobRequest request)
        {
            Debug.Assert(gpResult != null);
            Debug.Assert(request != null);

            var directionsFeatures = default(ILookup<Guid, GPFeature>);
            if (gpResult.Directions != null)
            {
                directionsFeatures = gpResult.Directions.Features.ToLookup(feature =>
                    _AttrToObjectId(NAAttribute.ROUTE_NAME, feature.Attributes));
            }

            var hasDirections = routeResponse != null || directionsFeatures != null;

            // route results
            var results = new List<RouteResult>();
            foreach (GPFeature feature in gpResult.Routes.Features)
            {
                // check violation status
                if (!_IsObjectViolated(feature))
                {
                    // route id
                    Guid routeId = _AttrToObjectId(NAAttribute.NAME, feature.Attributes);

                    // find route
                    Route route = DataObjectHelper.FindObjectById<Route>(routeId, _schedule.Routes);

                    if (route == null)
                    {
                        string message = Properties.Messages.Error_InvalidGPFeatureMapping;
                        throw new RouteException(message); // exception
                    }

                    List<StopData> stops = _GetRouteStops(gpResult, route, request);
                    // Get directions for route
                    if (stops.Count != 0 && hasDirections)
                    {
                        var directions = default(IEnumerable<DirectionEx>);

                        if (routeResponse != null)
                        {
                            // Use Routing service directions.
                            var routeDirs = _FindRouteDirections(routeResponse, routeId);
                            if (routeDirs == null || !_ContainsDirFeatures(routeDirs))
                            {   // route has stops, so there must be directions
                                throw _CreateNoDirectionsError(routeId);
                            }

                            directions = routeDirs.Features
                                .Select(DirectionsHelper.ConvertToDirection)
                                .ToList();
                        }
                        else if (directionsFeatures != null)
                        {
                            // Use VRP service directions
                            var directionFeatures = directionsFeatures[routeId];

                            // WORKAROUND: pass first stop geometry as geometry whihc will be used
                            // in case if directions has no geometry.
                            _FixGeometries(directionFeatures, routeId, stops.First().Geometry as GPPoint);

                            directions = directionFeatures
                                .Select(DirectionsHelper.ConvertToDirection)
                                .ToList();
                        }

                        // We should have either Routing or VRP service directions here.
                        Debug.Assert(directions != null);
                        DirectionsHelper.SetDirections(stops, directions);
                    }

                    // set order sequence values
                    _SetOrderSequence(stops);

                    // add route result
                    results.Add(_CreateRouteResult(feature, route, stops));
                }
            }

            return results;
        }