/// <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>
        /// Parses indexes.
        /// </summary>
        /// <param name="nodeIndexes">Indexes node.</param>
        /// <returns>Readed table indexes.</returns>
        private List<TableIndex> _ParseIndexes(XmlNode nodeIndexes)
        {
            var indexes = new List<TableIndex>();
            foreach (XmlNode node in nodeIndexes.ChildNodes)
            {
                if (node.NodeType != XmlNodeType.Element)
                    continue; // skip comments and other non element nodes

                if (node.Name.Equals(NODE_NAME_INDEX, StringComparison.OrdinalIgnoreCase))
                {
                    TableIndex index = new TableIndex();
                    index.Type =
                        (TableIndexType)Enum.Parse(typeof(TableIndexType),
                                                   node.Attributes[ATTRIBUTE_NAME_TYPE].Value);
                    index.FieldNames = _ParseIndexFields(node.ChildNodes);
                    Debug.Assert(_IsValidIndexValue(index.Type, index.FieldNames));
                    indexes.Add(index);
                }
            }

            return indexes;
        }