/**
   * 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));
    }
  }
 /**
  * Returns the aggregation value of a specific column and type.
  *
  * @param path The aggregation path.
  * @param columnId The requested column id.
  * @param type The requested aggregation type.
  * @return The aggregation values of a specific column.
  */
 public Value getAggregationValue(AggregationPath path, String columnId, AggregationType type) {
   return tree.getNode(path).getAggregationValue(columnId, type);
 }
 /**
  * Returns a set containing the paths to all the leaves in the tree.
  *
  * @return A set containing the paths to all the leaves in the tree.
  */
 public Set<AggregationPath> getPathsToLeaves() {
   return tree.getPathsToLeaves();
 }