### Question:
ProgressEventHandler implements Consumer<ProgressEvent> { @Override public void accept(ProgressEvent progressEvent) { Allocation allocation = progressEvent.getAllocation(); long progressUnits = progressEvent.getUnits(); double allocationFraction = allocation.getFractionOfRoot(); if (progressUnits != 0) { progress.add(progressUnits * allocationFraction); } if (completionTracker.updateProgress(allocation, progressUnits)) { updateNotifier.accept(new Update(progress.sum(), completionTracker.getUnfinishedLeafTasks())); } } ProgressEventHandler(Consumer<Update> updateNotifier); @Override void accept(ProgressEvent progressEvent);  }### Answer:
@Test public void testAccept() throws ExecutionException, InterruptedException, IOException { try (MultithreadedExecutor multithreadedExecutor = new MultithreadedExecutor()) { DoubleAccumulator maxProgress = new DoubleAccumulator(Double::max, 0); ProgressEventHandler progressEventHandler = new ProgressEventHandler(update -> maxProgress.accumulate(update.getProgress())); EventHandlers eventHandlers = EventHandlers.builder().add(ProgressEvent.class, progressEventHandler).build(); multithreadedExecutor.invoke( () -> { eventHandlers.dispatch(new ProgressEvent(AllocationTree.root, 0L)); return null; }); multithreadedExecutor.invoke( () -> { eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1, 0L)); return null; }); multithreadedExecutor.invoke( () -> { eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1Child, 0L)); return null; }); Assert.assertEquals(0.0, maxProgress.get(), DOUBLE_ERROR_MARGIN); List<Callable<Void>> callables = new ArrayList<>(150); callables.addAll( Collections.nCopies( 50, () -> { eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1Child, 1L)); return null; })); callables.addAll( Collections.nCopies( 100, () -> { eventHandlers.dispatch(new ProgressEvent(AllocationTree.child2, 1L)); return null; })); multithreadedExecutor.invokeAll(callables); Assert.assertEquals( 1.0 / 2 / 100 * 50 + 1.0 / 2 / 200 * 100, maxProgress.get(), DOUBLE_ERROR_MARGIN); multithreadedExecutor.invokeAll( Collections.nCopies( 100, () -> { eventHandlers.dispatch(new ProgressEvent(AllocationTree.child1, 0L)); return null; })); Assert.assertEquals( 1.0 / 2 / 100 * 50 + 1.0 / 2 / 200 * 100, maxProgress.get(), DOUBLE_ERROR_MARGIN); multithreadedExecutor.invokeAll(callables); Assert.assertEquals(1.0, maxProgress.get(), DOUBLE_ERROR_MARGIN); } }