public virtual string ScriptMigrations(
            string fromMigrationName,
            string toMigrationName,
            bool idempotent = false)
        {
            var migrations = _migrationAssembly.Migrations;

            if (string.IsNullOrEmpty(fromMigrationName))
            {
                fromMigrationName = InitialDatabase;
            }
            else if (fromMigrationName != InitialDatabase)
            {
                fromMigrationName = _idGenerator.ResolveId(fromMigrationName, migrations);
            }

            if (string.IsNullOrEmpty(toMigrationName))
            {
                toMigrationName = migrations.Last().Id;
            }
            else if (toMigrationName != InitialDatabase)
            {
                toMigrationName = _idGenerator.ResolveId(toMigrationName, migrations);
            }

            var builder = new IndentedStringBuilder();

            // If going up...
            if (string.Compare(fromMigrationName, toMigrationName, StringComparison.OrdinalIgnoreCase) <= 0)
            {
                var migrationsToApply = migrations.Where(
                    m => string.Compare(m.Id, fromMigrationName, StringComparison.OrdinalIgnoreCase) > 0 &&
                    string.Compare(m.Id, toMigrationName, StringComparison.OrdinalIgnoreCase) <= 0);
                var checkFirst = true;
                foreach (var migration in migrationsToApply)
                {
                    if (checkFirst)
                    {
                        if (migration == migrations[0])
                        {
                            builder.AppendLine(_historyRepository.Create(ifNotExists: true));
                            builder.AppendLine(_sqlGenerator.BatchSeparator);
                            builder.AppendLine();
                        }

                        checkFirst = false;
                    }

                    _logger.Value.LogVerbose(Strings.GeneratingUp(migration.Id));

                    foreach (var batch in ApplyMigration(migration))
                    {
                        if (idempotent)
                        {
                            builder.AppendLine(_historyRepository.BeginIfNotExists(migration.Id));
                            using (builder.Indent())
                            {
                                var lines = batch.Sql.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                                foreach (var line in lines)
                                {
                                    builder.AppendLine(line);
                                }
                            }
                            builder.AppendLine(_historyRepository.EndIf());
                        }
                        else
                        {
                            builder.Append(batch.Sql);
                        }

                        builder.AppendLine(_sqlGenerator.BatchSeparator);
                        builder.AppendLine();
                    }
                }
            }
            else // If going down...
            {
                var migrationsToRevert = migrations
                                         .Where(
                    m => string.Compare(m.Id, toMigrationName, StringComparison.OrdinalIgnoreCase) > 0 &&
                    string.Compare(m.Id, fromMigrationName, StringComparison.OrdinalIgnoreCase) <= 0)
                                         .OrderByDescending(m => m.Id);
                foreach (var migration in migrationsToRevert)
                {
                    _logger.Value.LogVerbose(Strings.GeneratingDown(migration.Id));

                    foreach (var batch in RevertMigration(migration))
                    {
                        if (idempotent)
                        {
                            builder.AppendLine(_historyRepository.BeginIfExists(migration.Id));
                            using (builder.Indent())
                            {
                                var lines = batch.Sql.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                                foreach (var line in lines)
                                {
                                    builder.AppendLine(line);
                                }
                            }
                            builder.AppendLine(_historyRepository.EndIf());
                        }
                        else
                        {
                            builder.Append(batch.Sql);
                        }

                        builder.AppendLine(_sqlGenerator.BatchSeparator);
                        builder.AppendLine();
                    }
                }
            }

            return(builder.ToString());
        }