/**
   * Main method.
   *
   * @param args The command-line arguments.
   */
  public static void main(final String[] args) {
    final Level logLevel = getLogLevel(args);
    initLogging(logLevel);

    try {
      if (isPrintVersionAndExit(args)) {
        printVersion();
        System.exit(0);
      }

      final List<String> operations = determineOperations(args);
      if (operations.isEmpty()) {
        printUsage();
        return;
      }

      final Properties properties = new Properties();
      initializeDefaults(properties);
      loadConfiguration(properties, args);
      overrideConfiguration(properties, args);
      dumpConfiguration(properties);

      loadJdbcDrivers();
      loadJavaMigrationsFromJarDirs(properties);

      final List<SqlStatement> sqlStatements = new LinkedList<SqlStatement>();
      final FlywayWithDryRun flyway = new FlywayWithDryRun(sqlStatements);
      filterProperties(properties);
      flyway.configure(properties);

      for (final String operation : operations) {
        executeOperation(flyway, operation, sqlStatements);
      }
    } catch (final Exception e) {
      if (logLevel == Level.DEBUG) {
        LOG.error("Unexpected error", e);
      } else {
        if (e instanceof FlywayException) {
          LOG.error(e.getMessage());
        } else {
          LOG.error(e.toString());
        }
      }
      System.exit(1);
    }
  }
  /**
   * Executes this operation on this Flyway instance.
   *
   * @param flyway The Flyway instance.
   * @param operation The operation to execute.
   * @param sqlStatements The current list of all pending migrations.
   */
  private static void executeOperation(
      final FlywayWithDryRun flyway,
      final String operation,
      final Iterable<SqlStatement> sqlStatements) {
    if ("clean".equals(operation)) {
      flyway.clean();
    } else if ("baseline".equals(operation)) {
      flyway.baseline();
    } else if ("migrate".equals(operation)) {
      flyway.migrate();
    } else if ("dryRunMigrate".equals(operation)) {
      flyway.dryRunMigrate();

      final StringBuilder stringBuilder = new StringBuilder("BEGIN;\n");
      for (final SqlStatement sqlStatement : sqlStatements) {
        stringBuilder.append(sqlStatement.getSql()).append(";\n");
      }
      stringBuilder.append("COMMIT;");
      LOG.info("\n" + stringBuilder.toString());
    } else if ("validate".equals(operation)) {
      flyway.validate();
    } else if ("info".equals(operation)) {
      LOG.info("\n" + MigrationInfoDumper.dumpToAsciiTable(flyway.info().all()));
    } else if ("repair".equals(operation)) {
      flyway.repair();
    } else {
      LOG.error("Invalid operation: " + operation);
      printUsage();
      System.exit(1);
    }
  }