diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4a412569fbd477f02a0b67b83e8814ab98b34031..01630912c52ccc728870d72c33a8f02cdf7c2c7f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -242,6 +242,7 @@ build-theodolite-native:
   script:
     - gu install native-image # TODO move to image
     - ./gradlew --build-cache assemble -Dquarkus.package.type=native
+  when: manual
   artifacts:
     paths:
       - "theodolite-quarkus/build/*-runner"
@@ -252,7 +253,7 @@ test-theodolite:
   extends: .theodolite
   needs:
     - build-theodolite-jvm
-    - build-theodolite-native
+    #- build-theodolite-native
   script: ./gradlew test --stacktrace
 
 # Disabled for now
@@ -279,12 +280,13 @@ deploy-theodolite:
     - .theodolite
     - .dind
   needs:
-    - build-theodolite-native
+    #- build-theodolite-native
+    - build-theodolite-jvm
     - test-theodolite
   script:
     - DOCKER_TAG_NAME=$(echo $CI_COMMIT_REF_SLUG- | sed 's/^master-$//')
-    - docker build -f src/main/docker/Dockerfile.native -t theodolite .
-    #- docker build -f src/main/docker/Dockerfile.jvm -t theodolite .
+    #- docker build -f src/main/docker/Dockerfile.native -t theodolite .
+    - docker build -f src/main/docker/Dockerfile.jvm -t theodolite .
     - "[ ! $CI_COMMIT_TAG ] && docker tag theodolite $CR_HOST/$CR_ORG/theodolite:${DOCKER_TAG_NAME}latest"
     - "[ ! $CI_COMMIT_TAG ] && docker tag theodolite $CR_HOST/$CR_ORG/theodolite:$DOCKER_TAG_NAME$CI_COMMIT_SHORT_SHA"
     - "[ $CI_COMMIT_TAG ] && docker tag theodolite $CR_HOST/$CR_ORG/theodolite:$CI_COMMIT_TAG"
@@ -309,6 +311,7 @@ deploy-slo-checker-lag-trend:
   stage: deploy
   extends:
     - .dind
+  needs: []
   script:
     - DOCKER_TAG_NAME=$(echo $CI_COMMIT_REF_SLUG- | sed 's/^master-$//')
     - docker build --pull -t theodolite-slo-checker-lag-trend slope-evaluator
@@ -335,6 +338,7 @@ deploy-random-scheduler:
   stage: deploy
   extends:
     - .dind
+  needs: []
   script:
     - DOCKER_TAG_NAME=$(echo $CI_COMMIT_REF_SLUG- | sed 's/^master-$//')
     - docker build --pull -t theodolite-random-scheduler execution/infrastructure/random-scheduler
diff --git a/slope-evaluator/README.md b/slope-evaluator/README.md
index 25c02b42e6a6eb4611972febf935403b8b8703c8..5929fb157a7c783bd37497885a5e3bc373b84aa0 100644
--- a/slope-evaluator/README.md
+++ b/slope-evaluator/README.md
@@ -17,10 +17,43 @@ docker build . -t theodolite-evaluator
 Run the Docker image:
 
 ```sh
- docker run -p 80:80 theodolite-evaluator
+docker run -p 80:80 theodolite-evaluator
 ```
 
 ## Configuration
 
 You can set the `HOST` and the `PORT` (and a lot of more parameters) via environment variables. Default is `0.0.0.0:80`.
