class ThemisRowCounter {

  public static Job createSubmittableJob(Configuration conf, String[] args)
  throws IOException {
    String tableName = args[0];
    String startKey = null;
    String endKey = null;
    StringBuilder sb = new StringBuilder();

    final String rangeSwitch = "--range=";

    // First argument is table name, starting from second
    for (int i = 1; i < args.length; i++) {
      if (args[i].startsWith(rangeSwitch)) {
        String[] startEnd = args[i].substring(rangeSwitch.length()).split(",", 2);
        if (startEnd.length != 2 || startEnd[1].contains(",")) {
          printUsage("Please specify range in such format as \"--range=a,b\" " +
              "or, with only one boundary, \"--range=,b\" or \"--range=a,\"");
          return null;
        }
        startKey = startEnd[0];
        endKey = startEnd[1];
      }
      else {
        // if no switch, assume column names
        sb.append(args[i]);
        sb.append(" ");
      }
    }

    Job job = new Job(conf, NAME + "_" + tableName);
    job.setJarByClass(RowCounter.class);
    Scan scan = new Scan();
    scan.setCacheBlocks(false);
    if (startKey != null && !startKey.equals("")) {
      scan.setStartRow(Bytes.toBytes(startKey));
    }
    if (endKey != null && !endKey.equals("")) {
      scan.setStopRow(Bytes.toBytes(endKey));
    }
    scan.setFilter(new FirstKeyOnlyFilter());
    if (sb.length() > 0) {
      for (String columnName : sb.toString().trim().split(" ")) {
        String family = StringUtils.substringBefore(columnName, ":");
        String qualifier = StringUtils.substringAfter(columnName, ":");
        if (StringUtils.isBlank(qualifier)) {
          throw new IOException("must specify qualifier to read themis table");
        } else {
          scan.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));
        }
      }
    }
    job.setOutputFormatClass(NullOutputFormat.class);
    ThemisTableMapReduceUtil.initTableMapperJob(tableName, scan,
      RowCounterMapper.class, ImmutableBytesWritable.class, Result.class, job);
    job.setNumReduceTasks(0);
    return job;
  }

}