/**
   * Constructs a table aggregator and aggregates the table.
   *
   * @param groupByColumns An ordered list of columns to group by.
   * @param aggregateColumns A set of columns to aggregate.
   * @param table The table.
   */
  public TableAggregator(
      List<String> groupByColumns, Set<String> aggregateColumns, DataTable table) {

    this.groupByColumns = groupByColumns;
    this.aggregateColumns = aggregateColumns;

    tree = new AggregationTree(aggregateColumns, table);

    // Iterate over all rows and aggregate each row via the aggregation tree.
    for (TableRow row : table.getRows()) {
      tree.aggregate(
          getRowPath(row, table, groupByColumns.size() - 1), getValuesToAggregate(row, table));
    }
  }