/// <summary>
        /// Creates a collection of tables found in the schema.
        /// </summary>
        /// <param name="xmlSchema">The schema that describes the data model.</param>
        /// <returns>A list of TableSchema objects that describe the tables found in the data model schema.</returns>
        private void FirstPass(XmlSchemaSet xmlSchemaSet)
        {
            // Scan through the schema set looking for table elements.  These can either be defined at the root element for a standard
            // schema or they can be found as choices of a special element describing a 'DataSet' for the Microsoft version of a
            // schema.
            foreach (XmlSchemaElement xmlSchemaElement in xmlSchemaSet.GlobalElements.Values)
            {
                // If the element read from the schema is the Microsoft DataSet element, then the tables are described as choices
                // associated with an implicit complex type on that element.
                if (ObjectSchema.IsDataSetElement(xmlSchemaElement))
                {
                    // The tables are described as an choices of an implicit (nested) complex type.
                    if (xmlSchemaElement.SchemaType is XmlSchemaComplexType)
                    {
                        // The complex type describes the table.
                        XmlSchemaComplexType xmlSchemaComplexType = xmlSchemaElement.SchemaType as XmlSchemaComplexType;

                        // The data model is described as a set of one or more choices of tables.
                        if (xmlSchemaComplexType.Particle is XmlSchemaChoice)
                        {
                            // The data model is described as a set of choices.  Each choice represents a table.
                            XmlSchemaChoice xmlSchemaChoice = xmlSchemaComplexType.Particle as XmlSchemaChoice;

                            // Create a table for each of the choices described in the complex type.
                            foreach (XmlSchemaObject choiceObject in xmlSchemaChoice.Items)
                            {
                                if (choiceObject is XmlSchemaElement)
                                {
                                    XmlSchemaElement tableElement = choiceObject as XmlSchemaElement;
                                    this.tableList.Add(tableElement.Name, new TableSchema(this, tableElement));
                                }
                            }
                        }
                    }

                    // The constraints describe the columns that are unique for a table.
                    foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints)
                    {
                        // This describes the columns that must be unique within a table.
                        if (xmlSchemaIdentityConstraint is XmlSchemaUnique)
                        {
                            XmlSchemaUnique        xmlSchemaUnique        = xmlSchemaIdentityConstraint as XmlSchemaUnique;
                            UniqueConstraintSchema uniqueConstraintSchema = new UniqueConstraintSchema(this, xmlSchemaUnique);
                            uniqueConstraintSchema.Table.Add(uniqueConstraintSchema);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// The foreign constraints can only be evaluated after all the tables, keys and unique constraints have been evaluated.
        /// </summary>
        /// <param name="xmlSchema"></param>
        private void SecondPass(XmlSchemaSet xmlSchemaSet)
        {
            // This is the second pass through the schemas.  Once the tables, keys and unique constraints have been evaluated,
            // then the foreign constraints can be constructed and applied to the parent and child tables.
            foreach (XmlSchemaElement xmlSchemaElement in xmlSchemaSet.GlobalElements.Values)
            {
                // Only the Microsoft DataSet element is evaluated for foreign keys.
                if (ObjectSchema.IsDataSetElement(xmlSchemaElement))
                {
                    // This will examine each of the constraints looking for a foreign key description.
                    foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints)
                    {
                        // Evaluate the foreign keys in the data model.
                        if (xmlSchemaIdentityConstraint is XmlSchemaKeyref)
                        {
                            // This object can be used as a foreign key constraint and, optionally, can be used to describe a
                            // parent/child relationship.
                            XmlSchemaKeyref xmlSchemaKeyref = xmlSchemaIdentityConstraint as XmlSchemaKeyref;

                            // This creates a foreign key.
                            ForeignKeyConstraintSchema foreignKeyConstraintSchema = new ForeignKeyConstraintSchema(this, xmlSchemaIdentityConstraint as XmlSchemaKeyref);

                            // Foreign constraint schemas are always added to the list of constraints on a table.  They can also
                            // conditionally become the source for a relationship between two tables.
                            foreignKeyConstraintSchema.Table.Add(foreignKeyConstraintSchema);

                            // Unless specifically instructed to supress the relation, it will be created add added to both the
                            // parent and child tables as well as the data model.
                            XmlAttribute isConstraintOnlyAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaIdentityConstraint, QualifiedName.ConstraintOnly);
                            if (isConstraintOnlyAttribute == null || !Convert.ToBoolean(isConstraintOnlyAttribute.Value))
                            {
                                RelationSchema relationSchema = new RelationSchema(this, xmlSchemaKeyref);
                                relationSchema.ParentTable.ChildRelations.Add(relationSchema.Name, relationSchema);
                                relationSchema.ChildTable.ParentRelations.Add(relationSchema.Name, relationSchema);
                                this.Relations.Add(relationSchema.Name, relationSchema);
                            }
                        }
                    }
                }
            }
        }