#pragma warning disable xUnit1013 // Public method should be marked as test
        public void RunBasedOnSettings([NotNull] RunningConfig settings, [NotNull] Logger logger)
#pragma warning restore xUnit1013 // Public method should be marked as test
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();
            var container = CreateBuilderContainer(_output, logger, settings);
            Dictionary <string, double> secondsPerStep = new Dictionary <string, double>();

            using (var scope = container.BeginLifetimeScope()) {
                var allItems = container.Resolve <IEnumerable <IBasicRunner> >().ToList();
                logger.Info("#The following scenarios are going to be processed.", Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                if (settings.Slices == null)
                {
                    throw new FlaException("slices was not initalized");
                }

                foreach (ScenarioSliceParameters scenarioSliceParameters in settings.Slices)
                {
                    logger.Info("\t" + scenarioSliceParameters, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                }

                logger.Info("#The following stages are going to be processed.", Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                foreach (Stage stage in settings.StagesToExecute)
                {
                    logger.Info("\t" + stage, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                }

                for (int stageIdx = 0; stageIdx < settings.StagesToExecute.Count; stageIdx++)
                {
                    Stage currentStage = settings.StagesToExecute[stageIdx];
                    logger.Info("## Starting Stage " + currentStage, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                    var steps = allItems.Where(x => x.MyStage == currentStage).ToList();
                    steps.Sort((x, y) => x.SequenceNumber.CompareTo(y.SequenceNumber));
                    logger.Info("### The following steps in this stage are going to be processed.",
                                Stage.Preparation,
                                nameof(MainBurgdorfStatisticsCreator));
                    foreach (var step in steps)
                    {
                        logger.Info("\t" + step.SequenceNumber + " - " + step.Name, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                    }

                    CheckAndValidateSteps(steps, logger, currentStage, out var stepType);

                    switch (stepType)
                    {
                    case Steptype.Global: {
                        ProcessGlobalSteps(steps, secondsPerStep);
                        logger.SaveToDatabase(Constants.PresentSlice);
                        break;
                    }

                    case Steptype.SliceProcessors: {
                        ProcessSliceSteps(steps, logger, settings, secondsPerStep, currentStage);
                        break;
                    }

                    case Steptype.Scenario: {
                        List <RunnableForScenarioWithBenchmark> scenarioSteps = steps.Select(x => (RunnableForScenarioWithBenchmark)x).ToList();
                        var scenariosToProcess = settings.Slices.Select(x => x.DstScenario).Distinct().ToList();

                        if (scenariosToProcess.Contains(Scenario.Present()) && currentStage == Stage.ScenarioCreation)
                        {
                            scenariosToProcess.Remove(Scenario.Present());
                        }

                        foreach (var scenario in scenariosToProcess)
                        {
                            logger.Info("Processing " + scenario, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                            var slicesWithScenario = settings.Slices.Where(x => x.DstScenario == scenario).ToList();
                            foreach (var step in scenarioSteps)
                            {
                                Stopwatch stopwatch = Stopwatch.StartNew();
                                step.Run(settings.Slices.ToList());
                                logger.SaveToDatabase(slicesWithScenario.Last());
                                var stepname = currentStage + "-" + step.Name;
                                stopwatch.Stop();
                                if (!secondsPerStep.ContainsKey(stepname))
                                {
                                    secondsPerStep.Add(stepname, 0);
                                }

                                secondsPerStep[stepname] += stopwatch.ElapsedMilliseconds / 1000.0;
                            }

                            logger.Info("Finished processing " + scenario, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                        }
                    }

                    break;

                    case Steptype.AllScenarios: {
                        List <RunnableForAllScenarioWithBenchmark> crossScenarioSteps =
                            steps.Select(x => (RunnableForAllScenarioWithBenchmark)x).ToList();
                        AnalysisRepository analysisRepository = new AnalysisRepository(settings);
                        foreach (var step in crossScenarioSteps)
                        {
                            Stopwatch stopwatch = Stopwatch.StartNew();
                            step.Run(settings.Slices.ToList(), analysisRepository);
                            logger.SaveToDatabase(Constants.PresentSlice);
                            var stepname = currentStage + "-" + step.Name;
                            stopwatch.Stop();
                            if (!secondsPerStep.ContainsKey(stepname))
                            {
                                secondsPerStep.Add(stepname, 0);
                            }

                            secondsPerStep[stepname] += stopwatch.ElapsedMilliseconds / 1000.0;
                        }
                    }

                    break;

                    default:
                        throw new Exception("unknown steptype");
                    }

                    logger.Info("Finished Stage " + currentStage + ", waiting for the charts to finish.",
                                Stage.Preparation,
                                nameof(MainBurgdorfStatisticsCreator));
                    var plotMaker = scope.Resolve <PlotMaker>();
                    plotMaker.Finish();
                    logger.Info("Finished Stage " + currentStage, Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                }

                logger.SaveToDatabase(Constants.PresentSlice);
                if (settings.MakeStageEntries)
                {
                    PngSvgConverter psc = new PngSvgConverter(logger, Stage.Preparation);
                    psc.ConvertAllSVG(settings);
                }

                sw.Stop();
                logger.Info("Finished everything after " + sw.Elapsed.TotalMinutes + " minutes",
                            Stage.Preparation,
                            nameof(MainBurgdorfStatisticsCreator));
                foreach (var pair in secondsPerStep)
                {
                    logger.Info(pair.Key + "\t" + pair.Value.ToString("F2"), Stage.Preparation, "Main");
                }

                logger.Info("Listing open threads before closing the logger", Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                ThreadProvider.Get().DisplayRunningThreads();
                logger.Info("Listing open threads after closing the logger", Stage.Preparation, nameof(MainBurgdorfStatisticsCreator));
                logger.FinishSavingEverything();
                ThreadProvider.Get().DisplayRunningThreads();
            }

            container.Dispose();
        }