@SuppressWarnings({"unchecked"})
    @Test
    void testAsyncDataProcessingOfFederatedResult() throws InterruptedException, ExecutionException, TimeoutException {
        // Set up
        // Source 1 (async with completion chain)
        FutureDataSource futureSource1 = new FutureDataSource();
        Chain<Processor> asyncChainSource1 = new Chain<Processor>(new DataCounter("source1"));
        Chain<Processor> chainSource1 = new Chain<>(new AsyncDataProcessingInitiator(asyncChainSource1), futureSource1);
        // Source 2 (async source)
        FutureDataSource futureSource2 = new FutureDataSource();
        Chain<Processor> chainSource2 = new Chain<Processor>(futureSource2);
        // Source 3 (sync source)
        Chain<Processor> chainSource3 = new Chain<Processor>(new DataSource());
        // Main chain federating to the above - not waiting for source 1 and 2 but invoking asyncMain when both are complete
        Chain<Processor> asyncMain = new Chain<Processor>(new DataCounter("main"));
        Chain<Processor> main = new Chain<>(new AsyncDataProcessingInitiator(asyncMain), new Federator(chainSource1, chainSource2, chainSource3));

        // Execute
        Request request = new Request();
        Response response = Execution.createRoot(main, 0, Execution.Environment.createEmpty()).process(request);

        // Verify the result prior to completion of delayed data
        assertEquals(3, response.data().asList().size(), "We have the sync data plus placeholders for the async lists");
        DataList source1Data = ((DataList) response.data().get(0));
        DataList source2Data = ((DataList) response.data().get(1));
        DataList source3Data = ((DataList) response.data().get(2));

        assertEquals(0, source1Data.asList().size(), "No data yet");
        assertEquals(0, source2Data.asList().size(), "No data yet");
        assertEquals(3, source3Data.asList().size());

        // complete async data in source1
        futureSource1.incomingData.get(0).addLast(new StringData(request, "source1Data"));
        assertEquals(0, source1Data.asList().size(), "Not visible yet");
        source1Data.completeFuture().get(1000, TimeUnit.MILLISECONDS);
        assertEquals(2, source1Data.asList().size());
        assertEquals("source1Data", source1Data.get(0).toString());
        assertEquals("[source1] Data count: 1", source1Data.get(1).toString(), "Completion listener chain on this has run");

        // source2 & main completion
        assertEquals(3, response.data().asList().size(), "Main completion listener has not run");
        futureSource2.incomingData.get(0).addLast(new StringData(request, "source2Data"));
        assertEquals(3, response.data().asList().size(), "Main completion listener has not run");

        Response.recursiveFuture(response.data()).get();
        assertEquals(4, response.data().asList().size(), "Main completion listener has run");
        assertEquals("[main] Data count: " + (2 + 0 + 3), response.data().get(3).toString(), "The main data counter saw all sync data, but not source2 data as it executes after this");
    }
Register a chain which federates over three sources, two of which are future.
When the first of the futures are done one additional chain is to be run.
When both are done another chain is to be run.
container-core/src/test/java/com/yahoo/processing/execution/test/FutureDataTestCase.java