@Override
  public void onTraversalStart() {

    sampleCollection = new SampleCollection(getHeaderForReads());

    logger.log(Level.INFO, "Reading targets locations from intervals...");

    targetCollection = resolveTargetCollection();

    // Initializing count and count column management member fields:
    countColumns = groupBy.countColumns(this);
    final int columnCount = countColumns.columnCount();
    counts = new int[columnCount][targetCollection.targetCount()];

    // Open output files and write headers:
    outputWriter =
        openOutputWriter(
            output,
            composeMatrixOutputHeader(
                getCommandLine(), targetOutInfo, groupBy, countColumns.columnNames()));
    if (columnSummaryOutput != null) {
      columnSummaryOutputWriter =
          openOutputWriter(
              columnSummaryOutput,
              composeColumnSummaryHeader(
                  getCommandLine(),
                  groupBy,
                  targetCollection.targetCount(),
                  targetCollection.totalSize()));
    }
    if (rowSummaryOutput != null) {
      rowSummaryOutputWriter =
          openOutputWriter(
              rowSummaryOutput,
              composeRowOutputHeader(
                  getCommandLine(), targetOutInfo, groupBy, countColumns.columnCount()));
    }

    // Next we start the traversal:
    logger.log(Level.INFO, "Collecting read counts ...");
  }
  @Override
  public Object onTraversalSuccess() {
    logger.log(Level.INFO, "Collecting read counts done.");
    logger.log(Level.INFO, "Writing counts ...");
    final long[] columnTotals = calculateColumnTotals();

    IntStream.range(0, targetCollection.targetCount())
        .forEach(
            target -> {
              final int[] countBuffer =
                  IntStream.range(0, counts.length).map(column -> counts[column][target]).toArray();
              writeOutputRows(countBuffer, columnTotals, target);
            });
    logger.log(Level.INFO, "Writing counts done.");

    writeColumnSummaryOutput();
    return "SUCCESS";
  }
 /**
  * Composes the target information output string.
  *
  * @param index of the target in the collection.
  * @param collection the target containing collection.
  * @throws IllegalArgumentException if either {@code target} or {@code collection} is {@code
  *     null}.
  */
 protected String composeTargetOutInfoString(
     final int index, final TargetCollection<Target> collection) {
   Utils.nonNull(collection, "the collection cannot be null");
   Utils.validIndex(index, collection.targetCount());
   return composer.apply(index, collection);
 }