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

        /// <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>
		/// Get ServerSolverParams controls (ReturnMap, SnapTolerance, etc.)
		/// </summary>
		private void GetServerSolverParams(NAServerNetworkDescription networkDescription, NAServerSolverParams solverParams)
		{
			chkReturnMap.Checked = true;
			txtSnapTolerance.Text = solverParams.SnapTolerance.ToString();
			txtMaxSnapTolerance.Text = solverParams.MaxSnapTolerance.ToString();
			cboSnapToleranceUnits.SelectedIndex = Convert.ToInt32(solverParams.SnapToleranceUnits);

			//Set Route Defaults
			chkReturnRouteGeometries.Checked = false;
			chkReturnRoutes.Checked = true;
			chkReturnStops.Checked = true;
			chkReturnDirections.Checked = true;
			checkReturnBarriers.Checked = true;

			//Set Directions Defaults
			cboRouteDirectionsTimeAttribute.Items.Clear();
			NAServerNetworkAttribute[] attributes = networkDescription.NetworkAttributes;
			for (int i = 0; i < attributes.Length; i++)
			{
				NAServerNetworkAttribute networkAttribute = attributes[i];
				if (networkAttribute.UsageType == esriNetworkAttributeUsageType.esriNAUTCost)
				{
					if (String.Compare(networkAttribute.Units.ToString(), "esriNAUMinutes") == 0)
					{
						cboRouteDirectionsTimeAttribute.Items.Add(networkAttribute.Name);
					}
				}
			}

			// Set the default direction settings
			NAServerRouteParams routeParams = solverParams as NAServerRouteParams;
			if (routeParams != null)
			{
				cboRouteDirectionsLengthUnits.Text = routeParams.DirectionsLengthUnits.ToString().Substring(7);
				//Select the first time attribute
				if (cboRouteDirectionsTimeAttribute.Items.Count > 0)
					cboRouteDirectionsTimeAttribute.Text = routeParams.DirectionsTimeAttributeName;
			}
		}
		/// <summary>
		/// Get Default NASolverSettings controls (Cost Attributes, Restrictions Attributes. etc.)
		/// </summary>
		private void GetNASolverSettings(NAServerNetworkDescription networkDescription, NAServerSolverParams solverSettings)
		{
			int ImpedanceIndex = 0;

			//Get Attributes
			cboImpedance.Items.Clear();
			chklstAccumulateAttributes.Items.Clear();
			chklstRestrictions.Items.Clear();
			cboUturnPolicy.SelectedIndex = -1;

			NAServerNetworkAttribute[] attributes = networkDescription.NetworkAttributes;
			string[] accumulateAttributeNames = solverSettings.AccumulateAttributeNames;
			string[] restrictionAttributeNames = solverSettings.RestrictionAttributeNames;

			for (int i = 0; i < attributes.Length; i++)
			{
				NAServerNetworkAttribute networkAttribute = attributes[i];
				string networkAttributeName = networkAttribute.Name;
				if (networkAttribute.UsageType == esriNetworkAttributeUsageType.esriNAUTCost)
				{
					chklstAccumulateAttributes.Items.Add(networkAttributeName, IsStringInStringArray(networkAttributeName, accumulateAttributeNames));

					int index = cboImpedance.Items.Add(networkAttributeName + " (" + networkAttribute.Units.ToString().Substring(7) + ")");
					if (networkAttributeName == solverSettings.ImpedanceAttributeName)
						ImpedanceIndex = index;
				}

				if (networkAttribute.UsageType == esriNetworkAttributeUsageType.esriNAUTRestriction)
				{
					chklstRestrictions.Items.Add(networkAttributeName, IsStringInStringArray(networkAttributeName, restrictionAttributeNames));
				}
			}

			if (cboImpedance.Items.Count > 0)
				cboImpedance.SelectedIndex = ImpedanceIndex;

			chkUseHierarchy.Checked = solverSettings.UseHierarchy;
			chkUseHierarchy.Enabled = solverSettings.HierarchyAttributeName.Length > 0;
			chkIgnoreInvalidLocations.Checked = solverSettings.IgnoreInvalidLocations;
			cboUturnPolicy.SelectedIndex = System.Convert.ToInt32(solverSettings.RestrictUTurns);
		}