@Override
    protected Map<ApplicationId, String> applicationsNeedingMaintenance() {
        if (deployer().bootstrapping()) return Map.of();

        return nodesNeedingMaintenance().stream()
                                        .map(node -> node.allocation().get().owner())
                                        .distinct()
                                        .filter(this::shouldMaintain)
                                        .filter(this::canDeployNow)
                                        .collect(toMap(applicationId -> applicationId, applicationId -> "current deployment being too old"));
    }
@Test(timeout = 60_000)
    public void queues_all_eligible_applications_for_deployment() throws Exception {
        fixture.activate();

        // Exhaust initial wait period and set bootstrapping to be done
        clock.advance(Duration.ofMinutes(30).plus(Duration.ofSeconds(1)));
        fixture.setBootstrapping(false);

        // Lock deployer to simulate slow deployments
        fixture.deployer.lock().lockInterruptibly();

        try {
            // Queues all eligible applications
            assertEquals(2, fixture.maintainer.applicationsNeedingMaintenance().size());
            fixture.runApplicationMaintainer(false);
            assertEquals(2, fixture.maintainer.pendingDeployments());

            // Enough time passes to make applications eligible for another periodic deployment
            clock.advance(Duration.ofMinutes(30).plus(Duration.ofSeconds(1)));
            fixture.runApplicationMaintainer(false);

            // Deployments are not re-queued as previous deployments are still pending
            assertEquals(2, fixture.maintainer.pendingDeployments());

            // Slow deployments complete
            fixture.deployer.lock().unlock();
            fixture.runApplicationMaintainer();
            Instant deployTime = clock.instant();
            assertEquals(deployTime, fixture.deployer.deployTime(fixture.app1).get());
            assertEquals(deployTime, fixture.deployer.deployTime(fixture.app2).get());

            // Too soon: Already deployed recently
            clock.advance(Duration.ofMinutes(5));
            assertEquals(0, fixture.maintainer.applicationsNeedingMaintenance().size());
        } finally {
            if (fixture.deployer.lock().isHeldByCurrentThread()) {
                fixture.deployer.lock().unlock();
            }
        }
    }