class DataSetLookupConstraints extends DataSetConstraints<DataSetLookupConstraints> {

    public DataSetLookup newDataSetLookup(DataSetMetadata metatada) {
        DataSetLookupBuilder<DataSetLookupBuilderImpl> builder = DataSetLookupFactory.newDataSetLookupBuilder();
        builder.dataset(metatada.getUUID());

        Set<Integer> exclude = new HashSet<Integer>();
        int startIndex = 0;

        // A group lookup requires to add a group-ready column
        if (groupRequired) {
            int groupIdx = getGroupColumn(metatada);
            if (groupIdx == -1) {
                throw new IllegalStateException("The data set does not contains group-able columns (label or date)");
            }
            // Add the group column
            exclude.add(groupIdx);
            builder.group(metatada.getColumnId(groupIdx));
            builder.column(metatada.getColumnId(groupIdx));
            startIndex = 1;
        }
        // If no target columns has been specified then take the minimum requested
        ColumnType[] types = getColumnTypes();
        if (types == null || types.length == 0) {

            if (minColumns > 0 && minColumns < metatada.getNumberOfColumns()) {
                types = new ColumnType[minColumns];
            }
            else {
                types = new ColumnType[metatada.getNumberOfColumns()];
            }

            for (int i = 0; i < types.length; i++) {
                types[i] = metatada.getColumnType(i);
            }
        }
        // Add the columns to the lookup
        for (int i=startIndex; i<types.length; i++) {
            ColumnType targetType = types[i];

            // Do the best to get a new (not already added) column for the targetType.
            int idx = getTargetColumn(metatada, targetType, exclude);

            // Otherwise, get the first column available.
            if (idx == -1) {
                idx = getTargetColumn(metatada, exclude);
            }

            String columnId = metatada.getColumnId(idx);
            ColumnType columnType = metatada.getColumnType(idx);
            exclude.add(idx);
            DataSetLookup currentLookup = builder.buildLookup();
            String uniqueColumnId = buildUniqueColumnId(currentLookup, columnId);
            String uniqueCountId = buildUniqueColumnId(currentLookup, "#items");

            if (ColumnType.NUMBER.equals(targetType)) {
                if (groupRequired || functionRequired) {
                    if (ColumnType.NUMBER.equals(columnType)) {
                        builder.column(columnId, AggregateFunctionType.SUM, uniqueColumnId);
                    } else {
                        builder.column(AggregateFunctionType.COUNT, uniqueCountId);
                    }
                } else {
                    builder.column(columnId, uniqueColumnId);
                }
            } else {
                if (functionRequired) {
                    builder.column(AggregateFunctionType.COUNT, uniqueCountId);
                } else {
                    builder.column(columnId, uniqueColumnId);
                }
            }
        }
        return builder.buildLookup();
    }

}