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(); }