@SuppressWarnings("unchecked")
  public boolean parseOptions(String args[]) {

    Options options = new Options();
    options.addOption(OUTPUT_DIR_OPTION, true, "Output directory" + Workload.MERGE.onlyUsedFor());
    options.addOption(
        COMPRESSION_OPTION,
        true,
        " Compression type, one of "
            + Arrays.toString(Compression.Algorithm.values())
            + Workload.MERGE.onlyUsedFor());
    options.addOption(
        BLOOM_FILTER_OPTION,
        true,
        "Bloom filter type, one of "
            + Arrays.toString(StoreFile.BloomType.values())
            + Workload.MERGE.onlyUsedFor());
    options.addOption(BLOCK_SIZE_OPTION, true, "HFile block size" + Workload.MERGE.onlyUsedFor());
    options.addOption(
        DURATION_OPTION,
        true,
        "The amount of time to run the "
            + "random read workload for"
            + Workload.RANDOM_READS.onlyUsedFor());
    options.addOption(
        NUM_THREADS_OPTION,
        true,
        "The number of random " + "reader threads" + Workload.RANDOM_READS.onlyUsedFor());
    options.addOption(
        NUM_THREADS_OPTION,
        true,
        "The number of random " + "reader threads" + Workload.RANDOM_READS.onlyUsedFor());
    options.addOption(
        LoadTestTool.OPT_DATA_BLOCK_ENCODING, true, LoadTestTool.OPT_DATA_BLOCK_ENCODING_USAGE);
    options.addOption(
        LoadTestTool.OPT_ENCODE_IN_CACHE_ONLY, false, LoadTestTool.OPT_ENCODE_IN_CACHE_ONLY_USAGE);
    options.addOptionGroup(Workload.getOptionGroup());

    if (args.length == 0) {
      HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp(HFileReadWriteTest.class.getSimpleName(), options, true);
      return false;
    }

    CommandLineParser parser = new PosixParser();
    CommandLine cmdLine;
    try {
      cmdLine = parser.parse(options, args);
    } catch (ParseException ex) {
      LOG.error(ex);
      return false;
    }

    workload = Workload.fromCmdLine(cmdLine);
    if (workload == null) return false;

    inputFileNames = (List<String>) cmdLine.getArgList();

    if (inputFileNames.size() == 0) {
      LOG.error("No input file names specified");
      return false;
    }

    if (inputFileNames.size() < workload.minNumInputFiles) {
      LOG.error("Too few input files: at least " + workload.minNumInputFiles + " required");
      return false;
    }

    if (inputFileNames.size() > workload.maxNumInputFiles) {
      LOG.error("Too many input files: at most " + workload.minNumInputFiles + " allowed");
      return false;
    }

    if (cmdLine.hasOption(COMPRESSION_OPTION)) {
      compression = Compression.Algorithm.valueOf(cmdLine.getOptionValue(COMPRESSION_OPTION));
    }

    if (cmdLine.hasOption(BLOOM_FILTER_OPTION)) {
      bloomType = StoreFile.BloomType.valueOf(cmdLine.getOptionValue(BLOOM_FILTER_OPTION));
    }

    encodeInCacheOnly = cmdLine.hasOption(LoadTestTool.OPT_ENCODE_IN_CACHE_ONLY);

    if (cmdLine.hasOption(LoadTestTool.OPT_DATA_BLOCK_ENCODING)) {
      dataBlockEncoding =
          DataBlockEncoding.valueOf(cmdLine.getOptionValue(LoadTestTool.OPT_DATA_BLOCK_ENCODING));
      // Optionally encode on disk, always encode in cache.
      dataBlockEncoder =
          new HFileDataBlockEncoderImpl(
              encodeInCacheOnly ? DataBlockEncoding.NONE : dataBlockEncoding, dataBlockEncoding);
    } else {
      if (encodeInCacheOnly) {
        LOG.error(
            "The -"
                + LoadTestTool.OPT_ENCODE_IN_CACHE_ONLY
                + " option does not make sense without -"
                + LoadTestTool.OPT_DATA_BLOCK_ENCODING);
        return false;
      }
    }

    blockSize = conf.getInt("hfile.min.blocksize.size", 65536);
    if (cmdLine.hasOption(BLOCK_SIZE_OPTION))
      blockSize = Integer.valueOf(cmdLine.getOptionValue(BLOCK_SIZE_OPTION));

    if (workload == Workload.MERGE) {
      String outputDirStr = cmdLine.getOptionValue(OUTPUT_DIR_OPTION);
      if (outputDirStr == null) {
        LOG.error("Output directory is not specified");
        return false;
      }
      outputDir = new Path(outputDirStr);
      // Will be checked for existence in validateConfiguration.
    }

    if (workload == Workload.RANDOM_READS) {
      if (!requireOptions(cmdLine, new String[] {DURATION_OPTION, NUM_THREADS_OPTION})) {
        return false;
      }

      durationSec = Integer.parseInt(cmdLine.getOptionValue(DURATION_OPTION));
      numReadThreads = Integer.parseInt(cmdLine.getOptionValue(NUM_THREADS_OPTION));
    }

    Collections.sort(inputFileNames);

    return true;
  }