/// <summary>
        /// Retrieves all Foreign keys.
        /// </summary>
        /// <param name="catalogMetaData">The catalog meta data.</param>
        private void RetrieveForeignKeys(DBCatalog catalogMetaData)
        {
            #region Description of query used
            //select  fks.user_name AS FK_SCHEMA, fkt.table_name as FK_TABLE_NAME, fcol.column_name AS FK_COLUMN_NAME,
            //        pks.user_name AS PK_SCHEMA, pkt.table_name as PK_TABLE_NAME, pcol.column_name AS PK_COLUMN_NAME, sc.constraint_name as FK_NAME
            //from    sysfkey fk inner join systab fkt on fk.foreign_table_id = fkt.table_id
            //        inner join systab pkt on fk.primary_table_id = pkt.table_id
            //        inner join sysuser fks on fkt.creator = fks.user_id
            //        inner join sysuser pks on pkt.creator = pks.user_id
            //        inner join sysidxcol fic on fic.table_id = fk.foreign_table_id and fic.index_id = fk.foreign_index_id
            //        inner join sysidxcol pic on pic.table_id = fk.primary_table_id and pic.index_id = fk.primary_index_id
            //                and fic.primary_column_id = pic.column_id
            //        inner join syscolumn fcol on fic.table_id=fcol.table_id and fic.column_id = fcol.column_id
            //        inner join syscolumn pcol on pic.table_id=pcol.table_id and pic.column_id = pcol.column_id
            //		  inner join sysidx si on si.table_id = fk.foreign_table_id and si.index_id = fk.foreign_index_id and si.index_category=2
            //		  inner join sysconstraint sc on sc.ref_object_id=si.object_id
            //where fks.user_name in (<schema list>) and pks.user_name in (<schema list>)
            //order BY fks.user_name ASC, fkt.table_name ASC, fic.column_id ASC
            #endregion

            string        inClause    = String.Join(", ", catalogMetaData.Schemas.Select(s => string.Format("'{0}'", s.SchemaOwner)).ToArray());
            string        query       = string.Format("select  fks.user_name AS FK_SCHEMA, fkt.table_name as FK_TABLE_NAME, fcol.column_name AS FK_COLUMN_NAME, pks.user_name AS PK_SCHEMA, pkt.table_name as PK_TABLE_NAME, pcol.column_name AS PK_COLUMN_NAME, sc.constraint_name as FK_NAME from sysfkey fk inner join systab fkt on fk.foreign_table_id = fkt.table_id inner join systab pkt on fk.primary_table_id = pkt.table_id inner join sysuser fks on fkt.creator = fks.user_id inner join sysuser pks on pkt.creator = pks.user_id inner join sysidxcol fic on fic.table_id = fk.foreign_table_id and fic.index_id = fk.foreign_index_id inner join sysidxcol pic on pic.table_id = fk.primary_table_id and pic.index_id = fk.primary_index_id and fic.primary_column_id = pic.column_id inner join syscolumn fcol on fic.table_id=fcol.table_id and fic.column_id = fcol.column_id inner join syscolumn pcol on pic.table_id=pcol.table_id and pic.column_id = pcol.column_id inner join sysidx si on si.table_id = fk.foreign_table_id and si.index_id = fk.foreign_index_id and si.index_category=2 inner join sysconstraint sc on sc.ref_object_id=si.object_id where fks.user_name in ({0}) and pks.user_name in ({0}) order BY fks.user_name ASC, fkt.table_name ASC, fic.column_id ASC", inClause);
            DbDataAdapter adapter     = this.DriverToUse.CreateDataAdapter(query);
            DataTable     foreignKeys = new DataTable();
            adapter.Fill(foreignKeys);

            string currentPKTableName = string.Empty;
            string currentFKTableName = string.Empty;
            string currentFKName      = string.Empty;

            // traverse per FK table name the fields which are stored in an FK constraint per different PK table name.
            DBForeignKeyConstraint newForeignKeyConstraint = new DBForeignKeyConstraint();
            DBTable tableForeignKey = null;
            DBTable tablePrimaryKey = null;
            bool    fkValid         = false;
            foreach (DataRow row in foreignKeys.AsEnumerable())
            {
                string previousPKTableName = currentPKTableName;
                currentPKTableName = row.Value <string>("PK_SCHEMA") + row.Value <string>("PK_TABLE_NAME");
                string previousFKTableName = currentFKTableName;
                currentFKTableName = row.Value <string>("FK_SCHEMA") + row.Value <string>("FK_TABLE_NAME");
                string previousFKName = currentFKName;
                currentFKName = row.Value <string>("FK_NAME");

                // if this is a new FK table, we've to start from scratch with a new FK constraint. If this isn't a new FK table, we've to check if this is a new
                // PK table. if so, we've also to start from scratch with a new FK constraint. If this isn't a new PK table, we've to check whether the FK name
                // changed. If so, we're dealing with a new FK constraint. Otherwise it's the same FK.
                if ((previousFKTableName != currentFKTableName) || (previousPKTableName != currentPKTableName) || (previousFKName != currentFKName))
                {
                    // create a new FK
                    fkValid = true;
                    newForeignKeyConstraint = new DBForeignKeyConstraint();
                    newForeignKeyConstraint.ConstraintName = "FK_" + Guid.NewGuid().ToString("N");

                    DBSchema schemaForeignKey = catalogMetaData.FindSchemaByName(row.Value <string>("FK_SCHEMA"));
                    if (schemaForeignKey == null)
                    {
                        fkValid = false;
                        continue;
                    }
                    tableForeignKey = schemaForeignKey.FindTableByName(row.Value <string>("FK_TABLE_NAME"));

                    // Get Primary Key Table, first get the schema, has to be there
                    DBSchema schemaPrimaryKey = catalogMetaData.FindSchemaByName(row.Value <string>("PK_SCHEMA"));
                    if (schemaPrimaryKey == null)
                    {
                        fkValid = false;
                        continue;
                    }
                    tablePrimaryKey = schemaPrimaryKey.FindTableByName(row.Value <string>("PK_TABLE_NAME"));

                    if ((tableForeignKey == null) || (tablePrimaryKey == null))
                    {
                        // not found. next
                        fkValid = false;
                        continue;
                    }

                    // Add to Foreign Key table.
                    tableForeignKey.ForeignKeyConstraints.Add(newForeignKeyConstraint);
                }

                // test again, if the FK is based on 2 or more fields, this test is required.
                if (!fkValid)
                {
                    // not valid, skip
                    if (tableForeignKey != null)
                    {
                        tableForeignKey.ForeignKeyConstraints.Remove(newForeignKeyConstraint);
                    }
                    continue;
                }

                newForeignKeyConstraint.AppliesToTable = tableForeignKey;
                DBTableField foreignKeyField = tableForeignKey.FindFieldByName(row.Value <string>("FK_COLUMN_NAME"));
                DBTableField primaryKeyField = tablePrimaryKey.FindFieldByName(row.Value <string>("PK_COLUMN_NAME"));
                if ((foreignKeyField == null) || (primaryKeyField == null))
                {
                    tableForeignKey.ForeignKeyConstraints.Remove(newForeignKeyConstraint);
                    fkValid = false;
                    continue;
                }
                newForeignKeyConstraint.PrimaryKeyFields.Add(primaryKeyField);
                newForeignKeyConstraint.ForeignKeyFields.Add(foreignKeyField);
            }
        }