protected Map<PortletExecutionAggregationDiscriminator, SortedSet<PortletExecutionAggregation>>
      createColumnDiscriminatorMap(PortletExecutionReportForm form) {
    // Collections used to track the queried groups and the results
    final Map<PortletExecutionAggregationDiscriminator, SortedSet<PortletExecutionAggregation>>
        groupedAggregations =
            new TreeMap<
                PortletExecutionAggregationDiscriminator, SortedSet<PortletExecutionAggregation>>(
                PortletExecutionAggregationDiscriminatorImpl.Comparator.INSTANCE);

    // Get concrete group mapping objects that are being queried for
    List<Long> groups = form.getGroups();
    Set<String> portletFNames = form.getPortlets();
    Set<String> executionTypes = form.getExecutionTypeNames();
    for (final Long queryGroupId : groups) {
      AggregatedGroupMapping groupMapping =
          this.aggregatedGroupLookupDao.getGroupMapping(queryGroupId);
      for (final String portletFName : portletFNames) {
        AggregatedPortletMapping tabMapping =
            this.aggregatedPortletLookupDao.getMappedPortletForFname(portletFName);
        for (String executionType : executionTypes) {
          final PortletExecutionAggregationDiscriminator mapping =
              new PortletExecutionAggregationDiscriminatorImpl(
                  groupMapping, tabMapping, ExecutionType.valueOf(executionType));
          // Create the set the aggregations for this report column will be stored in, sorted
          // chronologically
          final SortedSet<PortletExecutionAggregation> aggregations =
              new TreeSet<PortletExecutionAggregation>(BaseAggregationDateTimeComparator.INSTANCE);

          // Map the group to the set
          groupedAggregations.put(mapping, aggregations);
        }
      }
    }

    return groupedAggregations;
  }
 @ModelAttribute("executionTypes")
 public ExecutionType[] getExecutionTypes() {
   return ExecutionType.values();
 }