@SuppressWarnings("unused") // Used in commented out debugging code
    private List<TaskProgress> buildDummyTaskDataForTesting(final Predicate<TaskProgress> fuzzyMatchPredicate) {

        final AtomicInteger id = new AtomicInteger(10_000);
        final AtomicInteger timeDelta = new AtomicInteger(0);
        final List<String> taskNames = List.of(
                "Red",
                "Blue",
                "Green",
                "Yellow",
                "Brown",
                "Pink",
                "Orange");

        final List<String> users = List.of(
                "joebloggs",
                "johndoe");

        final Instant now = Instant.now();

        final List<TaskProgress> colourTasks = taskNames.stream()
                .flatMap(taskname -> {
                    // Need to make sure task IDs are unique over the cluster
                    TaskId grandparentTaskId = new TaskId(thisNodeName + "-" + id.incrementAndGet(), null);
                    TaskId parentTaskId = new TaskId(thisNodeName + "-" + id.incrementAndGet(),
                            grandparentTaskId);
                    TaskId childTaskId = new TaskId(thisNodeName + "-" + id.incrementAndGet(),
                            parentTaskId);
                    return Stream.of(
                            Tuple.of(taskname + "-grandparent", grandparentTaskId),
                            Tuple.of(taskname + "-parent", parentTaskId),
                            Tuple.of(taskname + "-child", childTaskId));
                })
                .map(tuple2 -> {
                    String taskName = tuple2._1();
                    TaskId taskId = tuple2._2();
                    String taskInfo = "taskInfo-" + taskName;
                    // Make a long taskInfo so we can test cell wrapping
                    for (int i = 0; i < 3; i++) {
                        taskInfo = taskInfo + " " + taskInfo;
                    }
                    final TaskProgress taskProgress = new TaskProgress();
                    taskProgress.setId(taskId);
                    taskProgress.setTaskName(taskName);
                    taskProgress.setUserRef(UserRef.builder().subjectId(users.get(id.get() % 2)).build());
                    taskProgress.setThreadName("thread-" + (ThreadLocalRandom.current().nextInt(20) + 1));
                    taskProgress.setTaskInfo(taskInfo);
                    taskProgress.setSubmitTimeMs(now.minus(timeDelta.incrementAndGet(), ChronoUnit.DAYS)
                            .toEpochMilli());
                    taskProgress.setTimeNowMs(now.toEpochMilli());
                    taskProgress.setNodeName(thisNodeName);

                    taskProgress.setFilterMatchState(
                            FilterMatchState.fromBoolean(fuzzyMatchPredicate.test(taskProgress)));
                    return taskProgress;

                })
                .toList();

        // If a parent task has died for some reason that leaves an orphaned task so the UI
        // needs to be able to cope with those too.
        final TaskId missingParentTask = new TaskId(thisNodeName + "-" + id.incrementAndGet(), null);
        final TaskProgress orphanedTask = new TaskProgress(
                new TaskId(thisNodeName + "-" + id.incrementAndGet(), missingParentTask),
                "Orphaned-task",
                "taskInfo-Orphaned-task",
                UserRef.builder().subjectId("janedoe").build(),
                "threadY",
                thisNodeName,
                now.minus(timeDelta.get(), ChronoUnit.DAYS).toEpochMilli(),
                now.toEpochMilli(),
                null,
                null);

        return Stream.concat(colourTasks.stream(), Stream.of(orphanedTask))
                .toList();
    }
This code is here to help UI testing in dev when you have no tasks to look at in the UI.
It produces a load of made up tasks
Used in {@link TaskManagerImpl#doFind(FindTaskProgressCriteria)}
stroom-task/stroom-task-impl/src/main/java/stroom/task/impl/TaskManagerImpl.java