///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="serviceUrl">Service url.</param>
        /// <param name="layerName">Layer name.</param>
        /// <param name="server">Server.</param>
        internal NetworkDescription(string serviceUrl, string layerName,
                                    AgsServer server)
        {
            Debug.Assert(serviceUrl != null);

            // Create connection.
            var             connection = server.OpenConnection();
            NAServiceClient client     = new NAServiceClient(serviceUrl, connection);

            try
            {
                NAServerNetworkDescription desc = client.GetNetworkDescription(layerName);

                NAServerSolverParams solverParams = client.GetSolverParameters(layerName);

                var parameterValues = solverParams.AttributeParameterValues.ToLookup(
                    value => value.AttributeName, StringComparer.OrdinalIgnoreCase);

                // Create attributes.
                foreach (NAServerNetworkAttribute attr in desc.NetworkAttributes)
                {
                    var routingAttributeName = attr.Name;
                    var attributeParameter   = parameterValues[attr.Name].FirstOrDefault();
                    if (attributeParameter != null)
                    {
                        routingAttributeName = attributeParameter.AttributeName;
                    }

                    var usageType = _ConvertUsageType(attr.UsageType);

                    var usageParameter =
                        _GetRestrictionUsageParameter(attr.RestrictionUsageParameterName,
                                                      parameterValues[attr.Name], usageType);

                    var attribute = new NetworkAttribute(attr.Name, routingAttributeName,
                                                         _ConvertUnits(attr.Units), usageType,
                                                         _GetAttrParams(attr, parameterValues[attr.Name]), usageParameter);

                    _attributes.Add(attribute);
                }

                // Enabled restriction names.
                _enabledRestrictionNames = solverParams.RestrictionAttributeNames;
                if (_enabledRestrictionNames == null)
                {
                    _enabledRestrictionNames = new string[0];
                }

                // Get impedance attribute name.
                _impedanceAttrName = solverParams.ImpedanceAttributeName;
            }
            finally
            {
                client.Close();
            }
        }
        /// <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>
        /// Constructor.
        /// </summary>
        /// <param name="serviceUrl">Service url.</param>
        /// <param name="layerName">Layer name.</param>
        /// <param name="server">Server.</param>
        internal NetworkDescription(string serviceUrl, string layerName,
            AgsServer server)
        {
            Debug.Assert(serviceUrl != null);

            // Create connection.
            var connection = server.OpenConnection();
            NAServiceClient client = new NAServiceClient(serviceUrl, connection);

            try
            {
                NAServerNetworkDescription desc = client.GetNetworkDescription(layerName);

                NAServerSolverParams solverParams = client.GetSolverParameters(layerName);

                var parameterValues = solverParams.AttributeParameterValues.ToLookup(
                    value => value.AttributeName, StringComparer.OrdinalIgnoreCase);

                // Create attributes.
                foreach (NAServerNetworkAttribute attr in desc.NetworkAttributes)
                {
                    var routingAttributeName = attr.Name;
                    var attributeParameter = parameterValues[attr.Name].FirstOrDefault();
                    if (attributeParameter != null)
                    {
                        routingAttributeName = attributeParameter.AttributeName;
                    }

                    var usageType = _ConvertUsageType(attr.UsageType);

                    var usageParameter =
                        _GetRestrictionUsageParameter(attr.RestrictionUsageParameterName,
                        parameterValues[attr.Name], usageType);

                    var attribute = new NetworkAttribute(attr.Name, routingAttributeName,
                        _ConvertUnits(attr.Units), usageType,
                        _GetAttrParams(attr, parameterValues[attr.Name]), usageParameter);

                    _attributes.Add(attribute);
                }

                // Enabled restriction names.
                _enabledRestrictionNames = solverParams.RestrictionAttributeNames;
                if (_enabledRestrictionNames == null)
                    _enabledRestrictionNames = new string[0];

                // Get impedance attribute name.
                _impedanceAttrName = solverParams.ImpedanceAttributeName;
            }
            finally
            {
                client.Close();
            }
        }