private void Transform()
        {
            foreach (var entitySet in _entityTypes.GetEntitySets())
            {
                var setRootMappings = new Dictionary <TableMapping, Dictionary <EntityType, StorageEntityTypeMapping> >();

                foreach (var entityType in _entityTypes.GetEntityTypes(entitySet))
                {
                    foreach (
                        var tableMapping in
                        _tableMappings.Values.Where(tm => tm.EntityTypes.Contains(entitySet, entityType)))
                    {
                        Dictionary <EntityType, StorageEntityTypeMapping> rootMappings;
                        if (!setRootMappings.TryGetValue(tableMapping, out rootMappings))
                        {
                            rootMappings = new Dictionary <EntityType, StorageEntityTypeMapping>();
                            setRootMappings.Add(tableMapping, rootMappings);
                        }

                        RemoveRedundantDefaultDiscriminators(tableMapping);

                        var requiresIsTypeOf = DetermineRequiresIsTypeOf(tableMapping, entitySet, entityType);
                        var requiresSplit    = false;

                        // Find the entity type mapping and fragment for this table / entity type mapping where properties will be mapped
                        StorageEntityTypeMapping propertiesTypeMapping;
                        StorageMappingFragment   propertiesTypeMappingFragment;
                        if (
                            !FindPropertyEntityTypeMapping(
                                tableMapping,
                                entitySet,
                                entityType,
                                requiresIsTypeOf,
                                out propertiesTypeMapping,
                                out propertiesTypeMappingFragment))
                        {
                            continue;
                        }

                        // Determine if the entity type mapping needs to be split into separate properties and condition type mappings.
                        requiresSplit = DetermineRequiresSplitEntityTypeMapping(
                            tableMapping, entityType, requiresIsTypeOf);

                        // Find the entity type mapping and fragment for this table / entity type mapping where conditions will be mapped
                        var conditionTypeMapping
                            = FindConditionTypeMapping(entityType, requiresSplit, propertiesTypeMapping);

                        var conditionTypeMappingFragment
                            = FindConditionTypeMappingFragment(
                                  _databaseMapping.Database.GetEntitySet(tableMapping.Table),
                                  propertiesTypeMappingFragment,
                                  conditionTypeMapping);

                        // Set the IsTypeOf appropriately
                        if (requiresIsTypeOf)
                        {
                            if (propertiesTypeMapping.IsHierarchyMapping == false)
                            {
                                var isTypeOfEntityTypeMapping =
                                    _databaseMapping.GetEntityTypeMappings(entityType).SingleOrDefault(
                                        etm => etm.IsHierarchyMapping);

                                if (isTypeOfEntityTypeMapping == null)
                                {
                                    if (propertiesTypeMapping.MappingFragments.Count > 1)
                                    {
                                        // Need to create a new entity type mapping with the non-IsTypeOf contents
                                        var nonIsTypeOfEntityTypeMapping = propertiesTypeMapping.Clone();
                                        var parentEntitySetMapping       =
                                            _databaseMapping.GetEntitySetMappings().Single(
                                                esm => esm.EntityTypeMappings.Contains(propertiesTypeMapping));
                                        parentEntitySetMapping.AddTypeMapping(nonIsTypeOfEntityTypeMapping);
                                        foreach (
                                            var fragment in
                                            propertiesTypeMapping.MappingFragments.Where(
                                                tmf => tmf != propertiesTypeMappingFragment).ToArray())
                                        {
                                            propertiesTypeMapping.RemoveFragment(fragment);
                                            nonIsTypeOfEntityTypeMapping.AddFragment(fragment);
                                        }
                                    }
                                    // else we just use the existing property mapping

                                    propertiesTypeMapping.AddIsOfType(propertiesTypeMapping.EntityType);
                                }
                                else
                                {
                                    // found an existing IsTypeOf mapping, so re-use that one
                                    propertiesTypeMapping.RemoveFragment(propertiesTypeMappingFragment);

                                    if (propertiesTypeMapping.MappingFragments.Count == 0)
                                    {
                                        _databaseMapping
                                        .GetEntitySetMapping(entitySet)
                                        .RemoveTypeMapping(propertiesTypeMapping);
                                    }

                                    propertiesTypeMapping = isTypeOfEntityTypeMapping;
                                    propertiesTypeMapping.AddFragment(propertiesTypeMappingFragment);
                                }
                            }
                            rootMappings.Add(entityType, propertiesTypeMapping);
                        }

                        ConfigureTypeMappings(
                            tableMapping, rootMappings, entityType, propertiesTypeMappingFragment,
                            conditionTypeMappingFragment);

                        if (propertiesTypeMappingFragment.IsUnmappedPropertiesFragment()
                            &&
                            propertiesTypeMappingFragment.ColumnMappings.All(
                                pm => entityType.GetKeyProperties().Contains(pm.PropertyPath.First())))
                        {
                            RemoveFragment(entitySet, propertiesTypeMapping, propertiesTypeMappingFragment);

                            if (requiresSplit
                                &&
                                conditionTypeMappingFragment.ColumnMappings.All(
                                    pm => entityType.GetKeyProperties().Contains(pm.PropertyPath.First())))
                            {
                                RemoveFragment(entitySet, conditionTypeMapping, conditionTypeMappingFragment);
                            }
                        }

                        EntityMappingConfiguration.CleanupUnmappedArtifacts(_databaseMapping, tableMapping.Table);

                        foreach (var fkConstraint in tableMapping.Table.ForeignKeyBuilders)
                        {
                            var associationType = fkConstraint.GetAssociationType();
                            if (associationType != null &&
                                associationType.IsRequiredToNonRequired())
                            {
                                AssociationEndMember _, dependentEnd;
                                fkConstraint.GetAssociationType().TryGuessPrincipalAndDependentEnds(
                                    out _, out dependentEnd);

                                if (dependentEnd.GetEntityType() == entityType)
                                {
                                    MarkColumnsAsNonNullableIfNoTableSharing(
                                        entitySet, tableMapping.Table, entityType, fkConstraint.DependentColumns);
                                }
                            }
                        }
                    }
                }

                ConfigureAssociationSetMappingForeignKeys(entitySet);
            }
        }