private DisplayData getDisplayData(
      FetchTimereportContext reportContext, boolean changedSinceLastRender) {

    if (changedSinceLastRender) {
      LOGGER.debug("Refreshing display data");
      DisplayData displayData = new DisplayData();

      WorklogReport result = reportContext.getResult().get();
      ImmutableList<TaskWithWorklogs> originalTasks = result.getTasks();

      // create a copy of the original task list
      // and pass it on to the getFilteredList method
      // which then may freely modify the list and its items
      List<TaskWithWorklogs> deepCopiedList = Lists.newArrayList();
      originalTasks.forEach(
          taskWithWorklogs -> deepCopiedList.add(taskWithWorklogs.createDeepCopy()));
      List<TaskWithWorklogs> filteredList = getFilteredList(deepCopiedList);

      // render the treetabledata
      if (reportContext.getGroupByCategory().isPresent()) {
        // grouping present
        processWithGrouping(filteredList, displayData);
      } else {
        // no grouping
        processWithoutGrouping(filteredList, displayData);
      }

      // add grandtotal column
      DisplayRow grandTotal = new DisplayRow();
      grandTotal.setIsGrandTotalSummary(true);
      displayData.addRow(new TreeItem<>(grandTotal));

      filteredList
          .stream()
          .map(TaskWithWorklogs::getWorklogItemList)
          .flatMap(Collection::stream)
          .forEach(
              worklogItem -> {
                LocalDate date = worklogItem.getDate();

                DisplayDayEntry workdayEntry =
                    grandTotal
                        .getWorkdayEntry(date)
                        .orElseGet(
                            () -> {
                              DisplayDayEntry displayDayEntry = new DisplayDayEntry();
                              displayDayEntry.setDate(date);

                              grandTotal.addDisplayDayEntry(displayDayEntry);

                              return displayDayEntry;
                            });

                workdayEntry.getSpentTime().addAndGet(worklogItem.getDurationInMinutes());
              });

      // call statistics update
      updateStatisticsData(filteredList);

      resultItemsToDisplay = Optional.of(displayData);
    }

    return resultItemsToDisplay.get();
  }