liquibase-core/src/main/java/liquibase/integration/commandline/Main.java
protected void doMigration() throws Exception {
        if (COMMANDS.HELP.equalsIgnoreCase(command)) {
            printHelp(System.err);
            return;
        }

        try {
//            if (null != logFile) {
//                Scope.getCurrentScope().getLog(getClass()).setLogLevel(logLevel, logFile);
//            } else {
//                Scope.getCurrentScope().getLog(getClass()).setLogLevel(logLevel);
//            }
        } catch (IllegalArgumentException e) {
            throw new CommandLineParsingException(e.getMessage(), e);
        }

        FileSystemResourceAccessor fsOpener = new FileSystemResourceAccessor();
        CommandLineResourceAccessor clOpener = new CommandLineResourceAccessor(classLoader);
        CompositeResourceAccessor fileOpener = new CompositeResourceAccessor(fsOpener, clOpener);

        Database database = CommandLineUtils.createDatabaseObject(fileOpener, this.url,
                this.username, this.password, this.driver, this.defaultCatalogName, this.defaultSchemaName,
                Boolean.parseBoolean(outputDefaultCatalog), Boolean.parseBoolean(outputDefaultSchema),
                this.databaseClass, this.driverPropertiesFile, this.propertyProviderClass,
                this.liquibaseCatalogName, this.liquibaseSchemaName, this.databaseChangeLogTableName,
                this.databaseChangeLogLockTableName);
        database.setLiquibaseTablespaceName(this.databaseChangeLogTablespaceName);
        try {

            if ((excludeObjects != null) && (includeObjects != null)) {
                throw new UnexpectedLiquibaseException(
                        String.format(coreBundle.getString("cannot.specify.both"),
                                OPTIONS.EXCLUDE_OBJECTS, OPTIONS.INCLUDE_OBJECTS));
            }

            ObjectChangeFilter objectChangeFilter = null;
            CompareControl.ComputedSchemas computedSchemas = CompareControl.computeSchemas(
                    schemas,
                    referenceSchemas,
                    outputSchemasAs,
                    defaultCatalogName, defaultSchemaName,
                    referenceDefaultCatalogName, referenceDefaultSchemaName,
                    database);

            CompareControl.SchemaComparison[] finalSchemaComparisons = computedSchemas.finalSchemaComparisons;
            DiffOutputControl diffOutputControl = new DiffOutputControl(
                    includeCatalog, includeSchema, includeTablespace, finalSchemaComparisons);

            if (excludeObjects != null) {
                objectChangeFilter = new StandardObjectChangeFilter(StandardObjectChangeFilter.FilterType.EXCLUDE,
                        excludeObjects);
                diffOutputControl.setObjectChangeFilter(objectChangeFilter);
            }

            if (includeObjects != null) {
                objectChangeFilter = new StandardObjectChangeFilter(StandardObjectChangeFilter.FilterType.INCLUDE,
                        includeObjects);
                diffOutputControl.setObjectChangeFilter(objectChangeFilter);
            }

            for (CompareControl.SchemaComparison schema : finalSchemaComparisons) {
                diffOutputControl.addIncludedSchema(schema.getReferenceSchema());
                diffOutputControl.addIncludedSchema(schema.getComparisonSchema());
            }

            if (COMMANDS.DIFF.equalsIgnoreCase(command)) {
                CommandLineUtils.doDiff(
                        createReferenceDatabaseFromCommandParams(commandParams, fileOpener),
                        database, StringUtil.trimToNull(diffTypes), finalSchemaComparisons
                );
                return;
            } else if (COMMANDS.DIFF_CHANGELOG.equalsIgnoreCase(command)) {
                CommandLineUtils.doDiffToChangeLog(changeLogFile,
                        createReferenceDatabaseFromCommandParams(commandParams, fileOpener),
                        database,
                        diffOutputControl, objectChangeFilter, StringUtil.trimToNull(diffTypes), finalSchemaComparisons
                );
                return;
            } else if (COMMANDS.GENERATE_CHANGELOG.equalsIgnoreCase(command)) {
                String currentChangeLogFile = this.changeLogFile;
                if (currentChangeLogFile == null) {
                    //will output to stdout:
                    currentChangeLogFile = "";
                }

                File file = new File(currentChangeLogFile);
                if (file.exists() && (!Boolean.parseBoolean(overwriteOutputFile))) {
                    throw new LiquibaseException(
                            String.format(coreBundle.getString("changelogfile.already.exists"), currentChangeLogFile));
                } else {
                    try {
                        if (!file.delete()) {
                            // Nothing needs to be done
                        }
                    } catch (SecurityException e) {
                        throw new LiquibaseException(
                                String.format(coreBundle.getString("attempt.to.delete.the.file.failed.cannot.continue"),
                                        currentChangeLogFile
                                ), e
                        );
                    }
                }

                CatalogAndSchema[] finalTargetSchemas = computedSchemas.finalTargetSchemas;
                CommandLineUtils.doGenerateChangeLog(currentChangeLogFile, database, finalTargetSchemas,
                        StringUtil.trimToNull(diffTypes), StringUtil.trimToNull(changeSetAuthor),
                        StringUtil.trimToNull(changeSetContext), StringUtil.trimToNull(dataOutputDirectory),
                        diffOutputControl);
                return;
            } else if (COMMANDS.SNAPSHOT.equalsIgnoreCase(command)) {
                SnapshotCommand snapshotCommand = (SnapshotCommand) CommandFactory.getInstance()
                        .getCommand(COMMANDS.SNAPSHOT);
                snapshotCommand.setDatabase(database);
                snapshotCommand.setSchemas(
                        getCommandParam(
                                OPTIONS.SCHEMAS, database.getDefaultSchema().getSchemaName()
                        )
                );
                snapshotCommand.setSerializerFormat(getCommandParam("snapshotFormat", null));
                Writer outputWriter = getOutputWriter();
                String result = snapshotCommand.execute().print();
                outputWriter.write(result);
                outputWriter.flush();
                outputWriter.close();
                return;
            } else if (COMMANDS.EXECUTE_SQL.equalsIgnoreCase(command)) {
                ExecuteSqlCommand executeSqlCommand = (ExecuteSqlCommand) CommandFactory.getInstance().getCommand(
                        COMMANDS.EXECUTE_SQL);
                executeSqlCommand.setDatabase(database);
                executeSqlCommand.setSql(getCommandParam("sql", null));
                executeSqlCommand.setSqlFile(getCommandParam("sqlFile", null));
                executeSqlCommand.setDelimiter(getCommandParam("delimiter", ";"));
                Writer outputWriter = getOutputWriter();
                outputWriter.write(executeSqlCommand.execute().print());
                outputWriter.flush();
                outputWriter.close();
                return;
            } else if (COMMANDS.SNAPSHOT_REFERENCE.equalsIgnoreCase(command)) {
                SnapshotCommand snapshotCommand = (SnapshotCommand) CommandFactory.getInstance()
                        .getCommand(COMMANDS.SNAPSHOT);
                Database referenceDatabase = createReferenceDatabaseFromCommandParams(commandParams, fileOpener);
                snapshotCommand.setDatabase(referenceDatabase);
                snapshotCommand.setSchemas(
                        getCommandParam(
                                OPTIONS.SCHEMAS, referenceDatabase.getDefaultSchema().getSchemaName()
                        )
                );
                Writer outputWriter = getOutputWriter();
                outputWriter.write(snapshotCommand.execute().print());
                outputWriter.flush();
                outputWriter.close();

                return;
            }

            Liquibase liquibase = new Liquibase(changeLogFile, fileOpener, database);
            ChangeExecListener listener = ChangeExecListenerUtils.getChangeExecListener(
                    liquibase.getDatabase(), liquibase.getResourceAccessor(),
                    changeExecListenerClass, changeExecListenerPropertiesFile);
            liquibase.setChangeExecListener(listener);

            database.setCurrentDateTimeFunction(currentDateTimeFunction);
            for (Map.Entry<String, Object> entry : changeLogParameters.entrySet()) {
                liquibase.setChangeLogParameter(entry.getKey(), entry.getValue());
            }

            if (COMMANDS.LIST_LOCKS.equalsIgnoreCase(command)) {
                liquibase.reportLocks(System.err);
                return;
            } else if (COMMANDS.RELEASE_LOCKS.equalsIgnoreCase(command)) {
                LockService lockService = LockServiceFactory.getInstance().getLockService(database);
                lockService.forceReleaseLock();
                Scope.getCurrentScope().getLog(getClass()).info(LogType.USER_MESSAGE, String.format(
                        coreBundle.getString("successfully.released.database.change.log.locks"),
                        liquibase.getDatabase().getConnection().getConnectionUserName() +
                                "@" + liquibase.getDatabase().getConnection().getURL()
                        )
                );
                return;
            } else if (COMMANDS.TAG.equalsIgnoreCase(command)) {
                liquibase.tag(getCommandArgument());
                Scope.getCurrentScope().getLog(getClass()).info(
                        LogType.LOG, String.format(
                                coreBundle.getString("successfully.tagged"), liquibase.getDatabase()
                                        .getConnection().getConnectionUserName() + "@" +
                                        liquibase.getDatabase().getConnection().getURL()
                        )
                );
                return;
            } else if (COMMANDS.TAG_EXISTS.equalsIgnoreCase(command)) {
                String tag = commandParams.iterator().next();
                boolean exists = liquibase.tagExists(tag);
                if (exists) {
                    Scope.getCurrentScope().getLog(getClass()).info(
                            LogType.LOG, String.format(coreBundle.getString("tag.exists"), tag,
                                    liquibase.getDatabase().getConnection().getConnectionUserName() + "@" +
                                            liquibase.getDatabase().getConnection().getURL()
                            )
                    );
                } else {
                    Scope.getCurrentScope().getLog(getClass()).info(
                            LogType.LOG, String.format(coreBundle.getString("tag.does.not.exist"), tag,
                                    liquibase.getDatabase().getConnection().getConnectionUserName() + "@" +
                                            liquibase.getDatabase().getConnection().getURL()
                            )
                    );
                }
                return;
            } else if (COMMANDS.DROP_ALL.equals(command)) {
                DropAllCommand dropAllCommand = (DropAllCommand) CommandFactory.getInstance().getCommand
                        (COMMANDS.DROP_ALL);
                dropAllCommand.setDatabase(liquibase.getDatabase());
                dropAllCommand.setSchemas(getCommandParam(
                        OPTIONS.SCHEMAS, database.getDefaultSchema().getSchemaName())
                );

                Scope.getCurrentScope().getLog(getClass()).info(LogType.USER_MESSAGE, dropAllCommand.execute().print());
                return;
            } else if (COMMANDS.STATUS.equalsIgnoreCase(command)) {
                boolean runVerbose = false;

                if (commandParams.contains("--" + OPTIONS.VERBOSE)) {
                    runVerbose = true;
                }
                liquibase.reportStatus(runVerbose, new Contexts(contexts), new LabelExpression(labels),
                        getOutputWriter());
                return;
            } else if (COMMANDS.UNEXPECTED_CHANGESETS.equalsIgnoreCase(command)) {
                boolean runVerbose = false;

                if (commandParams.contains("--" + OPTIONS.VERBOSE)) {
                    runVerbose = true;
                }
                liquibase.reportUnexpectedChangeSets(runVerbose, contexts, getOutputWriter());
                return;
            } else if (COMMANDS.VALIDATE.equalsIgnoreCase(command)) {
                try {
                    liquibase.validate();
                } catch (ValidationFailedException e) {
                    e.printDescriptiveError(System.err);
                    return;
                }
                Scope.getCurrentScope().getLog(getClass()).info(
                        LogType.USER_MESSAGE, coreBundle.getString("no.validation.errors.found"));
                return;
            } else if (COMMANDS.CLEAR_CHECKSUMS.equalsIgnoreCase(command)) {
                liquibase.clearCheckSums();
                return;
            } else if (COMMANDS.CALCULATE_CHECKSUM.equalsIgnoreCase(command)) {
                CheckSum checkSum = null;
                checkSum = liquibase.calculateCheckSum(commandParams.iterator().next());
                Scope.getCurrentScope().getLog(getClass()).info(LogType.USER_MESSAGE, checkSum.toString());
                return;
            } else if (COMMANDS.DB_DOC.equalsIgnoreCase(command)) {
                if (commandParams.isEmpty()) {
                    throw new CommandLineParsingException(coreBundle.getString("dbdoc.requires.output.directory"));
                }
                if (changeLogFile == null) {
                    throw new CommandLineParsingException(coreBundle.getString("dbdoc.requires.changelog.parameter"));
                }
                liquibase.generateDocumentation(commandParams.iterator().next(), contexts);
                return;
            }

            try {
                if (COMMANDS.UPDATE.equalsIgnoreCase(command)) {
                    liquibase.update(new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.CHANGELOG_SYNC.equalsIgnoreCase(command)) {
                    liquibase.changeLogSync(new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.CHANGELOG_SYNC_SQL.equalsIgnoreCase(command)) {
                    liquibase.changeLogSync(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.MARK_NEXT_CHANGESET_RAN.equalsIgnoreCase(command)) {
                    liquibase.markNextChangeSetRan(new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.MARK_NEXT_CHANGESET_RAN_SQL.equalsIgnoreCase(command)) {
                    liquibase.markNextChangeSetRan(new Contexts(contexts), new LabelExpression(labels),
                            getOutputWriter());
                } else if (COMMANDS.UPDATE_COUNT.equalsIgnoreCase(command)) {
                    liquibase.update(Integer.parseInt(commandParams.iterator().next()), new Contexts(contexts), new
                            LabelExpression(labels));
                } else if (COMMANDS.UPDATE_COUNT_SQL.equalsIgnoreCase(command)) {
                    liquibase.update(Integer.parseInt(commandParams.iterator().next()), new Contexts(contexts), new
                            LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.UPDATE_TO_TAG.equalsIgnoreCase(command)) {
                    if ((commandParams == null) || commandParams.isEmpty()) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"), COMMANDS.UPDATE_TO_TAG));
                    }

                    liquibase.update(commandParams.iterator().next(), new Contexts(contexts), new LabelExpression
                            (labels));
                } else if (COMMANDS.UPDATE_TO_TAG_SQL.equalsIgnoreCase(command)) {
                    if ((commandParams == null) || commandParams.isEmpty()) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"),
                                        COMMANDS.UPDATE_TO_TAG_SQL));
                    }

                    liquibase.update(commandParams.iterator().next(), new Contexts(contexts), new LabelExpression
                            (labels), getOutputWriter());
                } else if (COMMANDS.UPDATE_SQL.equalsIgnoreCase(command)) {
                    liquibase.update(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.ROLLBACK.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"), COMMANDS.ROLLBACK));
                    }
                    liquibase.rollback(getCommandArgument(), getCommandParam(COMMANDS.ROLLBACK_SCRIPT, null), new
                            Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.ROLLBACK_TO_DATE.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.timestamp"),
                                        COMMANDS.ROLLBACK_TO_DATE));
                    }
                    liquibase.rollback(new ISODateFormat().parse(getCommandArgument()), getCommandParam
                            (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.ROLLBACK_COUNT.equalsIgnoreCase(command)) {
                    liquibase.rollback(Integer.parseInt(getCommandArgument()), getCommandParam
                            (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts), new LabelExpression(labels));

                } else if (COMMANDS.ROLLBACK_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"),
                                        COMMANDS.ROLLBACK_SQL));
                    }
                    liquibase.rollback(getCommandArgument(), getCommandParam(COMMANDS.ROLLBACK_SCRIPT, null), new
                            Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.ROLLBACK_TO_DATE_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.timestamp"),
                                        COMMANDS.ROLLBACK_TO_DATE_SQL));
                    }
                    liquibase.rollback(new ISODateFormat().parse(getCommandArgument()), getCommandParam
                                    (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts), new LabelExpression
                                    (labels),
                            getOutputWriter());
                } else if (COMMANDS.ROLLBACK_COUNT_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.count"),
                                        COMMANDS.ROLLBACK_COUNT_SQL));
                    }

                    liquibase.rollback(Integer.parseInt(getCommandArgument()), getCommandParam
                                    (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts),
                            new LabelExpression(labels),
                            getOutputWriter()
                    );
                } else if (COMMANDS.FUTURE_ROLLBACK_SQL.equalsIgnoreCase(command)) {
                    liquibase.futureRollbackSQL(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.FUTURE_ROLLBACK_COUNT_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.count"),
                                        COMMANDS.FUTURE_ROLLBACK_COUNT_SQL));
                    }

                    liquibase.futureRollbackSQL(Integer.parseInt(getCommandArgument()), new Contexts(contexts), new
                            LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.FUTURE_ROLLBACK_FROM_TAG_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"),
                                        COMMANDS.FUTURE_ROLLBACK_FROM_TAG_SQL));
                    }

                    liquibase.futureRollbackSQL(getCommandArgument(), new Contexts(contexts), new LabelExpression
                            (labels), getOutputWriter());
                } else if (COMMANDS.UPDATE_TESTING_ROLLBACK.equalsIgnoreCase(command)) {
                    liquibase.updateTestingRollback(new Contexts(contexts), new LabelExpression(labels));
                } else {
                    throw new CommandLineParsingException(
                            String.format(coreBundle.getString("command.unknown"), command));
                }
            } catch (ParseException ignored) {
                throw new CommandLineParsingException(
                        coreBundle.getString("timeformat.invalid"));
            }
        } finally {
            try {
                database.rollback();
                database.close();
            } catch (DatabaseException e) {
                Scope.getCurrentScope().getLog(getClass()).warning(
                        LogType.LOG, coreBundle.getString("problem.closing.connection"), e);
            }
        }
    }
