class CollectDownscaleCandidatesHandler implements EventHandler<CollectDownscaleCandidatesRequest> {

    @Override
    public void accept(Event<CollectDownscaleCandidatesRequest> event) {
        CollectDownscaleCandidatesRequest request = event.getData();
        CollectDownscaleCandidatesResult result;
        try {
            result = transactionService.required(() -> {
                try {
                    Stack stack = stackService.getByIdWithListsInTransaction(request.getResourceId());
                    int defaultRootVolumeSize = defaultRootVolumeSizeProvider.getForPlatform(stack.cloudPlatform());
                    Set<Long> privateIds = request.getPrivateIds();
                    if (noSelectedInstancesForDownscale(privateIds)) {
                        privateIds = collectCandidates(request, stack, defaultRootVolumeSize);
                    } else {
                        List<InstanceMetaData> removableInstances =
                                stackService.getInstanceMetaDataForPrivateIdsWithoutTerminatedInstances(stack.getInstanceMetaDataAsList(), privateIds);
                        List<InstanceMetaData> removableAndNotDeletedInstances = removableInstances.stream()
                                .filter(instanceMetaData -> !instanceMetaData.isTerminated() && !instanceMetaData.isDeletedOnProvider())
                                .collect(Collectors.toList());
                        if (!request.getDetails().isForced()) {
                            clusterApiConnectors.getConnector(stack).clusterDecomissionService()
                                    .verifyNodesAreRemovable(stack, removableAndNotDeletedInstances);
                        }
                    }
                    return new CollectDownscaleCandidatesResult(request, privateIds);
                } catch (Exception e) {
                    return new CollectDownscaleCandidatesResult(e.getMessage(), e, request);
                }
            });
        } catch (TransactionExecutionException e) {
            throw e.getCause();
        }
        eventBus.notify(result.selector(), new Event<>(event.getHeaders(), result));
    }

}