private static bool RemapsInheritedProperties(
            DbDatabaseMapping databaseMapping, StorageEntityTypeMapping entityTypeMapping)
        {
            var inheritedProperties = entityTypeMapping.EntityType.Properties
                                                       .Except(entityTypeMapping.EntityType.DeclaredProperties)
                                                       .Except(entityTypeMapping.EntityType.GetKeyProperties());

            foreach (var property in inheritedProperties)
            {
                var fragment = GetFragmentForPropertyMapping(entityTypeMapping, property);

                if (fragment != null)
                {
                    // find if this inherited property is mapped to another table by a base type
                    var baseType = (EntityType)entityTypeMapping.EntityType.BaseType;
                    while (baseType != null)
                    {
                        if (databaseMapping.GetEntityTypeMappings(baseType)
                                           .Select(baseTypeMapping => GetFragmentForPropertyMapping(baseTypeMapping, property))
                                           .Any(
                                               baseFragment => baseFragment != null
                                                               && baseFragment.Table != fragment.Table))
                        {
                            return true;
                        }
                        baseType = (EntityType)baseType.BaseType;
                    }
                }
            }
            return false;
        }
        private static EntityType FindParentTable(
            DbDatabaseMapping databaseMapping,
            EntityType fromTable,
            StorageEntityTypeMapping entityTypeMapping,
            EntityType toTable,
            bool isMappingInheritedProperties,
            int configurationIndex,
            int configurationCount,
            out bool isSplitting)
        {
            EntityType parentTable = null;
            isSplitting = false;
            // Check for entity splitting first, since splitting on a derived type in TPT/TPC will always have fromTable != toTable
            if (entityTypeMapping.UsesOtherTables(toTable)
                || configurationCount > 1)
            {
                if (configurationIndex != 0)
                {
                    // Entity Splitting case
                    parentTable = entityTypeMapping.GetPrimaryTable();
                    isSplitting = true;
                }
            }

            if (parentTable == null
                && fromTable != toTable
                && !isMappingInheritedProperties)
            {
                // TPT case
                var baseType = entityTypeMapping.EntityType.BaseType;
                while (baseType != null
                       && parentTable == null)
                {
                    // Traverse to first anscestor with a mapping
                    var baseMapping = databaseMapping.GetEntityTypeMappings((EntityType)baseType).FirstOrDefault();
                    if (baseMapping != null)
                    {
                        parentTable = baseMapping.GetPrimaryTable();
                    }
                    baseType = baseType.BaseType;
                }
            }

            return parentTable;
        }
        private bool DiscoverIsSharingWithBase(
            DbDatabaseMapping databaseMapping, EntityType entityType, EntityType toTable)
        {
            var isSharingTableWithBase = false;

            if (entityType.BaseType != null)
            {
                var baseType = entityType.BaseType;
                var anyBaseMappings = false;

                while (baseType != null
                       && !isSharingTableWithBase)
                {
                    var baseMappings = databaseMapping.GetEntityTypeMappings((EntityType)baseType);

                    if (baseMappings.Any())
                    {
                        isSharingTableWithBase =
                            baseMappings.SelectMany(m => m.MappingFragments).Any(tmf => tmf.Table == toTable);
                        anyBaseMappings = true;
                    }

                    baseType = baseType.BaseType;
                }

                if (!anyBaseMappings)
                {
                    isSharingTableWithBase = TableName == null || string.IsNullOrWhiteSpace(TableName.Name);
                }
            }
            return isSharingTableWithBase;
        }
        private void ConfigurePropertyMappings(
            DbDatabaseMapping databaseMapping,
            EntityType entityType,
            DbProviderManifest providerManifest,
            bool allowOverride = false)
        {
            DebugCheck.NotNull(databaseMapping);
            DebugCheck.NotNull(entityType);
            DebugCheck.NotNull(providerManifest);

            var entityTypeMappings = databaseMapping.GetEntityTypeMappings(entityType);

            var propertyMappings
                = (from etm in entityTypeMappings
                   from etmf in etm.MappingFragments
                   from pm in etmf.ColumnMappings
                   select Tuple.Create(pm, etmf.Table))
                    .ToList();

            ConfigurePropertyMappings(propertyMappings, providerManifest, allowOverride);

            _entityMappingConfigurations.Each(
                c => c.ConfigurePropertyMappings(
                    propertyMappings, providerManifest, allowOverride));

            foreach (var derivedEntityType 
                in databaseMapping.Model.EntityTypes.Where(et => et.BaseType == entityType))
            {
                ConfigurePropertyMappings(databaseMapping, derivedEntityType, providerManifest, true);
            }
        }
        internal void Configure(
            EntityType entityType,
            DbDatabaseMapping databaseMapping,
            DbProviderManifest providerManifest)
        {
            DebugCheck.NotNull(entityType);
            DebugCheck.NotNull(databaseMapping);
            DebugCheck.NotNull(providerManifest);

            var entityTypeMapping
                = databaseMapping.GetEntityTypeMapping(entityType.GetClrType());

            if (entityTypeMapping != null)
            {
                VerifyAllCSpacePropertiesAreMapped(
                    databaseMapping.GetEntityTypeMappings(entityType).ToList(),
                    entityTypeMapping.EntityType.DeclaredProperties,
                    new List<EdmProperty>());
            }

            ConfigurePropertyMappings(databaseMapping, entityType, providerManifest);
            ConfigureAssociationMappings(databaseMapping, entityType, providerManifest);
            ConfigureDependentKeys(databaseMapping, providerManifest);
            ConfigureModificationFunctions(databaseMapping, entityType, providerManifest);
        }
        private void ConfigurePropertyMappings(
            DbDatabaseMapping databaseMapping,
            EntityType entityType,
            DbProviderManifest providerManifest,
            bool allowOverride = false)
        {
            DebugCheck.NotNull(databaseMapping);
            DebugCheck.NotNull(entityType);
            DebugCheck.NotNull(providerManifest);

            var entityTypeMappings
                = databaseMapping.GetEntityTypeMappings(entityType);

            var propertyMappings
                = (from etm in entityTypeMappings
                    from etmf in etm.MappingFragments
                    from pm in etmf.ColumnMappings
                    select Tuple.Create(pm, etmf.Table))
                    .ToList();

            ConfigurePropertyMappings(propertyMappings, providerManifest, allowOverride);

            _entityMappingConfigurations
                .Each(c => c.ConfigurePropertyMappings(propertyMappings, providerManifest, allowOverride));

            // Now, apply to any inherited (IsOfType) mappings
            var inheritedPropertyMappings
                = (from esm in databaseMapping.GetEntitySetMappings()
                    from etm in esm.EntityTypeMappings
                    where etm.IsHierarchyMapping
                          && etm.EntityType.IsAncestorOf(entityType)
                    from etmf in etm.MappingFragments
                    from pm1 in etmf.ColumnMappings
                    where !propertyMappings.Any(pm2 => pm2.Item1.PropertyPath.SequenceEqual(pm1.PropertyPath))
                    select Tuple.Create(pm1, etmf.Table))
                    .ToList();

            ConfigurePropertyMappings(inheritedPropertyMappings, providerManifest);

            _entityMappingConfigurations
                .Each(c => c.ConfigurePropertyMappings(inheritedPropertyMappings, providerManifest));

            foreach (var derivedEntityType 
                in databaseMapping.Model.EntityTypes.Where(et => et.BaseType == entityType))
            {
                ConfigurePropertyMappings(databaseMapping, derivedEntityType, providerManifest, true);
            }
        }