/// <summary>
        /// Fill depot-specific properties.
        /// </summary>
        /// <param name="depot">Depot.</param>
        /// <param name="settings">Current solver settings.</param>
        /// <param name="result">Stop information to fill in.</param>
        private static void _FillDepotProperties(Location depot,
                                                 SolverSettings settings, StopInfo result)
        {
            Debug.Assert(depot != null);
            Debug.Assert(result != null);

            // Fill curb approach policies.
            if (settings != null)
            {
                result.CurbApproach = settings.GetDepotCurbApproach();
            }
        }
        /// <summary>
        /// Fill order-specific properties.
        /// </summary>
        /// <param name="order">Order.</param>
        /// <param name="settings">Current solver settings.</param>
        /// <param name="result">Stop information to fill in.</param>
        private static void _FillOrderProperties(Order order,
                                                 SolverSettings settings, StopInfo result)
        {
            Debug.Assert(order != null);
            Debug.Assert(result != null);

            result.OrderType        = order.Type;
            result.Priority         = order.Priority;
            result.MaxViolationTime = (int)order.MaxViolationTime;

            // Fill curb approach policies.
            if (settings != null)
            {
                result.CurbApproach = settings.GetOrderCurbApproach();
            }
        }
        /// <summary>
        /// Exports the specified stop into a serializable stop info object.
        /// </summary>
        /// <param name="stop">The reference to the stop object to be exported.</param>
        /// <param name="sortedRouteStops">A collection of route stops sorted by their sequence
        /// numbers.</param>
        /// <param name="exportOrderProperties">The reference to the collection
        /// of custom order properties to be exported.</param>
        /// <param name="addressProperties">The reference to the collection
        /// of order address properties to be exported.</param>
        /// <param name="capacityProperties">The reference to the collection
        /// of order capacity properties to be exported.</param>
        /// <param name="customProperties">The reference to the collection
        /// of custom order properties to be exported.</param>
        /// <param name="settings">Current solver settings to be used for retrieving stop
        /// properties.</param>
        /// <returns>A stop info object corresponding to the specified stop.</returns>
        private static StopInfo _ExportStop(
            Stop stop,
            IList <Stop> sortedRouteStops,
            IEnumerable <OrderPropertyInfo> exportOrderProperties,
            IEnumerable <OrderPropertyInfo> addressProperties,
            IEnumerable <OrderPropertyInfo> capacityProperties,
            IEnumerable <OrderPropertyInfo> customProperties,
            SolverSettings settings)
        {
            Debug.Assert(stop != null);
            Debug.Assert(sortedRouteStops != null);
            Debug.Assert(sortedRouteStops.All(s => s != null));
            Debug.Assert(sortedRouteStops.All(s => stop.Route == s.Route));

            var commentsProperties = _GetOrderProperties(stop, exportOrderProperties);

            var result = new StopInfo
            {
                Name                  = _GetStopName(stop, sortedRouteStops),
                Location              = _GetStopLocation(stop, sortedRouteStops),
                Address               = _GetOrderProperties(stop, addressProperties),
                Capacities            = _GetOrderProperties(stop, capacityProperties),
                CustomOrderProperties = _GetOrderProperties(stop, customProperties),
                OrderComments         = _GetOrderComments(commentsProperties),
                ArriveTime            = stop.ArriveTime,
            };

            // Fill optional order-specific or depot-specific properties.
            var order = stop.AssociatedObject as Order;
            var depot = stop.AssociatedObject as Location;

            if (order != null)
            {
                _FillOrderProperties(order, settings, result);
            }
            else if (depot != null)
            {
                _FillDepotProperties(depot, settings, result);
            }

            return(result);
        }
        /// <summary>
        /// Fill order-specific properties.
        /// </summary>
        /// <param name="order">Order.</param>
        /// <param name="settings">Current solver settings.</param>
        /// <param name="result">Stop information to fill in.</param>
        private static void _FillOrderProperties(Order order,
            SolverSettings settings, StopInfo result)
        {
            Debug.Assert(order != null);
            Debug.Assert(result != null);

            result.OrderType = order.Type;
            result.Priority = order.Priority;
            result.MaxViolationTime = (int)order.MaxViolationTime;

            // Fill curb approach policies.
            if (settings != null)
            {
                result.CurbApproach = settings.GetOrderCurbApproach();
            }
        }
        /// <summary>
        /// Fill depot-specific properties.
        /// </summary>
        /// <param name="depot">Depot.</param>
        /// <param name="settings">Current solver settings.</param>
        /// <param name="result">Stop information to fill in.</param>
        private static void _FillDepotProperties(Location depot,
            SolverSettings settings, StopInfo result)
        {
            Debug.Assert(depot != null);
            Debug.Assert(result != null);

            // Fill curb approach policies.
            if (settings != null)
            {
                result.CurbApproach = settings.GetDepotCurbApproach();
            }
        }
        /// <summary>
        /// Exports the specified stop into a serializable stop info object.
        /// </summary>
        /// <param name="stop">The reference to the stop object to be exported.</param>
        /// <param name="sortedRouteStops">A collection of route stops sorted by their sequence
        /// numbers.</param>
        /// <param name="exportOrderProperties">The reference to the collection
        /// of custom order properties to be exported.</param>
        /// <param name="addressProperties">The reference to the collection
        /// of order address properties to be exported.</param>
        /// <param name="capacityProperties">The reference to the collection
        /// of order capacity properties to be exported.</param>
        /// <param name="customProperties">The reference to the collection
        /// of custom order properties to be exported.</param>
        /// <param name="settings">Current solver settings to be used for retrieving stop
        /// properties.</param>
        /// <returns>A stop info object corresponding to the specified stop.</returns>
        private static StopInfo _ExportStop(
            Stop stop,
            IList<Stop> sortedRouteStops,
            IEnumerable<OrderPropertyInfo> exportOrderProperties,
            IEnumerable<OrderPropertyInfo> addressProperties,
            IEnumerable<OrderPropertyInfo> capacityProperties,
            IEnumerable<OrderPropertyInfo> customProperties,
            SolverSettings settings)
        {
            Debug.Assert(stop != null);
            Debug.Assert(sortedRouteStops != null);
            Debug.Assert(sortedRouteStops.All(s => s != null));
            Debug.Assert(sortedRouteStops.All(s => stop.Route == s.Route));

            var commentsProperties = _GetOrderProperties(stop, exportOrderProperties);

            var result = new StopInfo
            {
                Name = _GetStopName(stop, sortedRouteStops),
                Location = _GetStopLocation(stop, sortedRouteStops),
                Address = _GetOrderProperties(stop, addressProperties),
                Capacities = _GetOrderProperties(stop, capacityProperties),
                CustomOrderProperties = _GetOrderProperties(stop, customProperties),
                OrderComments = _GetOrderComments(commentsProperties),
                ArriveTime = stop.ArriveTime,
            };

            // Fill optional order-specific or depot-specific properties.
            var order = stop.AssociatedObject as Order;
            var depot = stop.AssociatedObject as Location;

            if (order != null)
            {
                _FillOrderProperties(order, settings, result);
            }
            else if (depot != null)
            {
                _FillDepotProperties(depot, settings, result);
            }

            return result;
        }
 ///////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="project">project.</param>
 /// <param name="schedule">schedule.</param>
 /// <param name="settings">settings.</param>
 public VrpResultConverter(Project project, Schedule schedule,
     SolverSettings settings)
 {
     _project = project;
     _schedule = schedule;
     _settings = settings;
 }
        /// <summary>
        /// Get value for parameter.
        /// </summary>
        /// <param name="attributeName">Attribute name.</param>
        /// <param name="parameterName">Parameter name.</param>
        /// <param name="solverSettings">Solver settings from which 
        /// parameter value will be taken.</param>
        /// <returns>Parameter value or empty string if no such parameter.</returns>
        private string _GetParameterValue(string attributeName, string parameterName, 
            SolverSettings solverSettings)
        {
            object valueObj = null;
            if (!solverSettings.GetNetworkAttributeParameterValue(attributeName,
                parameterName, out valueObj))
                valueObj = null;

            return _ConvertValue2String(valueObj);
        }
        /// <summary>
        /// Updates value.
        /// </summary>
        /// <param name="wrapper">Restriction data wrapper.</param>
        /// <param name="solverSettings">Solver settings.</param>
        /// <param name="attribute">Network attribute.</param>
        private void _UpdateValue(RestrictionDataWrapper wrapper, SolverSettings solverSettings, 
            NetworkAttribute attribute)
        {
            Debug.Assert(null != wrapper);
            Debug.Assert(null != attribute);
            Debug.Assert(null != solverSettings);

            // Update restriction usage parameter if it exist.
            if (wrapper.RestrictionUsageParameter != null &&
                wrapper.RestrictionUsageParameter.Name != null)
            {
                _UpdateParameterIfNeeded(solverSettings, attribute,
                    wrapper.RestrictionUsageParameter.Name, wrapper.RestrictionUsageParameter.Value);
            }

            // Update all other parameters.
            foreach (Parameter parameter in wrapper.Parameters)
            {
                if(!string.IsNullOrEmpty(parameter.Name))
                    _UpdateParameterIfNeeded(solverSettings, attribute, parameter.Name, parameter.Value);
            }
        }
        /// <summary>
        /// Update parameter if it has been changed.
        /// </summary>
        /// <param name="solverSettings">Solver settings in which 
        /// parameter value will be updated.</param>
        /// <param name="attribute">Network attribute, which parameter must be updated.</param>
        /// <param name="parameterName">Name of the parameter which must be updated.</param>
        /// <param name="parameterValue">Value, which must be set in parameter.</param>
        /// <exception cref="System.ArgumentException">Is thrown when there is no 
        /// attribute with such parameter name in solver settings.</exception>
        private void _UpdateParameterIfNeeded(SolverSettings solverSettings,
            NetworkAttribute attribute, string parameterName, string parameterValue)
        {
            Debug.Assert(solverSettings != null);
            Debug.Assert(attribute != null);
            Debug.Assert(parameterName != null);

            // Get parameter.
            var parameter = attribute.Parameters.First(par => par.Name == parameterName);

            // Get current parameter value.
            object valueObj = null;
            if (!solverSettings.GetNetworkAttributeParameterValue(attribute.Name, parameterName, out valueObj))
                throw new ArgumentException("parameterName");
            string value = _ConvertValue2String(valueObj);

            // If value has changed - set new value.
            if (!value.Equals(parameterValue, StringComparison.OrdinalIgnoreCase))
            {
                if (parameterValue != null)
                {
                    try
                    {
                        solverSettings.SetNetworkAttributeParameterValue(attribute.Name,
                            parameter.Name, parameterValue);
                    }
                    // Inputed value is in wrong format - do not change solver settings.
                    catch
                    {
                    }
                }
            }
        }
        /// <summary>
        /// Converts network attributes to route attribute parameters.
        /// </summary>
        /// <param name="attrs">Network attributes.</param>
        /// <param name="settings">Solver settings.</param>
        /// <returns>Route attribute parameters.</returns>
        private static RouteAttrParameters _ConvertAttrParameters(
            ICollection<NetworkAttribute> attrs,
            SolverSettings settings)
        {
            Debug.Assert(attrs != null);
            Debug.Assert(settings != null);

            var list = new List<RouteAttrParameter>();
            foreach (NetworkAttribute attr in attrs)
            {
                foreach (NetworkAttributeParameter param in attr.Parameters)
                {
                    object value = null;
                    if (settings.GetNetworkAttributeParameterValue(attr.Name, param.Name, out value))
                    {
                        // skip null value overrides, let the service to use defaults
                        if (value != null)
                        {
                            var p = new RouteAttrParameter();
                            p.AttrName = attr.Name;
                            p.ParamName = param.Name;
                            p.Value = value;
                            list.Add(p);
                        }
                    }
                }
            }

            var res = new RouteAttrParameters();
            res.Parameters = list.ToArray();

            return res;
        }