-For more information see [here](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#advanced-usage).
+For more information see the [Gunicorn/FastAPI Docker docs](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#advanced-usage).
+
+## API Documentation
+
+The running webserver provides a REST API with the following route:
+
+* /evaluate-slope
+    * Method: POST
+    * Body:
+        * total_lag
+        * threshold
+        * warmup
+
+The body of the request must be a JSON string that satisfies the following conditions:
+
+* **total_lag**: This property is based on the [Range Vector type](https://www.prometheus.io/docs/prometheus/latest/querying/api/#range-vectors) from Prometheus and must have the following JSON structure:
+    ```
+        {
+            "metric": {
+                "group": "<label_value>"
+            },
+            "values": [
+                [
+                    <unix_timestamp>,
+                    "<sample_value>"
+                ]
+            ]
+        }
+    ```
+    * The `<label_value>` provided in "metric.group" must be equal to the id of the Kafka consumer group.
+    * The `<unix_timestamp>` provided as the first element of each element in the "values" array must be the timestamp of the measurement value in seconds (with optional decimal precision)
+    * The `<sample_value>` must be the measurement value as string.
+* **threshold**: Must be an unsigned integer that specifies the threshold for the SLO evaluation. The SLO is considered fulfilled, if the result value is below the threshold. If the result value is equal or above the threshold, the SLO is considered not fulfilled.
+* **warmup**: Specifieds the warmup time in seconds that are ignored for evaluating the SLO.
\ No newline at end of file
diff --git a/slope-evaluator/app/main.py b/slope-evaluator/app/main.py
index 83709c0f71563d9bd1c29c5f064645144163ea72..5995a1175f781c4eb51ab3d3083a665fbc02d6fd 100644
--- a/slope-evaluator/app/main.py
+++ b/slope-evaluator/app/main.py
@@ -18,7 +18,7 @@ if os.getenv('LOG_LEVEL') == 'INFO':
 elif os.getenv('LOG_LEVEL') == 'WARNING':
     logger.setLevel(logging.WARNING)
 elif os.getenv('LOG_LEVEL') == 'DEBUG':
-    logger.setLevel((logging.DEBUG))
+    logger.setLevel(logging.DEBUG)
 
 def execute(results, threshold, warmup):
     d = []
@@ -30,18 +30,18 @@ def execute(results, threshold, warmup):
 
     df = pd.DataFrame(d)
 
-    logger.info(df)
+    logger.info("Calculating trend slope with warmup of %s seconds for data frame:\n %s", warmup, df)
     try:
         trend_slope = trend_slope_computer.compute(df, warmup)
     except Exception as e:
-        err_msg = 'Computing trend slope failed'
+        err_msg = 'Computing trend slope failed.'
         logger.exception(err_msg)
-        logger.error('Mark this subexperiment as not successful and continue benchmark')
+        logger.error('Mark this subexperiment as not successful and continue benchmark.')
         return False
 
-    logger.info("Trend Slope: %s", trend_slope)
-
-    return trend_slope < threshold
+    result = trend_slope < threshold
+    logger.info("Computed lag trend slope is '%s'. Result is: %s", trend_slope, result)
+    return result
 
 @app.post("/evaluate-slope",response_model=bool)
 async def evaluate_slope(request: Request):
diff --git a/slope-evaluator/app/trend_slope_computer.py b/slope-evaluator/app/trend_slope_computer.py
index c128d9f48c1e7ba20e43dfbfd6a0391eeec2b60b..51b28f2baa5110a6d64f3adc1ac9a94c6b6f3ce9 100644
--- a/slope-evaluator/app/trend_slope_computer.py
+++ b/slope-evaluator/app/trend_slope_computer.py
@@ -2,13 +2,12 @@ from sklearn.linear_model import LinearRegression
 import pandas as pd
 import os
 
-def compute(x, warmup_sec):
-    input = x
-    input['sec_start'] = input.loc[0:, 'timestamp'] - input.iloc[0]['timestamp']
-    regress = input.loc[input['sec_start'] >= warmup_sec] # Warm-Up
+def compute(data, warmup_sec):
+    data['sec_start'] = data.loc[0:, 'timestamp'] - data.iloc[0]['timestamp']
+    regress = data.loc[data['sec_start'] >= warmup_sec] # Warm-Up
 
-    X = regress.iloc[:, 2].values.reshape(-1, 1)  # values converts it into a numpy array
-    Y = regress.iloc[:, 3].values.reshape(-1, 1)  # -1 means that calculate the dimension of rows, but have 1 column
+    X = regress.iloc[:, 1].values.reshape(-1, 1)  # values converts it into a numpy array
+    Y = regress.iloc[:, 2].values.reshape(-1, 1)  # -1 means that calculate the dimension of rows, but have 1 column
     linear_regressor = LinearRegression()  # create object for the class
     linear_regressor.fit(X, Y)  # perform linear regression
     Y_pred = linear_regressor.predict(X)  # make predictions
diff --git a/theodolite-quarkus/build.gradle b/theodolite-quarkus/build.gradle
index 2f58f4c8a587a4a17cf8586e507c0079d8cb56e6..8b61bf506dd241c5b0d4e75b1357ef3fd5966135 100644
--- a/theodolite-quarkus/build.gradle
+++ b/theodolite-quarkus/build.gradle
@@ -18,16 +18,16 @@ dependencies {
     implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
     implementation 'io.quarkus:quarkus-arc'
     implementation 'io.quarkus:quarkus-resteasy'
-    testImplementation 'io.quarkus:quarkus-junit5'
-    testImplementation 'io.rest-assured:rest-assured'
     implementation 'com.google.code.gson:gson:2.8.5'
-
     implementation 'org.slf4j:slf4j-simple:1.7.29'
     implementation 'io.github.microutils:kotlin-logging:1.12.0'
     implementation 'io.fabric8:kubernetes-client:5.0.0-alpha-2'
     implementation 'io.quarkus:quarkus-kubernetes-client'
     implementation 'org.apache.kafka:kafka-clients:2.7.0'
     implementation 'khttp:khttp:1.0.0'
+
+    testImplementation 'io.quarkus:quarkus-junit5'
+    testImplementation 'io.rest-assured:rest-assured'
 }
 
 group 'theodolite'
diff --git a/theodolite-quarkus/config/example-benchmark-yaml-resource.yaml b/theodolite-quarkus/config/example-benchmark-yaml-resource.yaml
index 60eb3bb9c31e3eab3e70f916b450372d56db4968..ebc2fe9e44fe303e342cabee301cb63664867cfb 100644
--- a/theodolite-quarkus/config/example-benchmark-yaml-resource.yaml
+++ b/theodolite-quarkus/config/example-benchmark-yaml-resource.yaml
@@ -19,9 +19,13 @@ loadTypes:
         resource: "uc1-load-generator-deployment.yaml"
         container: "workload-generator"
         variableName: "NUM_SENSORS"
+      - type: "NumSensorsLoadGeneratorReplicaPatcher"
+        resource: "uc1-load-generator-deployment.yaml"
 kafkaConfig:
   bootstrapServer: "theodolite-cp-kafka:9092"
   topics:
     - name: "input"
       numPartitions: 40
-      replicationFactor: 1
\ No newline at end of file
+      replicationFactor: 1
+    - name: "theodolite-.*"
+      removeOnly: True
\ No newline at end of file
diff --git a/theodolite-quarkus/config/example-operator-benchmark.yaml b/theodolite-quarkus/config/example-operator-benchmark.yaml
index 419042fdd0b1e58fed4d402b4bb329d54602d23f..3ed5218d8a8988b130e8d549c120cbca7329ffe3 100644
--- a/theodolite-quarkus/config/example-operator-benchmark.yaml
+++ b/theodolite-quarkus/config/example-operator-benchmark.yaml
@@ -23,9 +23,13 @@ loadTypes:
         resource: "uc1-load-generator-deployment.yaml"
         container: "workload-generator"
         variableName: "NUM_SENSORS"
+      - type: "NumSensorsLoadGeneratorReplicaPatcher"
+        resource: "uc1-load-generator-deployment.yaml"
 kafkaConfig:
   bootstrapServer: "theodolite-cp-kafka:9092"
   topics:
     - name: "input"
       numPartitions: 40
-      replicationFactor: 1
\ No newline at end of file
+      replicationFactor: 1
+    - name: "theodolite-.*"
+      removeOnly: True
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
index 71b65a28fd074e4554c283ee94a8db028d652d46..bbcb8a957fb2f04ca678b231a878be0a23d46748 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
@@ -96,7 +96,7 @@ class KubernetesBenchmark : Benchmark, CustomResource(), Namespaced {
             namespace = namespace,
             resources = resources.map { r -> r.second },
             kafkaConfig = hashMapOf("bootstrap.servers" to kafkaConfig.bootstrapServer),
-            topics = kafkaConfig.getKafkaTopics(),
+            topics = kafkaConfig.topics,
             client = DefaultKubernetesClient().inNamespace(namespace)
         )
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
index 3d73dd67ddcb5363e752d9a0a65d5a8bff98b4e9..a6bf881d6ded7b0936b400a37b572c77c95bb241 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
@@ -3,9 +3,13 @@ package theodolite.benchmark
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
+import mu.KotlinLogging
 import org.apache.kafka.clients.admin.NewTopic
 import theodolite.k8s.K8sManager
 import theodolite.k8s.TopicManager
+import theodolite.util.KafkaConfig
+
+private val logger = KotlinLogging.logger {}
 
 /**
  * Organizes the deployment of benchmarks in Kubernetes.
@@ -20,12 +24,13 @@ class KubernetesBenchmarkDeployment(
     val namespace: String,
     val resources: List<KubernetesResource>,
     private val kafkaConfig: HashMap<String, Any>,
-    private val topics: Collection<NewTopic>,
+    private val topics: List<KafkaConfig.TopicWrapper>,
     private val client: NamespacedKubernetesClient
 ) : BenchmarkDeployment {
     private val kafkaController = TopicManager(this.kafkaConfig)
     private val kubernetesManager = K8sManager(client)
-    private val LABEL = "app.kubernetes.io/name=kafka-lag-exporter"
+    private val LAG_EXPORTER_POD_LABEL = "app.kubernetes.io/name=kafka-lag-exporter"
+    private val SLEEP_AFTER_TEARDOWN = 5000L
 
     /**
      * Setup a [KubernetesBenchmark] using the [TopicManager] and the [K8sManager]:
@@ -33,10 +38,10 @@ class KubernetesBenchmarkDeployment(
      *  - Deploy the needed resources.
      */
     override fun setup() {
-        kafkaController.createTopics(this.topics)
-        resources.forEach {
-            kubernetesManager.deploy(it)
-        }
+        val kafkaTopics = this.topics.filter { !it.removeOnly }
+            .map{ NewTopic(it.name, it.numPartitions, it.replicationFactor) }
+        kafkaController.createTopics(kafkaTopics)
+        resources.forEach { kubernetesManager.deploy(it) }
     }
 
     /**
@@ -46,10 +51,12 @@ class KubernetesBenchmarkDeployment(
      *  - Remove the [KubernetesResource]s.
      */
     override fun teardown() {
-        KafkaLagExporterRemover(client).remove(LABEL)
-        kafkaController.removeTopics(this.topics.map { topic -> topic.name() })
         resources.forEach {
             kubernetesManager.remove(it)
         }
+        kafkaController.removeTopics(this.topics.map { topic -> topic.name })
+        KafkaLagExporterRemover(client).remove(LAG_EXPORTER_POD_LABEL)
+        logger.info { "Teardown complete. Wait $SLEEP_AFTER_TEARDOWN ms to let everything come down." }
+        Thread.sleep(SLEEP_AFTER_TEARDOWN)
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
index 8c74c73881e6c45d48a4197338d1a6eff6845e2f..c5d691eb8f1437726bcce22500ad995bc1b6e4da 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
@@ -4,8 +4,11 @@ import mu.KotlinLogging
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.util.LoadDimension
 import theodolite.util.Resource
+import java.text.Normalizer
 import java.time.Duration
 import java.time.Instant
+import java.util.*
+import java.util.regex.Pattern
 
 private val logger = KotlinLogging.logger {}
 
@@ -46,7 +49,10 @@ class AnalysisExecutor(
                 resultsFolder += "/"
             }
 
-            CsvExporter().toCsv(name = "$resultsFolder$executionId-${load.get()}-${res.get()}-${slo.sloType}", prom = prometheusData)
+            CsvExporter().toCsv(
+                name = "${resultsFolder}exp${executionId}_${load.get()}_${res.get()}_${slo.sloType.toSlug()}",
+                prom = prometheusData
+            )
             val sloChecker = SloCheckerFactory().create(
                 sloType = slo.sloType,
                 externalSlopeURL = slo.externalSloUrl,
@@ -60,8 +66,18 @@ class AnalysisExecutor(
             )
 
         } catch (e: Exception) {
-            logger.error { "Evaluation failed for resource: ${res.get()} and load: ${load.get()} error: $e" }
+            logger.error { "Evaluation failed for resource '${res.get()}' and load '${load.get()}'. Error: $e" }
         }
         return result
     }
+
+    private val NONLATIN: Pattern = Pattern.compile("[^\\w-]")
+    private val WHITESPACE: Pattern = Pattern.compile("[\\s]")
+
+    fun String.toSlug(): String {
+        val noWhitespace: String = WHITESPACE.matcher(this).replaceAll("-")
+        val normalized: String = Normalizer.normalize(noWhitespace, Normalizer.Form.NFD)
+        val slug: String = NONLATIN.matcher(normalized).replaceAll("")
+        return slug.toLowerCase(Locale.ENGLISH)
+    }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/CsvExporter.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/CsvExporter.kt
index 68862851523934c533cf3af41f0a786ba2b5a73f..4ef78cd58085c4ff5fed1477fa08ae2e6342aa66 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/CsvExporter.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/CsvExporter.kt
@@ -24,12 +24,12 @@ class CsvExporter {
         val csvOutputFile = File("$name.csv")
 
         PrintWriter(csvOutputFile).use { pw ->
-            pw.println(listOf("name", "time", "value").joinToString())
+            pw.println(listOf("group", "timestamp", "value").joinToString())
             responseArray.forEach {
                 pw.println(it.joinToString())
             }
         }
-        logger.info { "Wrote csv file: $name to ${csvOutputFile.absolutePath}" }
+        logger.info { "Wrote CSV file: $name to ${csvOutputFile.absolutePath}." }
     }
 
     /**
@@ -41,9 +41,11 @@ class CsvExporter {
         val dataList = mutableListOf<List<String>>()
 
         if (values != null) {
-            for (x in values) {
-                val y = x as List<*>
-                dataList.add(listOf(name, "${y[0]}", "${y[1]}"))
+            for (maybeValuePair in values) {
+                val valuePair = maybeValuePair as List<*>
+                val timestamp = (valuePair[0] as Double).toLong().toString()
+                val value = valuePair[1].toString()
+                dataList.add(listOf(name, timestamp, value))
             }
         }
         return Collections.unmodifiableList(dataList)
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt
index fd901abc470a1f4b739b26e30276366e6bc69739..8eac05a815e0bc45e1abc38bcdf0352e61bd7730 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt
@@ -17,8 +17,7 @@ class ExternalSloChecker(
     private val externalSlopeURL: String,
     private val threshold: Int,
     private val warmup: Int
-) :
-    SloChecker {
+) : SloChecker {
 
     private val RETRIES = 2
     private val TIMEOUT = 60.0
@@ -38,19 +37,23 @@ class ExternalSloChecker(
      */
     override fun evaluate(start: Instant, end: Instant, fetchedData: PrometheusResponse): Boolean {
         var counter = 0
-        val data =
-            Gson().toJson(mapOf("total_lag" to fetchedData.data?.result, "threshold" to threshold, "warmup" to warmup))
+        val data = Gson().toJson(mapOf(
+            "total_lag" to fetchedData.data?.result,
+            "threshold" to threshold,
+            "warmup" to warmup))
 
         while (counter < RETRIES) {
             val result = post(externalSlopeURL, data = data, timeout = TIMEOUT)
             if (result.statusCode != 200) {
                 counter++
-                logger.error { "Could not reach external slope analysis" }
+                logger.error { "Could not reach external SLO checker" }
             } else {
-                return result.text.toBoolean()
+                val booleanResult = result.text.toBoolean()
+                logger.info { "SLO checker result is: $booleanResult" }
+                return booleanResult
             }
         }
 
-        throw ConnectException("Could not reach slope evaluation")
+        throw ConnectException("Could not reach external SLO checker")
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt
index bbfbf8c3269e442188f92a9b057fcc264acbbe78..833d7d1e16c2fbc91b58817b319a7d02af7f5b2b 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt
@@ -48,18 +48,18 @@ class MetricFetcher(private val prometheusURL: String, private val offset: Durat
             val response = get("$prometheusURL/api/v1/query_range", params = parameter, timeout = TIMEOUT)
             if (response.statusCode != 200) {
                 val message = response.jsonObject.toString()
-                logger.warn { "Could not connect to Prometheus: $message, retrying now" }
+                logger.warn { "Could not connect to Prometheus: $message. Retrying now." }
                 counter++
             } else {
                 val values = parseValues(response)
                 if (values.data?.result.isNullOrEmpty()) {
-                    logger.error { "Empty query result: $values between $start and $end for querry $query" }
+                    logger.error { "Empty query result: $values between $start and $end for query $query." }
                     throw NoSuchFieldException()
                 }
                 return parseValues(response)
             }
         }
-        throw ConnectException("No answer from Prometheus received")
+        throw ConnectException("No answer from Prometheus received.")
     }
 
     /**
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
index e179f7fa9492fc4fbe069330046dfd5d83ff8374..6d4cd9ea9b5d03dda360b2ddcefcfb9682fd8383 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
@@ -47,7 +47,7 @@ abstract class BenchmarkExecutor(
      *
      */
     fun waitAndLog() {
-        logger.info { "Execution of a new benchmark started." }
+        logger.info { "Execution of a new experiment started." }
 
         var secondsRunning = 0L
 
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
index efbfe4df41d70b1b35ea91667c8e0c85d8b58953..cd85c143e3c416f115a4d301629caf4d46b7459f 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
@@ -29,8 +29,8 @@ class BenchmarkExecutorImpl(
         try {
             benchmarkDeployment.setup()
             this.waitAndLog()
-        } catch(e: Exception) {
-            logger.error { "Error while setup experiment." }
+        } catch (e: Exception) {
+            logger.error { "Error while setting up experiment with id ${this.executionId}." }
             logger.error { "Error is: $e" }
             this.run.set(false)
         }
@@ -39,11 +39,20 @@ class BenchmarkExecutorImpl(
          * Analyse the experiment, if [run] is true, otherwise the experiment was canceled by the user.
          */
         if (this.run.get()) {
-            result =
-                AnalysisExecutor(slo = slo, executionId = executionId).analyze(load = load, res = res, executionDuration = executionDuration)
+            result = AnalysisExecutor(slo = slo, executionId = executionId).analyze(
+                load = load,
+                res = res,
+                executionDuration = executionDuration
+            )
             this.results.setResult(Pair(load, res), result)
         }
-        benchmarkDeployment.teardown()
+
+        try {
+            benchmarkDeployment.teardown()
+        } catch (e: Exception) {
+            logger.warn { "Error while tearing down the benchmark deployment." }
+            logger.debug { "Teardown failed, caused by: $e" }
+        }
 
         return result
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt
index 4518ef7957104819b26eae95cf4e6e9b35c4e995..64a40c0b11854d61900ab1fde3797e17427cac15 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt
@@ -13,13 +13,17 @@ object Main {
     @JvmStatic
     fun main(args: Array<String>) {
 
-        val mode = System.getenv("MODE") ?: "yaml-executor"
+        val mode = System.getenv("MODE") ?: "standalone"
         logger.info { "Start Theodolite with mode $mode" }
 
         when(mode) {
-           "yaml-executor" -> TheodoliteYamlExecutor().start()
+            "standalone" -> TheodoliteYamlExecutor().start()
+            "yaml-executor" -> TheodoliteYamlExecutor().start() // TODO remove (#209)
             "operator" -> TheodoliteOperator().start()
-            else ->  {logger.error { "MODE $mode not found" }; exitProcess(1)}
+            else ->  {
+                logger.error { "MODE $mode not found" }
+                exitProcess(1)
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt
index ac2165303f083be066c4398e294e456f1d268dad..c58225bf855c70a5a7057132617418a89b0816a8 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt
@@ -6,6 +6,9 @@ import io.fabric8.kubernetes.api.model.Service
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.StatefulSet
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import mu.KotlinLogging
+
+private val logger = KotlinLogging.logger {}
 
 /**
  * This class is used to deploy or remove different Kubernetes resources.
@@ -39,16 +42,32 @@ class K8sManager(private val client: NamespacedKubernetesClient) {
      */
     fun remove(resource: KubernetesResource) {
         when (resource) {
-            is Deployment ->
+            is Deployment -> {
+                val label = resource.spec.selector.matchLabels["app"]!!
                 this.client.apps().deployments().delete(resource)
+                blockUntilPodsDeleted(label)
+                logger.info { "Deployment '${resource.metadata.name}' deleted." }
+            }
             is Service ->
                 this.client.services().delete(resource)
             is ConfigMap ->
                 this.client.configMaps().delete(resource)
-            is StatefulSet ->
+            is StatefulSet -> {
+                val label = resource.spec.selector.matchLabels["app"]!!
                 this.client.apps().statefulSets().delete(resource)
+                blockUntilPodsDeleted(label)
+                logger.info { "StatefulSet '$resource.metadata.name' deleted." }
+            }
             is ServiceMonitorWrapper -> resource.delete(client)
             else -> throw IllegalArgumentException("Unknown Kubernetes resource.")
         }
     }
+
+    private fun blockUntilPodsDeleted(podLabel: String) {
+        while (!this.client.pods().withLabel(podLabel).list().items.isNullOrEmpty()) {
+            logger.info { "Wait for pods with label '$podLabel' to be deleted." }
+            Thread.sleep(1000)
+        }
+    }
+
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt
index 43dc697255ec86dd39640df7d10b89676e5d1d67..ef5715e248ae6c64df0035a94d57fea12202787e 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt
@@ -2,28 +2,50 @@ package theodolite.k8s
 
 import mu.KotlinLogging
 import org.apache.kafka.clients.admin.AdminClient
+import org.apache.kafka.clients.admin.CreateTopicsResult
 import org.apache.kafka.clients.admin.NewTopic
+import org.apache.kafka.common.errors.TopicExistsException
+import java.lang.Thread.sleep
 
 private val logger = KotlinLogging.logger {}
+private const val RETRY_TIME = 2000L
 
 /**
  * Manages the topics related tasks
- * @param kafkaConfig Kafka Configuration as HashMap
+ * @param kafkaConfig Kafka configuration as a Map
  * @constructor Creates a KafkaAdminClient
  */
-class TopicManager(private val kafkaConfig: HashMap<String, Any>) {
+class TopicManager(private val kafkaConfig: Map<String, Any>) {
 
     /**
-     * Creates topics.
-     * @param newTopics List of all Topic that should be created
+     * Create topics.
+     * @param newTopics Collection of all topic that should be created
      */
     fun createTopics(newTopics: Collection<NewTopic>) {
-        var kafkaAdmin: AdminClient = AdminClient.create(this.kafkaConfig)
-        val result = kafkaAdmin.createTopics(newTopics)
-        result.all().get()// wait for the future object
+        val kafkaAdmin: AdminClient = AdminClient.create(this.kafkaConfig)
+        lateinit var result: CreateTopicsResult
+
+        do {
+            var retryCreation = false
+            try {
+                result = kafkaAdmin.createTopics(newTopics)
+                result.all().get() // wait for the future to be completed
+            } catch (e: Exception) { // TopicExistsException
+                logger.warn(e) { "Error during topic creation." }
+                logger.debug { e } // TODO remove due to attached exception to warn log?
+                logger.info { "Remove existing topics." }
+                delete(newTopics.map { topic -> topic.name() }, kafkaAdmin)
+                logger.info { "Will retry the topic creation in ${RETRY_TIME/1000} seconds." }
+                sleep(RETRY_TIME)
+                retryCreation = true
+            }
+        } while (retryCreation)
+
         logger.info {
-            "Topics created finished with result: ${
-                result.values().map { it -> it.key + ": " + it.value.isDone }
+            "Topics creation finished with result: ${
+                result
+                    .values()
+                    .map { it -> it.key + ": " + it.value.isDone }
                     .joinToString(separator = ",")
             } "
         }
@@ -31,24 +53,60 @@ class TopicManager(private val kafkaConfig: HashMap<String, Any>) {
     }
 
     /**
-     * Removes topics.
-     * @param topics List of names with the topics to remove.
+     * Remove topics.
+     * @param topics Collection of names for the topics to remove.
      */
     fun removeTopics(topics: List<String>) {
-        var kafkaAdmin: AdminClient = AdminClient.create(this.kafkaConfig)
-        try {
-            val result = kafkaAdmin.deleteTopics(topics)
-            result.all().get() // wait for the future object
-            logger.info {
-                "Topics deletion finished with result: ${
-                    result.values().map { it -> it.key + ": " + it.value.isDone }
-                        .joinToString(separator = ",")
-                } "
+        val kafkaAdmin: AdminClient = AdminClient.create(this.kafkaConfig)
+        val currentTopics = kafkaAdmin.listTopics().names().get()
+        delete(currentTopics.filter{ matchRegex(it, topics) }, kafkaAdmin)
+        kafkaAdmin.close()
+    }
+
+    /**
+     * This function checks whether one string in `topics` can be used as prefix of a regular expression to create the string `existingTopic`
+     *
+     * @param existingTopic string for which should be checked if it could be created
+     * @param topics list of string which are used as possible prefixes to create `existingTopic`
+     * @return true, `existingTopics` matches a created regex, else false
+     */
+    private fun matchRegex(existingTopic: String, topics: List<String>): Boolean {
+        for (t in topics) {
+            val regex = t.toRegex()
+            if (regex.matches(existingTopic)) {
+                return true
             }
-        } catch (e: Exception) {
-            logger.error { "Error while removing topics: $e" }
-            logger.debug { "Existing topics are: ${kafkaAdmin.listTopics()}." }
         }
-        kafkaAdmin.close()
+        return false
     }
+
+    private fun delete(topics: List<String>, kafkaAdmin: AdminClient) {
+        var deleted = false
+
+        while (!deleted) {
+            try {
+                val result = kafkaAdmin.deleteTopics(topics)
+                result.all().get() // wait for the future to be completed
+                logger.info {
+                    "Topics deletion finished with result: ${
+                        result.values().map { it -> it.key + ": " + it.value.isDone }
+                            .joinToString(separator = ",")
+                    }"
+                }
+            } catch (e: Exception) {
+                logger.error(e) { "Error while removing topics: $e" }
+                logger.info { "Existing topics are: ${kafkaAdmin.listTopics().names().get()}." }
+            }
+
+            val toDelete = topics.filter { kafkaAdmin.listTopics().names().get().contains(it) }
+
+            if (toDelete.isNullOrEmpty()) {
+                deleted = true
+            } else {
+                logger.info { "Deletion of Kafka topics failed, will retry in ${RETRY_TIME/1000} seconds." }
+                sleep(RETRY_TIME)
+            }
+        }
+    }
+
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
index a1a4501c919748389089b9d81e3cf927b0ea2e2a..c0d17244b6a7a3f37b8d8a57713659b85b9b65b1 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
@@ -12,7 +12,7 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
  * @param variableName *(optional)* The variable name to be patched
  *
  *
- * **For example** to patch the load dimension of a workload generator, the Patcher should be created as follow:
+ * **For example** to patch the load dimension of a load generator, the patcher should be created as follow:
  *
  * k8sResource: `uc-1-workload-generator.yaml`
  * container: `workload`
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
index 16bd9aa34127b79c97e8f9d195d4757145a3fa93..b640df1da2ca1c139bb5b02e9e42bad9e7d08d74 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
@@ -2,7 +2,6 @@ package theodolite.patcher
 
 import io.fabric8.kubernetes.api.model.Container
 import io.fabric8.kubernetes.api.model.EnvVar
-import io.fabric8.kubernetes.api.model.EnvVarSource
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.api.model.apps.Deployment
 
@@ -39,7 +38,9 @@ class EnvVarPatcher(
             val x = container.env.filter { envVar -> envVar.name == k }
 
             if (x.isEmpty()) {
-                val newVar = EnvVar(k, v, EnvVarSource())
+                val newVar = EnvVar()
+                newVar.name = k
+                newVar.value = v
                 container.env.add(newVar)
             } else {
                 x.forEach {
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/StrategyFactory.kt b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
index 9bef5587ac9c26d2323af41c5119ac36b95cf807..829370e8ce1c181c1a4cb9fdd8ccf0ecefd48d3d 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
@@ -4,12 +4,13 @@ import theodolite.execution.BenchmarkExecutor
 import theodolite.strategies.restriction.LowerBoundRestriction
 import theodolite.strategies.restriction.RestrictionStrategy
 import theodolite.strategies.searchstrategy.BinarySearch
+import theodolite.strategies.searchstrategy.FullSearch
 import theodolite.strategies.searchstrategy.LinearSearch
 import theodolite.strategies.searchstrategy.SearchStrategy
 import theodolite.util.Results
 
 /**
- * Factory for creating [SearchStrategy] and [RestrictionStrategy] Strategies.
+ * Factory for creating [SearchStrategy] and [RestrictionStrategy] strategies.
  */
 class StrategyFactory {
 
@@ -24,6 +25,7 @@ class StrategyFactory {
      */
     fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyString: String): SearchStrategy {
         return when (searchStrategyString) {
+            "FullSearch" -> FullSearch(executor)
             "LinearSearch" -> LinearSearch(executor)
             "BinarySearch" -> BinarySearch(executor)
             else -> throw IllegalArgumentException("Search Strategy $searchStrategyString not found")
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
index 2911b6ac949a9d523e464c0ea2942063e996d767..13bfedfe055f2bd428137f89b2986f3967ec797c 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
@@ -5,12 +5,13 @@ import theodolite.util.Resource
 import theodolite.util.Results
 
 /**
- * The Lower Bound Restriction sets the lower bound of the resources to be examined to the value
+ * The [LowerBoundRestriction] sets the lower bound of the resources to be examined to the value
  * needed to successfully execute the next smaller load.
  *
  * @param results [Result] object used as a basis to restrict the resources.
  */
 class LowerBoundRestriction(results: Results) : RestrictionStrategy(results) {
+
     override fun apply(load: LoadDimension, resources: List<Resource>): List<Resource> {
         val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load)
         var lowerBound: Resource? = this.results.getMinRequiredInstances(maxLoad)
@@ -19,4 +20,5 @@ class LowerBoundRestriction(results: Results) : RestrictionStrategy(results) {
         }
         return resources.filter { x -> x.get() >= lowerBound.get() }
     }
+
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
index 027444fe36a47878af998abdf18dc7a7562d7afd..28e8194c699cd074026c8cb7e6f3ce4ec347023b 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
@@ -1,9 +1,12 @@
 package theodolite.strategies.searchstrategy
 
+import mu.KotlinLogging
 import theodolite.execution.BenchmarkExecutor
 import theodolite.util.LoadDimension
 import theodolite.util.Resource
 
+private val logger = KotlinLogging.logger {}
+
 /**
  *  Binary-search-like implementation for determining the smallest suitable number of instances.
  *
@@ -32,6 +35,8 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
         }
         // special case:  length == 1 or 2
         if (lower == upper) {
+            val res = resources[lower]
+            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
             if (this.benchmarkExecutor.runExperiment(load, resources[lower])) return lower
             else {
                 if (lower + 1 == resources.size) return -1
@@ -41,6 +46,8 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
             // apply binary search for a list with
             // length > 2 and adjust upper and lower depending on the result for `resources[mid]`
             val mid = (upper + lower) / 2
+            val res = resources[mid]
+            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
             if (this.benchmarkExecutor.runExperiment(load, resources[mid])) {
                 if (mid == lower) {
                     return lower
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
new file mode 100644
index 0000000000000000000000000000000000000000..20290a9477f16c7d479d32ec4435da0c1bb26514
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
@@ -0,0 +1,31 @@
+package theodolite.strategies.searchstrategy
+
+import mu.KotlinLogging
+import theodolite.execution.BenchmarkExecutor
+import theodolite.util.LoadDimension
+import theodolite.util.Resource
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ * [SearchStrategy] that executes experiment for provides resources in a linear-search-like fashion, but **without
+ * stopping** once a suitable resource amount is found.
+ *
+ * @see LinearSearch for a SearchStrategy that stops once a suitable resource amount is found.
+ *
+ * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
+ */
+class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
+
+    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
+        var minimalSuitableResources: Resource? = null;
+        for (res in resources) {
+            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
+            val result = this.benchmarkExecutor.runExperiment(load, res)
+            if (result && minimalSuitableResources != null) {
+                minimalSuitableResources = res
+            }
+        }
+        return minimalSuitableResources
+    }
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
index 08daa082d0eb8f2ecbb71193111a0263ae275fbc..85deaf6fa75437199bfc560404eb5b40bb4a986a 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
@@ -1,9 +1,12 @@
 package theodolite.strategies.searchstrategy
 
+import mu.KotlinLogging
 import theodolite.execution.BenchmarkExecutor
 import theodolite.util.LoadDimension
 import theodolite.util.Resource
 
+private val logger = KotlinLogging.logger {}
+
 /**
  *  Linear-search-like implementation for determining the smallest suitable number of instances.
  *
@@ -13,6 +16,8 @@ class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
 
     override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
         for (res in resources) {
+
+            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
             if (this.benchmarkExecutor.runExperiment(load, res)) return res
         }
         return null
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt
index 4ba096e37345a9488cb288b21a8aa57ff07ac1ff..f304d8cd06969d4650329b9b9f410a56985a2002 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
 import org.apache.kafka.clients.admin.NewTopic
 import kotlin.properties.Delegates
+import kotlin.reflect.KProperty
 
 /**
  * Configuration of Kafka connection.
@@ -23,15 +24,6 @@ class KafkaConfig {
      */
     lateinit var topics: List<TopicWrapper>
 
-    /**
-     * Get all current Kafka topics.
-     *
-     * @return the list of topics.
-     */
-    fun getKafkaTopics(): List<NewTopic> {
-        return topics.map { topic -> NewTopic(topic.name, topic.numPartitions, topic.replicationFactor) }
-    }
-
     /**
      * Wrapper for a topic definition.
      */
@@ -51,5 +43,25 @@ class KafkaConfig {
          * The replication factor of this topic
          */
         var replicationFactor by Delegates.notNull<Short>()
+
+        /**
+         * If remove only, this topic would only used to delete all topics, which has the name of the topic as a prefix.
+         */
+        var removeOnly by DelegatesFalse()
     }
 }
+
+/**
+ * Delegates to initialize a lateinit boolean to false
+ */
+@RegisterForReflection
+class DelegatesFalse {
+    private var state = false
+    operator fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
+        return state
+    }
+    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
+        state = value
+    }
+
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt
index 7116d73cf5b54325c8cfa41b1186d58695628874..60641ea0248435de53aaaaf362da7be995b391c5 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt
@@ -40,23 +40,26 @@ class Results {
      * @param load the [LoadDimension]
      *
      * @return the smallest suitable number of resources. If the experiment was not executed yet,
-     * a @see Resource with the constant Int.MAX_VALUE as value is returned. If no experiments have been marked as either successful or unsuccessful
+     * a @see Resource with the constant Int.MAX_VALUE as value is returned.
+     * If no experiments have been marked as either successful or unsuccessful
      * yet, a Resource with the constant value Int.MIN_VALUE is returned.
      */
     fun getMinRequiredInstances(load: LoadDimension?): Resource? {
-        if (this.results.isEmpty()) return Resource(Int.MIN_VALUE, emptyList())
+        if (this.results.isEmpty()) {
+            return Resource(Int.MIN_VALUE, emptyList())
+        }
 
-        var requiredInstances: Resource? = Resource(Int.MAX_VALUE, emptyList())
+        var minRequiredInstances: Resource? = Resource(Int.MAX_VALUE, emptyList())
         for (experiment in results) {
+            // Get all successful experiments for requested load
             if (experiment.key.first == load && experiment.value) {
-                if (requiredInstances == null) {
-                    requiredInstances = experiment.key.second
-                } else if (experiment.key.second.get() < requiredInstances.get()) {
-                    requiredInstances = experiment.key.second
+                if (minRequiredInstances == null || experiment.key.second.get() < minRequiredInstances.get()) {
+                    // Found new smallest resources
+                    minRequiredInstances = experiment.key.second
                 }
             }
         }
-        return requiredInstances
+        return minRequiredInstances
     }
 
     /**
@@ -70,13 +73,11 @@ class Results {
     fun getMaxBenchmarkedLoad(load: LoadDimension): LoadDimension? {
         var maxBenchmarkedLoad: LoadDimension? = null
         for (experiment in results) {
-            if (experiment.value) {
-                if (experiment.key.first.get() <= load.get()) {
-                    if (maxBenchmarkedLoad == null) {
-                        maxBenchmarkedLoad = experiment.key.first
-                    } else if (maxBenchmarkedLoad.get() < experiment.key.first.get()) {
-                        maxBenchmarkedLoad = experiment.key.first
-                    }
+            if (experiment.key.first.get() <= load.get()) {
+                if (maxBenchmarkedLoad == null) {
+                    maxBenchmarkedLoad = experiment.key.first
+                } else if (maxBenchmarkedLoad.get() < experiment.key.first.get()) {
+                    maxBenchmarkedLoad = experiment.key.first
                 }
             }
         }
diff --git a/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml b/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml
index 9fc16f92e303f05a449f7e8b83600c3b299f215d..19ec972be8236fbdcad123e9c9ef63945bb53d16 100644
--- a/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml
+++ b/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml
@@ -26,4 +26,6 @@ kafkaConfig:
   topics:
     - name: "input"
       numPartitions: 40
-      replicationFactor: 1
\ No newline at end of file
+      replicationFactor: 1
+    - name: "theodolite-.*"
+      removeOnly: True
\ No newline at end of file
diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b6b9eaecd9fc35b25b9447611835c3d8469cea0e
--- /dev/null
+++ b/theodolite-quarkus/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
@@ -0,0 +1,116 @@
+package theodolite.strategies.restriction
+
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Disabled
+import org.junit.jupiter.api.Test
+import theodolite.util.LoadDimension
+import theodolite.util.Resource
+import theodolite.util.Results
+
+internal class LowerBoundRestrictionTest {
+
+    @Test
+    fun testNoPreviousResults() {
+        val results = Results()
+        val strategy = LowerBoundRestriction(results)
+        val load = buildLoadDimension(10000)
+        val resources = listOf(
+            buildResourcesDimension(1),
+            buildResourcesDimension(2),
+            buildResourcesDimension(3)
+        )
+        val restriction = strategy.apply(load, resources)
+
+        assertEquals(3, restriction.size)
+        assertEquals(resources, restriction)
+    }
+
+    @Test
+    fun testWithSuccessfulPreviousResults() {
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(20000, 1, false)
+        results.setResult(20000, 2, true)
+        val strategy = LowerBoundRestriction(results)
+        val load = buildLoadDimension(30000)
+        val resources = listOf(
+            buildResourcesDimension(1),
+            buildResourcesDimension(2),
+            buildResourcesDimension(3)
+        )
+        val restriction = strategy.apply(load, resources)
+
+        assertEquals(2, restriction.size)
+        assertEquals(resources.subList(1,3), restriction)
+    }
+
+    @Test
+    @Disabled
+    fun testWithNoSuccessfulPreviousResults() {
+        // This test is currently not implemented this way, but might later be the desired behavior.
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(20000, 1, false)
+        results.setResult(20000, 2, false)
+        results.setResult(20000, 3, false)
+        val strategy = LowerBoundRestriction(results)
+        val load = buildLoadDimension(30000)
+        val resources = listOf(
+            buildResourcesDimension(1),
+            buildResourcesDimension(2),
+            buildResourcesDimension(3)
+        )
+        val restriction = strategy.apply(load, resources)
+
+        assertEquals(0, restriction.size)
+        assertEquals(emptyList<Resource>(), restriction)
+    }
+
+
+    @Test
+    fun testNoPreviousResults2() {
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(20000, 2, true)
+        results.setResult(10000, 1, false)
+        results.setResult(20000, 2, true)
+
+        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
+
+        assertNotNull(minRequiredInstances)
+        assertEquals(2, minRequiredInstances!!.get())
+    }
+
+    @Test
+    @Disabled
+    fun testMinRequiredInstancesWhenNotSuccessful() {
+        // This test is currently not implemented this way, but might later be the desired behavior.
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(20000, 2, true)
+        results.setResult(10000, 1, false)
+        results.setResult(20000, 2, false)
+
+        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
+
+        assertNotNull(minRequiredInstances)
+        assertEquals(2, minRequiredInstances!!.get())
+    }
+
+    private fun buildLoadDimension(load: Int): LoadDimension {
+        return LoadDimension(load, emptyList())
+    }
+
+    private fun buildResourcesDimension(resources: Int): Resource {
+        return Resource(resources, emptyList())
+    }
+
+    private fun Results.setResult(load: Int, resources: Int, successful: Boolean) {
+        this.setResult(
+            Pair(
+                buildLoadDimension(load),
+                buildResourcesDimension(resources)
+            ),
+            successful)
+    }
+}
\ No newline at end of file
diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/util/ResultsTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/util/ResultsTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9cfc2ae78e7a8846e3f0fa136699509145e5de22
--- /dev/null
+++ b/theodolite-quarkus/src/test/kotlin/theodolite/util/ResultsTest.kt
@@ -0,0 +1,75 @@
+package theodolite.util
+
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertNotNull
+import org.junit.jupiter.api.Disabled
+import org.junit.jupiter.api.Test
+
+@QuarkusTest
+internal class ResultsTest {
+
+    @Test
+    fun testMinRequiredInstancesWhenSuccessful() {
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(10000, 2, true)
+        results.setResult(20000, 1, false)
+        results.setResult(20000, 2, true)
+
+        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
+
+        assertNotNull(minRequiredInstances)
+        assertEquals(2, minRequiredInstances!!.get())
+    }
+
+    @Test
+    @Disabled
+    fun testMinRequiredInstancesWhenNotSuccessful() {
+        // This test is currently not implemented this way, but might later be the desired behavior.
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(10000, 2, true)
+        results.setResult(20000, 1, false)
+        results.setResult(20000, 2, false)
+
+        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
+
+        assertNotNull(minRequiredInstances)
+        assertEquals(2, minRequiredInstances!!.get())
+    }
+
+    private fun Results.setResult(load: Int, resources: Int, successful: Boolean) {
+        this.setResult(
+            Pair(
+                LoadDimension(load, emptyList()),
+                Resource(resources, emptyList())
+            ),
+            successful
+        )
+    }
+
+
+    @Test
+    fun testGetMaxBenchmarkedLoadWhenAllSuccessful() {
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(10000, 2, true)
+
+        val test1 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get()
+
+        assertEquals(10000, test1)
+    }
+
+    @Test
+    fun testGetMaxBenchmarkedLoadWhenLargestNotSuccessful() {
+        val results = Results()
+        results.setResult(10000, 1, true)
+        results.setResult(10000, 2, true)
+        results.setResult(20000, 1, false)
+
+        val test2 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get()
+
+        assertEquals(20000, test2)
+    }
+}