}
public final ExpressionNode rewrite() throws CompilerException
{
final ArrayDescriptor tableDescriptor = this.table.arrayDescriptor();
if (tableDescriptor.numberOfColumns() == ArrayDescriptor.DYNAMIC) {
throw new CompilerException.SectionOrientation( "The function "
+ this.fun.getFunction() + " can only operate on vertically repeating sections." );
}
// We need the type info to properly treat by-example criteria contained in strings.
TypeAnnotator.annotateExpr( this.table );
final List<ExpressionNode> tableElements = this.table.arguments();
final List<String> tableLabels = getLabelsFromTable( tableDescriptor, tableElements );
final List<ExpressionNode> dataElements = stripLabelsFromTable( tableDescriptor, tableElements );
final List<CellModel> firstRow = getFirstRowFromTable( tableDescriptor, dataElements );
final DataType[] colTypes = getColTypesFromFirstRow( firstRow );
final int[] foldableColumnKeys = getFoldableColumnKeys( colTypes );
final ExpressionNode data = getShapedDataFromTable( tableDescriptor, dataElements );
final ArrayDescriptor critDescriptor = this.criteria.arrayDescriptor();
final List<ExpressionNode> critElements = this.criteria.arguments();
final List<String> critLabels = getLabelsFromTable( critDescriptor, critElements );
final List<ExpressionNode> critData = stripLabelsFromTable( critDescriptor, critElements );
final int[] critCols = associateCriteriaColumnsWithTableLabels( tableLabels, critLabels );