///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Clone procedure.
        /// </summary>
        /// <returns>Deep copy of object.</returns>
        public object Clone()
        {
            FieldInfo obj = new FieldInfo();
            obj.RelationType = this.RelationType;
            obj.NameFormat = this.NameFormat;
            obj.Type = this.Type;
            obj.Size = this.Size;
            obj.Precision = this.Precision;
            obj.Scale = this.Scale;
            obj.IsDefault = this.IsDefault;
            obj.IsHidden = this.IsHidden;
            obj.Name = this.Name;
            obj.LongName = this.LongName;
            obj.ShortName = this.ShortName;
            obj.Description = this.Description;
            obj.IsImage = this.IsImage;

            return obj;
        }
        /// <summary>
        /// Loads field information.
        /// </summary>
        /// <param name="nodeFields">Fields node.</param>
        /// <returns>Readed field information.</returns>
        private List<FieldInfo> _LoadFields(XmlNode nodeFields)
        {
            var fields = new List<FieldInfo>();
            foreach (XmlNode node in nodeFields.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                    continue; // skip comments and other non element nodes

                if (node.Name.Equals(NODE_NAME_FIELD, StringComparison.OrdinalIgnoreCase))
                {
                    FieldInfo field = new FieldInfo();
                    field.Name = node.Attributes[ATTRIBUTE_NAME_NAME].Value;
                    string longName = node.Attributes[ATTRIBUTE_NAME_LONGNAME].Value;
                    field.LongName = Properties.Resources.ResourceManager.GetString(longName);
                    string shortName = node.Attributes[ATTRIBUTE_NAME_SHORTNAME].Value;
                    field.ShortName = Properties.Resources.ResourceManager.GetString(shortName);

                    field.RelationType = null;
                    if (null != node.Attributes[ATTRIBUTE_NAME_RELATIONTYPE])
                        field.RelationType = node.Attributes[ATTRIBUTE_NAME_RELATIONTYPE].Value;
                    field.NameFormat =
                        (string.IsNullOrEmpty(field.RelationType)) ? null : field.Name;

                    field.Type =
                        (OleDbType)Enum.Parse(typeof(OleDbType),
                                              node.Attributes[ATTRIBUTE_NAME_ADOTYPE].Value);

                    field.Size = 0;
                    if (null != node.Attributes[ATTRIBUTE_NAME_SIZE])
                        field.Size = int.Parse(node.Attributes[ATTRIBUTE_NAME_SIZE].Value);
                    field.Precision = 0;
                    if (null != node.Attributes[ATTRIBUTE_NAME_PRECISION])
                        field.Precision = int.Parse(node.Attributes[ATTRIBUTE_NAME_PRECISION].Value);
                    field.Scale = 0;
                    if (null != node.Attributes[ATTRIBUTE_NAME_SCALE])
                        field.Scale = int.Parse(node.Attributes[ATTRIBUTE_NAME_SCALE].Value);

                    field.IsDefault = true;
                    if (null != node.Attributes[ATTRIBUTE_NAME_DEFAULT])
                        field.IsDefault = bool.Parse(node.Attributes[ATTRIBUTE_NAME_DEFAULT].Value);

                    field.IsHidden = false;
                    if (null != node.Attributes[ATTRIBUTE_NAME_HIDDEN])
                        field.IsHidden = bool.Parse(node.Attributes[ATTRIBUTE_NAME_HIDDEN].Value);

                    field.IsImage = false;
                    if (null != node.Attributes[ATTRIBUTE_NAME_IMAGE])
                        field.IsImage = bool.Parse(node.Attributes[ATTRIBUTE_NAME_IMAGE].Value);

                    field.Description = null;
                    if (null != node.Attributes[ATTRIBUTE_NAME_DESCRIPTION])
                    {
                        string description = node.Attributes[ATTRIBUTE_NAME_DESCRIPTION].Value;
                        field.Description =
                            Properties.Resources.ResourceManager.GetString(description);
                    }

                    fields.Add(field);
                }
            }
            return fields;
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Updates info with info name.
        /// </summary>
        /// <param name="infoName">Property name.</param>
        /// <param name="infoRead">Readed info.</param>
        /// <param name="info">Validated info.</param>
        private void _UpdateInfoWithInfoName(string infoName,
                                             FieldInfo infoRead,
                                             ref FieldInfo info)
        {
            Debug.Assert(!string.IsNullOrEmpty(infoRead.Name));
            Debug.Assert(!string.IsNullOrEmpty(infoRead.LongName));
            Debug.Assert(!string.IsNullOrEmpty(infoRead.ShortName));

            string name = ValidateRelativeName(infoName);

            info.Name = string.Format(infoRead.Name, name);
            info.LongName = string.Format(infoRead.LongName, name);

            string shortName = string.Format(infoRead.ShortName, name);
            info.ShortName = (SHORT_NAME_LENGTH < shortName.Length)?
                                        shortName.Substring(0, SHORT_NAME_LENGTH) : shortName;
        }
        /// <summary>
        /// Adds custom order property relative fields.
        /// </summary>
        /// <param name="orderCustomPropertyInfos">Order custom order properties info information.</param>
        /// <param name="info">Field information with data settings.</param>
        private void _AddCustomOrderPropertyRelativeFields(
            OrderCustomPropertiesInfo orderCustomPropertyInfos,
            FieldInfo info)
        {
            for (int index = 0; index < orderCustomPropertyInfos.Count; ++index)
            {
                FieldInfo infoRealtion = (FieldInfo)info.Clone();

                OrderCustomProperty prorety = orderCustomPropertyInfos[index];
                _UpdateInfoWithInfoName(prorety.Name, info, ref infoRealtion);
                infoRealtion.Description = prorety.Description;

                Debug.Assert(!string.IsNullOrEmpty(infoRealtion.Name));

                // NOTE: special issue
                //  support numeric custom order propertiy - need change type description
                if (orderCustomPropertyInfos[index].Type == OrderCustomPropertyType.Numeric)
                {
                    infoRealtion.Type = OleDbType.Double;
                    infoRealtion.Size = 0;
                    infoRealtion.Scale = 2;
                    infoRealtion.Precision = 14;
                }

                _fieldsMap.Add(infoRealtion.Name, infoRealtion);
            }
        }
        /// <summary>
        /// Adds capacity relative fields.
        /// </summary>
        /// <param name="capacityInfos">Capacities informations.</param>
        /// <param name="info">Field information with data settings.</param>
        private void _AddCapacityRelativeFields(CapacitiesInfo capacityInfos, FieldInfo info)
        {
            for (int index = 0; index < capacityInfos.Count; ++index)
            {
                FieldInfo infoRealtion = (FieldInfo)info.Clone();

                CapacityInfo capacityInfo = capacityInfos[index];
                _UpdateInfoWithInfoName(capacityInfo.Name, info, ref infoRealtion);

                // format description
                if (!string.IsNullOrEmpty(infoRealtion.Description))
                {
                    if ((infoRealtion.Description == Properties.Resources.ExportFieldDescriptionCapacity) ||
                        (infoRealtion.Description == Properties.Resources.ExportFieldDescriptionRelativeCapacity))
                    {
                        infoRealtion.Description =
                            _FormatCapacityDescription(capacityInfo, infoRealtion.Description);
                    }

                    else if (infoRealtion.Description == Properties.Resources.ExportFieldDescriptionTotal)
                    {
                        infoRealtion.Description =
                            _FormatCapacityDescriptionTotal(capacityInfo, infoRealtion.Description);
                    }

                    else if (infoRealtion.Description == Properties.Resources.ExportFieldDescriptionUtilization)
                    {
                        infoRealtion.Description =
                            _FormatCapacityDescriptionUtilization(capacityInfo, infoRealtion.Description);
                    }

                    // else Do nothing - use without modification
                }

                Debug.Assert(!string.IsNullOrEmpty(infoRealtion.Name));
                _fieldsMap.Add(infoRealtion.Name, infoRealtion);
            }
        }
        /// <summary>
        /// Add address relative fields.
        /// </summary>
        /// <param name="addressFields">Address fields.</param>
        /// <param name="info">Field information with data settings.</param>
        private void _AddAddressRelativeFields(AddressField[] addressFields, FieldInfo info)
        {
            for (int index = 0; index < addressFields.Length; ++index)
            {
                AddressField adress = addressFields[index];

                FieldInfo infoRealtion = (FieldInfo)info.Clone();
                infoRealtion.Name = infoRealtion.LongName = adress.Title;
                infoRealtion.ShortName = (SHORT_NAME_LENGTH < infoRealtion.LongName.Length) ?
                        infoRealtion.LongName.Substring(0, SHORT_NAME_LENGTH) :
                        infoRealtion.LongName;
                infoRealtion.NameFormat = adress.Type.ToString();
                Debug.Assert(string.IsNullOrEmpty(infoRealtion.Description));
                if (string.IsNullOrEmpty(infoRealtion.Description))
                    infoRealtion.Description = adress.Description;

                Debug.Assert(!string.IsNullOrEmpty(infoRealtion.Name));
                _fieldsMap.Add(infoRealtion.Name, infoRealtion);
            }
        }