private static Map<String, String> checkOptions(Map<String, String> options)
      throws IllegalArgumentException {

    if (options.get(OPTION_MODE) == null) {
      throw new IllegalArgumentException(String.format(COMMAND_LINE_PARSER_MODE_PARAM_MANDATORY));
    }

    options = setDefaultIfNotPresent(options, OPTION_MODE, OStressTester.OMode.PLOCAL.name());
    options = setDefaultIfNotPresent(options, OPTION_CONCURRENCY, "4");
    options = setDefaultIfNotPresent(options, OPTION_TRANSACTIONS, "0");
    options = setDefaultIfNotPresent(options, OPTION_WORKLOAD, "CRUD:C25000R25000U25000D25000");

    try {
      OStressTester.OMode.valueOf(options.get(OPTION_MODE).toUpperCase());
    } catch (IllegalArgumentException ex) {
      throw new IllegalArgumentException(
          String.format(COMMAND_LINE_PARSER_INVALID_MODE, options.get(OPTION_MODE)));
    }

    return options;
  }
  /**
   * builds a StressTester object using the command line arguments
   *
   * @param args
   * @return
   * @throws Exception
   */
  public static OStressTester getStressTester(String[] args) throws Exception {

    final Map<String, String> options = checkOptions(readOptions(args));

    final OStressTesterSettings settings = new OStressTesterSettings();

    settings.dbName =
        TEMP_DATABASE_NAME + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    settings.mode = OStressTester.OMode.valueOf(options.get(OPTION_MODE).toUpperCase());
    settings.rootPassword = options.get(OPTION_ROOT_PASSWORD);
    settings.resultOutputFile = options.get(OPTION_OUTPUT_FILE);
    settings.plocalPath = options.get(OPTION_PLOCAL_PATH);
    settings.operationsPerTransaction = getNumber(options.get(OPTION_TRANSACTIONS), "transactions");
    settings.concurrencyLevel = getNumber(options.get(OPTION_CONCURRENCY), "concurrency");
    settings.remoteIp = options.get(OPTION_REMOTE_IP);
    settings.haMetrics =
        options.get(OPTION_HA_METRICS) != null
            ? Boolean.parseBoolean(options.get(OPTION_HA_METRICS))
            : false;
    settings.workloadCfg = options.get(OPTION_WORKLOAD);
    settings.keepDatabaseAfterTest =
        options.get(OPTION_KEEP_DATABASE_AFTER_TEST) != null
            ? Boolean.parseBoolean(options.get(OPTION_KEEP_DATABASE_AFTER_TEST))
            : false;
    settings.remotePort = 2424;
    settings.checkDatabase = Boolean.parseBoolean(options.get(OPTION_CHECK_DATABASE));

    if (settings.plocalPath != null) {
      if (settings.plocalPath.endsWith(File.separator)) {
        settings.plocalPath =
            settings.plocalPath.substring(
                0, settings.plocalPath.length() - File.separator.length());
      }
      File plocalFile = new File(settings.plocalPath);
      if (!plocalFile.exists()) {
        throw new IllegalArgumentException(
            String.format(COMMAND_LINE_PARSER_NOT_EXISTING_PLOCAL_PATH, settings.plocalPath));
      }
      if (!plocalFile.canWrite()) {
        throw new IllegalArgumentException(
            String.format(
                COMMAND_LINE_PARSER_NO_WRITE_PERMISSION_PLOCAL_PATH, settings.plocalPath));
      }
      if (!plocalFile.isDirectory()) {
        throw new IllegalArgumentException(
            String.format(COMMAND_LINE_PARSER_PLOCAL_PATH_IS_NOT_DIRECTORY, settings.plocalPath));
      }
    }

    if (settings.resultOutputFile != null) {

      File outputFile = new File(settings.resultOutputFile);
      if (outputFile.exists()) {
        outputFile.delete();
      }

      File parentFile = outputFile.getParentFile();

      // if the filename does not contain a path (both relative and absolute)
      if (parentFile == null) {
        parentFile = new File(".");
      }

      if (!parentFile.exists()) {
        throw new IllegalArgumentException(
            String.format(
                COMMAND_LINE_PARSER_NOT_EXISTING_OUTPUT_DIRECTORY, parentFile.getAbsoluteFile()));
      }
      if (!parentFile.canWrite()) {
        throw new IllegalArgumentException(
            String.format(
                COMMAND_LINE_PARSER_NO_WRITE_PERMISSION_OUTPUT_FILE, parentFile.getAbsoluteFile()));
      }
    }

    if (options.get(OPTION_REMOTE_PORT) != null) {
      settings.remotePort = getNumber(options.get(OPTION_REMOTE_PORT), "remotePort");
      if (settings.remotePort > 65535) {
        throw new IllegalArgumentException(
            String.format(COMMAND_LINE_PARSER_INVALID_REMOTE_PORT_NUMBER, settings.remotePort));
      }
    }

    if (settings.mode == OStressTester.OMode.DISTRIBUTED) {
      throw new IllegalArgumentException(
          String.format("OMode [%s] not yet supported.", settings.mode));
    }

    if (settings.mode == OStressTester.OMode.REMOTE && settings.remoteIp == null) {
      throw new IllegalArgumentException(COMMAND_LINE_PARSER_MISSING_REMOTE_IP);
    }

    if (settings.rootPassword == null && settings.mode == OStressTester.OMode.REMOTE) {
      Console console = System.console();
      if (console != null) {
        settings.rootPassword =
            String.valueOf(
                console.readPassword(
                    String.format(
                        CONSOLE_REMOTE_PASSWORD_PROMPT, settings.remoteIp, settings.remotePort)));
      } else {
        throw new Exception(ERROR_OPENING_CONSOLE);
      }
    }

    final List<OWorkload> workloads = parseWorkloads(settings.workloadCfg);

    final ODatabaseIdentifier databaseIdentifier = new ODatabaseIdentifier(settings);

    return new OStressTester(workloads, databaseIdentifier, settings);
  }