@Override
    public void apply(IntentOperationContext<FlowObjectiveIntent> intentOperationContext) {
        Objects.requireNonNull(intentOperationContext);
        Optional<IntentData> toUninstall = intentOperationContext.toUninstall();
        Optional<IntentData> toInstall = intentOperationContext.toInstall();

        List<FlowObjectiveIntent> uninstallIntents = intentOperationContext.intentsToUninstall();
        List<FlowObjectiveIntent> installIntents = intentOperationContext.intentsToInstall();

        if (!toInstall.isPresent() && !toUninstall.isPresent()) {
            intentInstallCoordinator.intentInstallSuccess(intentOperationContext);
            return;
        }

        if (toUninstall.isPresent()) {
            IntentData intentData = toUninstall.get();
            trackerService.removeTrackedResources(intentData.key(), intentData.intent().resources());
            uninstallIntents.forEach(installable ->
                                             trackerService.removeTrackedResources(intentData.intent().key(),
                                                                                   installable.resources()));
        }

        if (toInstall.isPresent()) {
            IntentData intentData = toInstall.get();
            trackerService.addTrackedResources(intentData.key(), intentData.intent().resources());
            installIntents.forEach(installable ->
                                           trackerService.addTrackedResources(intentData.key(),
                                                                              installable.resources()));
        }

        FlowObjectiveIntentInstallationContext intentInstallationContext =
                new FlowObjectiveIntentInstallationContext(intentOperationContext);

        uninstallIntents.stream()
                .map(intent -> buildObjectiveContexts(intent, REMOVE))
                .flatMap(Collection::stream)
                .forEach(context -> {
                    context.intentInstallationContext(intentInstallationContext);
                    intentInstallationContext.addContext(context);
                    intentInstallationContext.addPendingContext(context);
                });

        installIntents.stream()
                .map(intent -> buildObjectiveContexts(intent, ADD))
                .flatMap(Collection::stream)
                .forEach(context -> {
                    context.intentInstallationContext(intentInstallationContext);
                    intentInstallationContext.addContext(context);
                    intentInstallationContext.addNextPendingContext(context);
                });

        intentInstallationContext.apply();
    }
@Test
    public void testUninstallAndInstallIntent() {
        List<Intent> intentsToUninstall = createFlowObjectiveIntents();
        List<Intent> intentsToInstall = createAnotherFlowObjectiveIntents();
        IntentData toInstall = new IntentData(createP2PIntent(),
                                              IntentState.INSTALLING,
                                              new WallClockTimestamp());
        toInstall = IntentData.compiled(toInstall, intentsToInstall);
        IntentData toUninstall = new IntentData(createP2PIntent(),
                                                IntentState.INSTALLED,
                                                new WallClockTimestamp());
        toUninstall = IntentData.compiled(toUninstall, intentsToUninstall);

        IntentOperationContext<FlowObjectiveIntent> operationContext;
        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);

        installer.apply(operationContext);

        IntentOperationContext successContext = intentInstallCoordinator.successContext;
        assertEquals(successContext, operationContext);
    }