/// <summary>
        /// </summary>
        /// <param name="source"></param>
        /// <param name="foreignColumn"></param>
        /// <param name="foreignTableName"></param>
        /// <returns></returns>
        public static TableAssociation FromChildManyToMany(TableEntity source, IMemberColumnSchema foreignColumn, string foreignTableName)
        {
            TableAssociation association = null;

            //ASpNetUser -> AspNetUserInRole -> AspnetRole
            IEntity intermediaryEntity = EntityStore.Instance.GetEntity(foreignColumn.Table.FullName) ?? EntityStore.Instance.GetExcludedEntity(foreignColumn.Table.FullName);
            IEntity rightEntity        = EntityStore.Instance.GetEntity(foreignTableName);

            if (intermediaryEntity != null && rightEntity != null)
            {
                int leftIndex  = source.EntityKeyName.Equals(foreignColumn.Table.ForeignKeys[0].PrimaryKeyMemberColumns[0].Table.Name, StringComparison.OrdinalIgnoreCase) ? 0 : 1;
                int rightIndex = leftIndex == 1 ? 0 : 1;

                var intermediaryAssocation = new TableAssociation(foreignColumn.Table.ForeignKeys[rightIndex], AssociationType.ManyToMany, rightEntity, intermediaryEntity, false, isChildManyToMany: true, sourceManyToManyTable: source);
                association = new TableAssociation(foreignColumn.Table.ForeignKeys[leftIndex], AssociationType.ManyToMany, source, intermediaryEntity, true, intermediaryAssociation: intermediaryAssocation, isChildManyToMany: true);
                //End Association between AspNetUser -> ASpNetRole with Intermediary table as a property
            }

            if (association == null || association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey))
            {
                return(null);
            }

            return(association);
        }
        /// <summary>
        /// </summary>
        /// <param name="source"></param>
        /// <param name="tableKeySchema"></param>
        /// <returns></returns>
        public static TableAssociation FromChildPrimaryKey(TableEntity source, ITableKeySchema tableKeySchema)
        {
            //In Child Associations, the ForeignKey should be the associated entity
            IEntity associationEntity = EntityStore.Instance.GetEntity(tableKeySchema.ForeignKeyTable.FullName);

            if (associationEntity == null && !Configuration.Instance.IncludeManyToManyEntity && tableKeySchema.ForeignKeyTable.IsManyToMany())
            {
                associationEntity = EntityStore.Instance.GetExcludedEntity(tableKeySchema.ForeignKeyTable.FullName);
            }

            if (associationEntity == null)
            {
                return(null);
            }

            TableAssociation association = null;

            foreach (IMemberColumnSchema foreignColumn in tableKeySchema.ForeignKeyMemberColumns)
            {
                //Added a check to see if the FK is also a Foreign composite key (http://community.codesmithtools.com/forums/t/10266.aspx).
                bool isForeignKeyAlsoComposite = foreignColumn.Table.HasPrimaryKey && foreignColumn.Table.PrimaryKey.MemberColumns.Count > 1 && foreignColumn.IsPrimaryKeyMember && foreignColumn.IsForeignKeyMember;

                if (!foreignColumn.IsPrimaryKeyMember || isForeignKeyAlsoComposite)
                {
                    if (foreignColumn.Table.IsManyToMany())
                    {
                        //&& foreignTable != null) // NOTE: This can because a ManyToMany can be to itself.
                        ITableSchema foreignTable = GetToManyTable(foreignColumn.Table, source.EntitySource) ?? source.EntitySource;
                        association = FromChildManyToMany(source, foreignColumn, foreignTable.FullName);
                    }
                    else
                    {
                        var type = AssociationType.OneToMany;
                        if (tableKeySchema.ForeignKeyMemberColumns.Count(m => m.AllowDBNull) == tableKeySchema.ForeignKeyMemberColumns.Count)
                        {
                            type = AssociationType.ZeroOrOneToMany;
                        }
                        else if (!isForeignKeyAlsoComposite && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.IsUnique || m.IsPrimaryKeyMember) == tableKeySchema.ForeignKeyMemberColumns.Count)
                        {
                            type = AssociationType.OneToZeroOrOne;
                        }

                        association = new TableAssociation(tableKeySchema, type, source, associationEntity, true);
                    }
                }
                else if (GetToManyTable(foreignColumn.Table, source.EntitySource) == null)
                {
                    association = new TableAssociation(tableKeySchema, AssociationType.OneToZeroOrOne, source, associationEntity, true);
                }
            }

            //End Association between AspNetUser -> ASpNetRole with Intermediary table as a property
            if (association == null || association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey))
            {
                return(null);
            }

            return(association);
        }
        /// <summary>
        /// Populates the Child Associations
        /// </summary>
        private void GetChildAssociations()
        {
            foreach (TableKeySchema tableKeySchema in EntitySource.PrimaryKeys)
            {
                IAssociation association = TableAssociation.FromChildPrimaryKey(this, tableKeySchema);

                // Always overwrite the previous associations if they exist because this is the parent association.
                if (association != null && !String.IsNullOrEmpty(association.AssociationKey))
                {
                    AssociationMap[association.AssociationKey] = association;
                }
            }
        }
        /// <summary>
        /// Populates the Parent Associations
        /// </summary>
        private void GetParentAssociations()
        {
            if (EntitySource.IsManyToMany())
            {
                TableAssociation association = TableAssociation.FromParentManyToMany(this);
                if (association != null && !AssociationMap.ContainsKey(association.AssociationKey))
                {
                    AssociationMap.Add(association.AssociationKey, association);
                    return;
                }
            }

            foreach (TableKeySchema tableKeySchema in EntitySource.ForeignKeys)
            {
                TableAssociation association = TableAssociation.FromParentForeignKey(this, tableKeySchema);
                if (association != null && !AssociationMap.ContainsKey(association.AssociationKey))
                {
                    AssociationMap.Add(association.AssociationKey, association);
                }
            }
        }
        /// <summary>
        /// Gets a parent many to many association from a foreign key.
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static TableAssociation FromParentManyToMany(TableEntity source)
        {
            if (!source.EntitySource.IsManyToMany())
            {
                return(null);
            }

            //ASpNetUser -> AspNetUserInRole -> AspnetRole
            ITableSchema rightTable = GetToManyTable(source.EntitySource, source.EntitySource);
            ITableSchema leftTable  = GetToManyTable(source.EntitySource, rightTable) ?? GetToManyTable(source.EntitySource, source.EntitySource); // This could be a Many-To-Many relation ship to the same table User (User) -> UserMappings <- User (Usee).

            if (leftTable == null || rightTable == null)
            {
                return(null);
            }

            IEntity rightEntity = EntityStore.Instance.GetEntity(rightTable.FullName);
            IEntity leftEntity  = EntityStore.Instance.GetEntity(leftTable.FullName);

            if (leftEntity == null || rightEntity == null)
            {
                return(null);
            }

            int leftIndex  = leftEntity.EntityKeyName.Equals(source.EntitySource.ForeignKeys[0].PrimaryKeyMemberColumns[0].Table.Name, StringComparison.OrdinalIgnoreCase) ? 0 : 1;
            int rightIndex = leftIndex == 1 ? 0 : 1;

            var intermediaryAssocation = new TableAssociation(source.EntitySource.ForeignKeys[rightIndex], AssociationType.ManyToMany, source, rightEntity, true);
            var association            = new TableAssociation(source.EntitySource.ForeignKeys[leftIndex], AssociationType.ManyToMany, source, leftEntity, true, intermediaryAssociation: intermediaryAssocation);

            //End Association between AspNetUser -> ASpNetRole with Intermediary table as a property
            if (association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey))
            {
                return(null);
            }

            return(association);
        }
        /// <summary>
        /// Gets a parent association from a foreign key.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="tableKeySchema"></param>
        /// <returns></returns>
        public static TableAssociation FromParentForeignKey(TableEntity source, ITableKeySchema tableKeySchema)
        {
            //In Parent Associations, the Primary table should be the Associated IEntity
            IEntity foreignEntity = EntityStore.Instance.GetEntity(tableKeySchema.PrimaryKeyTable.FullName);

            if (foreignEntity == null)
            {
                Trace.WriteLine("Foreign Key not generated since related Table not included in generation");
                return(null);
            }

            bool isParentMany      = false;
            bool isParentOne       = false;
            bool isParentOneOrZero = false;
            bool isParentUnique    = tableKeySchema.PrimaryKeyMemberColumns.Count(m => m.IsUnique || m.IsPrimaryKeyMember) == tableKeySchema.PrimaryKeyMemberColumns.Count;

            if (isParentUnique && tableKeySchema.PrimaryKeyMemberColumns.Count(m => m.AllowDBNull) != tableKeySchema.PrimaryKeyMemberColumns.Count)
            {
                isParentOne = true;
            }
            else if (isParentUnique && tableKeySchema.PrimaryKeyMemberColumns.Count(m => m.AllowDBNull) == tableKeySchema.PrimaryKeyMemberColumns.Count)
            {
                isParentOneOrZero = true;
            }
            else
            {
                isParentMany = true;
            }

            bool isForeignKeyAlsoComposite = tableKeySchema.ForeignKeyTable.HasPrimaryKey && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count > 1;

            bool isChildMany      = false;
            bool isChildOne       = false;
            bool isChildOneOrZero = false;
            bool isChildUnique    = !isForeignKeyAlsoComposite && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.IsUnique || m.IsPrimaryKeyMember) == tableKeySchema.ForeignKeyMemberColumns.Count;

            if (isChildUnique && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.AllowDBNull) != tableKeySchema.ForeignKeyMemberColumns.Count)
            {
                isChildOne = true;
            }
            else if (isChildUnique && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.AllowDBNull) == tableKeySchema.ForeignKeyMemberColumns.Count)
            {
                isChildOneOrZero = true;
            }
            else
            {
                isChildMany = true;
            }

            var type = AssociationType.ManyToOne;

            if (isChildMany && isParentMany)
            {
                type = AssociationType.ManyToMany;
            }
            else if (isChildMany && isParentOne)
            {
                type = AssociationType.ManyToOne;
            }
            else if (isChildMany && isParentOneOrZero)
            {
                type = AssociationType.ManyToZeroOrOne;
            }
            else if (isChildOne && isParentMany)
            {
                type = AssociationType.OneToMany;
            }
            else if (isChildOne && isParentOne)
            {
                type = AssociationType.OneToOne;
            }
            else if (isChildOne && isParentOneOrZero)
            {
                type = AssociationType.OneToZeroOrOne;
            }
            else if (isChildOneOrZero && isParentMany)
            {
                type = AssociationType.ZeroOrOneToMany;
            }
            else
            {
                Debug.WriteLine("Contact support cause you have a crazy up schema.");
            }

            var association = new TableAssociation(tableKeySchema, type, source, foreignEntity, false);

            if (association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey))
            {
                return(null);
            }

            return(association);
        }