public void resolveLevel(int level) {
        if (groupBy != null) {
            if (level == 0) {
                throw new IllegalArgumentException("Operation '" + this + "' can not group " +
                                                   getLevelDesc(level) + ".");
            }
            groupBy.resolveLevel(level - 1);
            ++level;
        }
        if (hasMax()) {
            if (level == 0) {
                throw new IllegalArgumentException("Operation '" + this + "' can not apply max to " +
                                                   getLevelDesc(level) + ".");
            }
        }
        this.level = level;
        for (GroupingExpression exp : outputs) {
            exp.resolveLevel(level);
        }
        if (!orderBy.isEmpty()) {
            if (level == 0) {
                throw new IllegalArgumentException("Operation '" + this + "' can not order " +
                                                   getLevelDesc(level) + ".");
            }
            for (GroupingExpression exp : orderBy) {
                exp.resolveLevel(level - 1);
            }
        }
        for (GroupingOperation child : children) {
            child.resolveLevel(level);
        }
    }
Resolves the conceptual level of this operation. This level represents the type of data that is consumed by this
operation, where level 0 is a single hit, level 1 is a group, level 2 is a list of groups, and so forth. This
method verifies the input level against the operation type, and recursively resolves the level of all argument
expressions.

@param level the level of the input data
@throws IllegalArgumentException thrown if a contained expression is invalid for the given level
container-search/src/main/java/com/yahoo/search/grouping/request/GroupingOperation.java