///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Initializes a new instance of ExportValidator.
        /// </summary>
        /// <param name="capacitiesInfo">Current capacities info.</param>
        /// <param name="addressFields">Current address fields.</param>
        public ExportValidator(CapacitiesInfo capacitiesInfo,
                               AddressField[] addressFields)
        {
            if (null == capacitiesInfo)
                throw new ArgumentNullException("capacitiesInfo"); // exception

            if (null == addressFields)
                throw new ArgumentNullException("addressFields"); // exception

            // load export structure
            ExportStructureReader reader = Exporter.GetReader(capacitiesInfo,
                                                              new OrderCustomPropertiesInfo(),
                                                              addressFields);

            _readedNames = new List<string>();
            _GetFieldNames(reader, ExportType.Access, _readedNames);
            _GetFieldNames(reader, ExportType.TextOrders, _readedNames);
            _GetFieldNames(reader, ExportType.TextStops, _readedNames);

            _description = reader.GetTableDescription(TableType.Stops);
        }
        /// <summary>
        /// Creates insert command.
        /// </summary>
        /// <param name="tableName">Table name.</param>
        /// <param name="tableDescription">Table Description.</param>
        /// <param name="fields">Fields to export.</param>
        /// <returns>Insert command.</returns>
        private OleDbCommand _CreateInsertCommand(string tableName,
                                                  TableDescription tableDescription,
                                                  ICollection<string> fields)
        {
            var command = new OleDbCommand();

            var valueNames = new StringBuilder();
            var values = new StringBuilder();
            OleDbParameterCollection parameters = command.Parameters;
            foreach (string field in fields)
            {
                if (!string.IsNullOrEmpty(valueNames.ToString()))
                {
                    valueNames.Append(SQL_PARAM_SEPARATOR);
                    values.Append(SQL_PARAM_SEPARATOR);
                }

                FieldInfo info = tableDescription.GetFieldInfo(field);
                Debug.Assert(null != info);

                string realName = _FormatFieldName(field);
                valueNames.Append(realName);
                values.Append(SQL_VALUE_SYMBOL);

                parameters.Add(field, info.Type, info.Size, field);
            }

            command.CommandText = string.Format(SQL_INSERT_COMMAND_FORMAT, tableName,
                                                valueNames.ToString(), values.ToString());
            return command;
        }
        /// <summary>
        /// Adds key to index of table.
        /// </summary>
        /// <param name="tableDescription">Table description.</param>
        /// <param name="indexDefinition">Index definition.</param>
        /// <param name="indexes">Database indexes.</param>
        private void _AddKeyToTableIndex(TableDescription tableDescription,
                                         TableIndex indexDefinition,
                                         ADOX.Indexes indexes)
        {
            Debug.Assert(null != tableDescription);
            Debug.Assert(null != indexDefinition);
            Debug.Assert(null != indexes);

            var index = new ADOX.Index();
            ADOX.Columns columns = index.Columns;
            switch (indexDefinition.Type)
            {
                case TableIndexType.Primary:
                case TableIndexType.Simple:
                {
                    string field = indexDefinition.FieldNames[0];
                    if (TableIndexType.Primary == indexDefinition.Type)
                    {
                        index.Name = INDEX_PRIMARY_KEY;
                        index.PrimaryKey = true;
                        index.Unique = true;
                    }
                    else // simple
                        index.Name = field;

                    FieldInfo info = tableDescription.GetFieldInfo(field);
                    Debug.Assert(null != info);
                    columns.Append(info.Name, _ConvertType(info.Type), info.Size);
                    break;
                }

                case TableIndexType.Multiple:
                {
                    var sbKeyName = new StringBuilder();
                    foreach (string field in indexDefinition.FieldNames)
                    {
                        FieldInfo info = tableDescription.GetFieldInfo(field);
                        Debug.Assert(null != info);
                        columns.Append(info.Name, _ConvertType(info.Type), info.Size);

                        if (!string.IsNullOrEmpty(sbKeyName.ToString()))
                            sbKeyName.Append(SQL_KEY_SYMBOL);
                        sbKeyName.Append(field);
                    }

                    index.Name = sbKeyName.ToString();
                    break;
                }

                default:
                {
                    Debug.Assert(false); // NOTE: not supported
                    break;
                }
            }

            index.IndexNulls = ADOX.AllowNullsEnum.adIndexNullsAllow;
            indexes.Append(index, null);
        }
        /// <summary>
        /// Adds keys to index of table.
        /// </summary>
        /// <param name="tableDescription">Table description.</param>
        /// <param name="tableDefinition">Table definition.</param>
        /// <param name="indexes">Database indexes.</param>
        private void _AddKeysToTableIndex(TableDescription tableDescription,
                                          ITableDefinition tableDefinition,
                                          ADOX.Indexes indexes)
        {
            ICollection<TableInfo> patternTables = _structureKeeper.GetPattern(ExportType.Access);
            foreach (TableInfo tableInfo in patternTables)
            {
                if (tableInfo.Type != tableDefinition.Type)
                    continue; // skip

                foreach(TableIndex indexDefinition in tableInfo.Indexes)
                {
                    if (_IsIndexFieldSelected(indexDefinition.FieldNames, tableDefinition.Fields))
                        _AddKeyToTableIndex(tableDescription, indexDefinition, indexes);
                }

                break; // process done
            }
        }
        /// <summary>
        /// Adds fields to table.
        /// </summary>
        /// <param name="tableDefinition">Table definition.</param>
        /// <param name="tableDescription">Table Description.</param>
        /// <param name="columns">Database columns.</param>
        private void _AddFieldsToTable(ITableDefinition tableDefinition,
                                       TableDescription tableDescription,
                                       ADOX.Columns columns)
        {
            Debug.Assert(null != tableDefinition);
            Debug.Assert(null != tableDescription);
            Debug.Assert(null != columns);

            ICollection<string> fields = tableDefinition.Fields;
            foreach (string field in fields)
            {
                FieldInfo info = tableDescription.GetFieldInfo(field);
                Debug.Assert(null != info);
                columns.Append(info.Name, _ConvertType(info.Type), info.Size);

                // make field not required
                ADOX.Column column = columns[info.Name];
                column.Attributes = ADOX.ColumnAttributesEnum.adColNullable;
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Creates a new instance of the <c>TableDefinition</c> class.
        /// </summary>
        /// <param name="description">Description of table.</param>
        /// <param name="ignorableFields">Ignorable fields.</param>
        /// <param name="isShortNamesMode">Is short names mode indicator.</param>
        public TableDefinition(TableDescription description,
                               StringCollection ignorableFields,
                               bool isShortNamesMode)
        {
            Debug.Assert(null != description);
            Debug.Assert(null != ignorableFields);

            _type = description.Type;
            _name = description.Name;

            foreach (string fieldName in description.GetFieldNames())
            {
                if (ignorableFields.Contains(fieldName))
                    continue; // skip ignorable fields

                // set default selected
                Debug.Assert(null != description.GetFieldInfo(fieldName));
                FieldInfo fieldInfo = description.GetFieldInfo(fieldName);
                if (fieldInfo.IsDefault)
                    _fields.Add(fieldName);

                if (fieldInfo.IsHidden)
                    _hiddenFields.Add(fieldName);
                else
                    _supportedFields.Add(fieldName);

                string name = (isShortNamesMode) ? fieldInfo.ShortName : fieldInfo.LongName;
                _mapFaceNameByName.Add(fieldName, name);
                _mapDescriptionByName.Add(fieldName, fieldInfo.Description);
            }
        }