public static ModelMapping Build(HandlerAccessor handlers, SchemaExtractionResult sqlModel, MappingResolver resolver, NodeConfiguration nodeConfiguration, bool isLegacy)
        {
            var domainModel   = handlers.Domain.Model;
            var configuration = handlers.Domain.Configuration;
            var providerInfo  = handlers.ProviderInfo;

            var mapping = new ModelMapping();

            // Register persistent types

            var typesToProcess = domainModel.Types.AsEnumerable();

            if (isLegacy || configuration.IsMultidatabase)
            {
                typesToProcess = typesToProcess.Where(t => !t.IsSystem);
            }

            foreach (var type in typesToProcess)
            {
                var primaryIndex = type.Indexes.FindFirst(IndexAttributes.Real | IndexAttributes.Primary);
                if (primaryIndex == null || primaryIndex.IsAbstract)
                {
                    continue;
                }
                var reflectedType = primaryIndex.ReflectedType;
                var nodeName      = resolver.GetNodeName(reflectedType);
                var storageTable  = resolver.Resolve(sqlModel, nodeName).GetTable();
                if (storageTable == null)
                {
                    throw new DomainBuilderException(String.Format(Strings.ExTableXIsNotFound, nodeName));
                }
                mapping.Register(reflectedType, storageTable);
            }

            // Register key generators

            var keyGenerator = domainModel.Hierarchies
                               .Select(h => h.Key.Sequence)
                               .Where(s => s != null)
                               .Distinct();

            Func <MappingResolveResult, SchemaNode> nodeResolver;

            if (providerInfo.Supports(ProviderFeatures.Sequences))
            {
                nodeResolver = r => r.GetSequence();
            }
            else
            {
                nodeResolver = r => r.GetTable();
            }

            foreach (var sequence in keyGenerator)
            {
                var nodeResult = resolver.Resolve(sqlModel, resolver.GetNodeName(sequence));
                var node       = nodeResolver.Invoke(nodeResult);
                mapping.Register(sequence, node);
            }

            // Fill information for TemporaryTableManager

            var defaultSchema = resolver.ResolveSchema(sqlModel, configuration.DefaultDatabase, configuration.DefaultSchema);

            if (configuration.ShareStorageSchemaOverNodes && handlers.ProviderInfo.Supports(ProviderFeatures.Multischema))
            {
                mapping.TemporaryTableDatabase = nodeConfiguration.GetActualNameFor(defaultSchema.Catalog);
                mapping.TemporaryTableSchema   = nodeConfiguration.GetActualNameFor(defaultSchema);
            }
            else
            {
                mapping.TemporaryTableDatabase = defaultSchema.Catalog.GetNameInternal();
                mapping.TemporaryTableSchema   = defaultSchema.GetNameInternal();
            }

            if (providerInfo.Supports(ProviderFeatures.Collations))
            {
                if (!string.IsNullOrEmpty(configuration.Collation))
                {
                    // If user explicitly specified collation use that
                    mapping.TemporaryTableCollation = configuration.Collation;
                }
                else
                {
                    // Otherwise use first available collation
                    var collation = defaultSchema.Collations.FirstOrDefault();
                    mapping.TemporaryTableCollation = collation != null ? collation.Name : null;
                }
            }

            mapping.Lock();
            return(mapping);
        }