protected void doMigration() throws Exception {
        if (COMMANDS.HELP.equalsIgnoreCase(command)) {
            printHelp(System.err);
            return;
        }

        try {
//            if (null != logFile) {
//                Scope.getCurrentScope().getLog(getClass()).setLogLevel(logLevel, logFile);
//            } else {
//                Scope.getCurrentScope().getLog(getClass()).setLogLevel(logLevel);
//            }
        } catch (IllegalArgumentException e) {
            throw new CommandLineParsingException(e.getMessage(), e);
        }

        FileSystemResourceAccessor fsOpener = new FileSystemResourceAccessor();
        CommandLineResourceAccessor clOpener = new CommandLineResourceAccessor(classLoader);
        CompositeResourceAccessor fileOpener = new CompositeResourceAccessor(fsOpener, clOpener);

        Database database = CommandLineUtils.createDatabaseObject(fileOpener, this.url,
                this.username, this.password, this.driver, this.defaultCatalogName, this.defaultSchemaName,
                Boolean.parseBoolean(outputDefaultCatalog), Boolean.parseBoolean(outputDefaultSchema),
                this.databaseClass, this.driverPropertiesFile, this.propertyProviderClass,
                this.liquibaseCatalogName, this.liquibaseSchemaName, this.databaseChangeLogTableName,
                this.databaseChangeLogLockTableName);
        database.setLiquibaseTablespaceName(this.databaseChangeLogTablespaceName);
        try {

            if ((excludeObjects != null) && (includeObjects != null)) {
                throw new UnexpectedLiquibaseException(
                        String.format(coreBundle.getString("cannot.specify.both"),
                                OPTIONS.EXCLUDE_OBJECTS, OPTIONS.INCLUDE_OBJECTS));
            }

            ObjectChangeFilter objectChangeFilter = null;
            CompareControl.ComputedSchemas computedSchemas = CompareControl.computeSchemas(
                    schemas,
                    referenceSchemas,
                    outputSchemasAs,
                    defaultCatalogName, defaultSchemaName,
                    referenceDefaultCatalogName, referenceDefaultSchemaName,
                    database);

            CompareControl.SchemaComparison[] finalSchemaComparisons = computedSchemas.finalSchemaComparisons;
            DiffOutputControl diffOutputControl = new DiffOutputControl(
                    includeCatalog, includeSchema, includeTablespace, finalSchemaComparisons);

            if (excludeObjects != null) {
                objectChangeFilter = new StandardObjectChangeFilter(StandardObjectChangeFilter.FilterType.EXCLUDE,
                        excludeObjects);
                diffOutputControl.setObjectChangeFilter(objectChangeFilter);
            }

            if (includeObjects != null) {
                objectChangeFilter = new StandardObjectChangeFilter(StandardObjectChangeFilter.FilterType.INCLUDE,
                        includeObjects);
                diffOutputControl.setObjectChangeFilter(objectChangeFilter);
            }

            for (CompareControl.SchemaComparison schema : finalSchemaComparisons) {
                diffOutputControl.addIncludedSchema(schema.getReferenceSchema());
                diffOutputControl.addIncludedSchema(schema.getComparisonSchema());
            }

            if (COMMANDS.DIFF.equalsIgnoreCase(command)) {
                CommandLineUtils.doDiff(
                        createReferenceDatabaseFromCommandParams(commandParams, fileOpener),
                        database, StringUtil.trimToNull(diffTypes), finalSchemaComparisons
                );
                return;
            } else if (COMMANDS.DIFF_CHANGELOG.equalsIgnoreCase(command)) {
                CommandLineUtils.doDiffToChangeLog(changeLogFile,
                        createReferenceDatabaseFromCommandParams(commandParams, fileOpener),
                        database,
                        diffOutputControl, objectChangeFilter, StringUtil.trimToNull(diffTypes), finalSchemaComparisons
                );
                return;
            } else if (COMMANDS.GENERATE_CHANGELOG.equalsIgnoreCase(command)) {
                String currentChangeLogFile = this.changeLogFile;
                if (currentChangeLogFile == null) {
                    //will output to stdout:
                    currentChangeLogFile = "";
                }

                File file = new File(currentChangeLogFile);
                if (file.exists() && (!Boolean.parseBoolean(overwriteOutputFile))) {
                    throw new LiquibaseException(
                            String.format(coreBundle.getString("changelogfile.already.exists"), currentChangeLogFile));
                } else {
                    try {
                        if (!file.delete()) {
                            // Nothing needs to be done
                        }
                    } catch (SecurityException e) {
                        throw new LiquibaseException(
                                String.format(coreBundle.getString("attempt.to.delete.the.file.failed.cannot.continue"),
                                        currentChangeLogFile
                                ), e
                        );
                    }
                }

                CatalogAndSchema[] finalTargetSchemas = computedSchemas.finalTargetSchemas;
                CommandLineUtils.doGenerateChangeLog(currentChangeLogFile, database, finalTargetSchemas,
                        StringUtil.trimToNull(diffTypes), StringUtil.trimToNull(changeSetAuthor),
                        StringUtil.trimToNull(changeSetContext), StringUtil.trimToNull(dataOutputDirectory),
                        diffOutputControl);
                return;
            } else if (COMMANDS.SNAPSHOT.equalsIgnoreCase(command)) {
                SnapshotCommand snapshotCommand = (SnapshotCommand) CommandFactory.getInstance()
                        .getCommand(COMMANDS.SNAPSHOT);
                snapshotCommand.setDatabase(database);
                snapshotCommand.setSchemas(
                        getCommandParam(
                                OPTIONS.SCHEMAS, database.getDefaultSchema().getSchemaName()
                        )
                );
                snapshotCommand.setSerializerFormat(getCommandParam("snapshotFormat", null));
                Writer outputWriter = getOutputWriter();
                String result = snapshotCommand.execute().print();
                outputWriter.write(result);
                outputWriter.flush();
                outputWriter.close();
                return;
            } else if (COMMANDS.EXECUTE_SQL.equalsIgnoreCase(command)) {
                ExecuteSqlCommand executeSqlCommand = (ExecuteSqlCommand) CommandFactory.getInstance().getCommand(
                        COMMANDS.EXECUTE_SQL);
                executeSqlCommand.setDatabase(database);
                executeSqlCommand.setSql(getCommandParam("sql", null));
                executeSqlCommand.setSqlFile(getCommandParam("sqlFile", null));
                executeSqlCommand.setDelimiter(getCommandParam("delimiter", ";"));
                Writer outputWriter = getOutputWriter();
                outputWriter.write(executeSqlCommand.execute().print());
                outputWriter.flush();
                outputWriter.close();
                return;
            } else if (COMMANDS.SNAPSHOT_REFERENCE.equalsIgnoreCase(command)) {
                SnapshotCommand snapshotCommand = (SnapshotCommand) CommandFactory.getInstance()
                        .getCommand(COMMANDS.SNAPSHOT);
                Database referenceDatabase = createReferenceDatabaseFromCommandParams(commandParams, fileOpener);
                snapshotCommand.setDatabase(referenceDatabase);
                snapshotCommand.setSchemas(
                        getCommandParam(
                                OPTIONS.SCHEMAS, referenceDatabase.getDefaultSchema().getSchemaName()
                        )
                );
                Writer outputWriter = getOutputWriter();
                outputWriter.write(snapshotCommand.execute().print());
                outputWriter.flush();
                outputWriter.close();

                return;
            }

            Liquibase liquibase = new Liquibase(changeLogFile, fileOpener, database);
            ChangeExecListener listener = ChangeExecListenerUtils.getChangeExecListener(
                    liquibase.getDatabase(), liquibase.getResourceAccessor(),
                    changeExecListenerClass, changeExecListenerPropertiesFile);
            liquibase.setChangeExecListener(listener);

            database.setCurrentDateTimeFunction(currentDateTimeFunction);
            for (Map.Entry<String, Object> entry : changeLogParameters.entrySet()) {
                liquibase.setChangeLogParameter(entry.getKey(), entry.getValue());
            }

            if (COMMANDS.LIST_LOCKS.equalsIgnoreCase(command)) {
                liquibase.reportLocks(System.err);
                return;
            } else if (COMMANDS.RELEASE_LOCKS.equalsIgnoreCase(command)) {
                LockService lockService = LockServiceFactory.getInstance().getLockService(database);
                lockService.forceReleaseLock();
                Scope.getCurrentScope().getLog(getClass()).info(LogType.USER_MESSAGE, String.format(
                        coreBundle.getString("successfully.released.database.change.log.locks"),
                        liquibase.getDatabase().getConnection().getConnectionUserName() +
                                "@" + liquibase.getDatabase().getConnection().getURL()
                        )
                );
                return;
            } else if (COMMANDS.TAG.equalsIgnoreCase(command)) {
                liquibase.tag(getCommandArgument());
                Scope.getCurrentScope().getLog(getClass()).info(
                        LogType.LOG, String.format(
                                coreBundle.getString("successfully.tagged"), liquibase.getDatabase()
                                        .getConnection().getConnectionUserName() + "@" +
                                        liquibase.getDatabase().getConnection().getURL()
                        )
                );
                return;
            } else if (COMMANDS.TAG_EXISTS.equalsIgnoreCase(command)) {
                String tag = commandParams.iterator().next();
                boolean exists = liquibase.tagExists(tag);
                if (exists) {
                    Scope.getCurrentScope().getLog(getClass()).info(
                            LogType.LOG, String.format(coreBundle.getString("tag.exists"), tag,
                                    liquibase.getDatabase().getConnection().getConnectionUserName() + "@" +
                                            liquibase.getDatabase().getConnection().getURL()
                            )
                    );
                } else {
                    Scope.getCurrentScope().getLog(getClass()).info(
                            LogType.LOG, String.format(coreBundle.getString("tag.does.not.exist"), tag,
                                    liquibase.getDatabase().getConnection().getConnectionUserName() + "@" +
                                            liquibase.getDatabase().getConnection().getURL()
                            )
                    );
                }
                return;
            } else if (COMMANDS.DROP_ALL.equals(command)) {
                DropAllCommand dropAllCommand = (DropAllCommand) CommandFactory.getInstance().getCommand
                        (COMMANDS.DROP_ALL);
                dropAllCommand.setDatabase(liquibase.getDatabase());
                dropAllCommand.setSchemas(getCommandParam(
                        OPTIONS.SCHEMAS, database.getDefaultSchema().getSchemaName())
                );

                Scope.getCurrentScope().getLog(getClass()).info(LogType.USER_MESSAGE, dropAllCommand.execute().print());
                return;
            } else if (COMMANDS.STATUS.equalsIgnoreCase(command)) {
                boolean runVerbose = false;

                if (commandParams.contains("--" + OPTIONS.VERBOSE)) {
                    runVerbose = true;
                }
                liquibase.reportStatus(runVerbose, new Contexts(contexts), new LabelExpression(labels),
                        getOutputWriter());
                return;
            } else if (COMMANDS.UNEXPECTED_CHANGESETS.equalsIgnoreCase(command)) {
                boolean runVerbose = false;

                if (commandParams.contains("--" + OPTIONS.VERBOSE)) {
                    runVerbose = true;
                }
                liquibase.reportUnexpectedChangeSets(runVerbose, contexts, getOutputWriter());
                return;
            } else if (COMMANDS.VALIDATE.equalsIgnoreCase(command)) {
                try {
                    liquibase.validate();
                } catch (ValidationFailedException e) {
                    e.printDescriptiveError(System.err);
                    return;
                }
                Scope.getCurrentScope().getLog(getClass()).info(
                        LogType.USER_MESSAGE, coreBundle.getString("no.validation.errors.found"));
                return;
            } else if (COMMANDS.CLEAR_CHECKSUMS.equalsIgnoreCase(command)) {
                liquibase.clearCheckSums();
                return;
            } else if (COMMANDS.CALCULATE_CHECKSUM.equalsIgnoreCase(command)) {
                CheckSum checkSum = null;
                checkSum = liquibase.calculateCheckSum(commandParams.iterator().next());
                Scope.getCurrentScope().getLog(getClass()).info(LogType.USER_MESSAGE, checkSum.toString());
                return;
            } else if (COMMANDS.DB_DOC.equalsIgnoreCase(command)) {
                if (commandParams.isEmpty()) {
                    throw new CommandLineParsingException(coreBundle.getString("dbdoc.requires.output.directory"));
                }
                if (changeLogFile == null) {
                    throw new CommandLineParsingException(coreBundle.getString("dbdoc.requires.changelog.parameter"));
                }
                liquibase.generateDocumentation(commandParams.iterator().next(), contexts);
                return;
            }

            try {
                if (COMMANDS.UPDATE.equalsIgnoreCase(command)) {
                    liquibase.update(new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.CHANGELOG_SYNC.equalsIgnoreCase(command)) {
                    liquibase.changeLogSync(new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.CHANGELOG_SYNC_SQL.equalsIgnoreCase(command)) {
                    liquibase.changeLogSync(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.MARK_NEXT_CHANGESET_RAN.equalsIgnoreCase(command)) {
                    liquibase.markNextChangeSetRan(new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.MARK_NEXT_CHANGESET_RAN_SQL.equalsIgnoreCase(command)) {
                    liquibase.markNextChangeSetRan(new Contexts(contexts), new LabelExpression(labels),
                            getOutputWriter());
                } else if (COMMANDS.UPDATE_COUNT.equalsIgnoreCase(command)) {
                    liquibase.update(Integer.parseInt(commandParams.iterator().next()), new Contexts(contexts), new
                            LabelExpression(labels));
                } else if (COMMANDS.UPDATE_COUNT_SQL.equalsIgnoreCase(command)) {
                    liquibase.update(Integer.parseInt(commandParams.iterator().next()), new Contexts(contexts), new
                            LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.UPDATE_TO_TAG.equalsIgnoreCase(command)) {
                    if ((commandParams == null) || commandParams.isEmpty()) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"), COMMANDS.UPDATE_TO_TAG));
                    }

                    liquibase.update(commandParams.iterator().next(), new Contexts(contexts), new LabelExpression
                            (labels));
                } else if (COMMANDS.UPDATE_TO_TAG_SQL.equalsIgnoreCase(command)) {
                    if ((commandParams == null) || commandParams.isEmpty()) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"),
                                        COMMANDS.UPDATE_TO_TAG_SQL));
                    }

                    liquibase.update(commandParams.iterator().next(), new Contexts(contexts), new LabelExpression
                            (labels), getOutputWriter());
                } else if (COMMANDS.UPDATE_SQL.equalsIgnoreCase(command)) {
                    liquibase.update(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.ROLLBACK.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"), COMMANDS.ROLLBACK));
                    }
                    liquibase.rollback(getCommandArgument(), getCommandParam(COMMANDS.ROLLBACK_SCRIPT, null), new
                            Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.ROLLBACK_TO_DATE.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.timestamp"),
                                        COMMANDS.ROLLBACK_TO_DATE));
                    }
                    liquibase.rollback(new ISODateFormat().parse(getCommandArgument()), getCommandParam
                            (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts), new LabelExpression(labels));
                } else if (COMMANDS.ROLLBACK_COUNT.equalsIgnoreCase(command)) {
                    liquibase.rollback(Integer.parseInt(getCommandArgument()), getCommandParam
                            (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts), new LabelExpression(labels));

                } else if (COMMANDS.ROLLBACK_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"),
                                        COMMANDS.ROLLBACK_SQL));
                    }
                    liquibase.rollback(getCommandArgument(), getCommandParam(COMMANDS.ROLLBACK_SCRIPT, null), new
                            Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.ROLLBACK_TO_DATE_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.timestamp"),
                                        COMMANDS.ROLLBACK_TO_DATE_SQL));
                    }
                    liquibase.rollback(new ISODateFormat().parse(getCommandArgument()), getCommandParam
                                    (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts), new LabelExpression
                                    (labels),
                            getOutputWriter());
                } else if (COMMANDS.ROLLBACK_COUNT_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.count"),
                                        COMMANDS.ROLLBACK_COUNT_SQL));
                    }

                    liquibase.rollback(Integer.parseInt(getCommandArgument()), getCommandParam
                                    (COMMANDS.ROLLBACK_SCRIPT, null), new Contexts(contexts),
                            new LabelExpression(labels),
                            getOutputWriter()
                    );
                } else if (COMMANDS.FUTURE_ROLLBACK_SQL.equalsIgnoreCase(command)) {
                    liquibase.futureRollbackSQL(new Contexts(contexts), new LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.FUTURE_ROLLBACK_COUNT_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.count"),
                                        COMMANDS.FUTURE_ROLLBACK_COUNT_SQL));
                    }

                    liquibase.futureRollbackSQL(Integer.parseInt(getCommandArgument()), new Contexts(contexts), new
                            LabelExpression(labels), getOutputWriter());
                } else if (COMMANDS.FUTURE_ROLLBACK_FROM_TAG_SQL.equalsIgnoreCase(command)) {
                    if (getCommandArgument() == null) {
                        throw new CommandLineParsingException(
                                String.format(coreBundle.getString("command.requires.tag"),
                                        COMMANDS.FUTURE_ROLLBACK_FROM_TAG_SQL));
                    }

                    liquibase.futureRollbackSQL(getCommandArgument(), new Contexts(contexts), new LabelExpression
                            (labels), getOutputWriter());
                } else if (COMMANDS.UPDATE_TESTING_ROLLBACK.equalsIgnoreCase(command)) {
                    liquibase.updateTestingRollback(new Contexts(contexts), new LabelExpression(labels));
                } else {
                    throw new CommandLineParsingException(
                            String.format(coreBundle.getString("command.unknown"), command));
                }
            } catch (ParseException ignored) {
                throw new CommandLineParsingException(
                        coreBundle.getString("timeformat.invalid"));
            }
        } finally {
            try {
                database.rollback();
                database.close();
            } catch (DatabaseException e) {
                Scope.getCurrentScope().getLog(getClass()).warning(
                        LogType.LOG, coreBundle.getString("problem.closing.connection"), e);
            }
        }
    }
Do the actual database migration, i.e. apply the ChangeSets.

@throws Exception