class ExperimentManager {

    Stream<Experiment> createSpecificExperiments (Platform platform, ExperimentSuite.ExperimentCriteria experimentCriteria, int minimumNumberOfSurvivors) {
        String containerAggregationIdentifier = experimentCriteria.getContainerIdentifier();
        List<String> experimentMethods = experimentCriteria.getExperimentMethods();
        List<String> specificContainerTargets = experimentCriteria.getSpecificContainerTargets();
        log.debug("Creating experiments of type {} against {} with identifier {}", experimentMethods, platform, containerAggregationIdentifier);
        List<Container> potentialContainers = new ArrayList<>(platform.getRosterByAggregationId(containerAggregationIdentifier));
        if (potentialContainers.size() - minimumNumberOfSurvivors < experimentMethods.size()) {
            throw new ChaosException(NOT_ENOUGH_CONTAINERS_FOR_PLANNED_EXPERIMENT);
        }
        Stream<Experiment> experimentStream1 = IntStream.range(0, specificContainerTargets.size()).mapToObj(i -> {
            String experimentMethod = experimentMethods.get(i);
            Experiment experiment = createSingleExperiment(platform, specificContainerTargets.get(i), experimentMethod);
            Optional.ofNullable(experiment).map(Experiment::getContainer).ifPresent(potentialContainers::remove);
            return experiment;
        });
        List<String> leftoverExperimentMethods = experimentMethods.subList(specificContainerTargets.size(), experimentMethods
                .size());
        Collections.shuffle(potentialContainers);
        Stream<Experiment> experimentStream2 = IntStream.range(0, leftoverExperimentMethods.size()).mapToObj(i -> {
            Container container = potentialContainers.get(i);
            String experimentMethod = leftoverExperimentMethods.get(i);
            return container.createExperiment(experimentMethod);
        });
        return Stream.concat(experimentStream1, experimentStream2);
    }

}