class ReservationUsageCalculator {

    public Map<String, ReservationUsage> buildUsage() {
        Map<String, ResourceAccumulator> accumulatorMap = new HashMap<>();

        List<Pair<Job, List<Task>>> jobsAndTasks = jobOperations.getJobsAndTasks();

        Set<String> capacityGroupNames = capacityManagementService.getApplicationSLAs().stream()
                .map(ApplicationSLA::getAppName)
                .collect(Collectors.toSet());

        for (Pair<Job, List<Task>> jobAndTasks : jobsAndTasks) {
            Job job = jobAndTasks.getLeft();

            String capacityGroup = capacityGroupNames.contains(job.getJobDescriptor().getCapacityGroup())
                    ? job.getJobDescriptor().getCapacityGroup()
                    : ApplicationSlaManagementService.DEFAULT_APPLICATION;

            ResourceAccumulator accumulator = accumulatorMap.computeIfAbsent(
                    capacityGroup,
                    cp -> new ResourceAccumulator()
            );
            processJob(accumulator, jobAndTasks);
        }

        Map<String, ReservationUsage> result = new HashMap<>();
        accumulatorMap.forEach((capacityGroup, accumulator) -> result.put(capacityGroup, accumulator.toReservationUsage()));

        capacityManagementService.getApplicationSLAs().forEach(capacityGroup -> {
            if (!result.containsKey(capacityGroup.getAppName())) {
                result.put(capacityGroup.getAppName(), ReservationUsage.none());
            }
        });

        return result;
    }

    @Inject public  ReservationUsageCalculator(ReadOnlyJobOperations jobOperations,
                                      ApplicationSlaManagementService capacityManagementService);

}