diff --git a/docs/api-reference/crds.md b/docs/api-reference/crds.md
index c5cc7596f4c23408597f48b366f6b97e889e7a66..996ea1a3a4486ca27031f3d29ad64e018f66f5fb 100644
--- a/docs/api-reference/crds.md
+++ b/docs/api-reference/crds.md
@@ -1774,7 +1774,7 @@ Contains the Kafka configuration.
         </td>
         <td>true</td>
       </tr><tr>
-        <td><b><a href="#executionspecload">load</a></b></td>
+        <td><b><a href="#executionspecloads">loads</a></b></td>
         <td>object</td>
         <td>
           Specifies the load values that are benchmarked.<br/>
@@ -1915,35 +1915,83 @@ Defines the overall parameter for the execution.
         <td><b>repetitions</b></td>
         <td>integer</td>
         <td>
-          Numper of repititions for each experiments.<br/>
+          Number of repititions for each experiment.<br/>
         </td>
         <td>true</td>
       </tr><tr>
-        <td><b>restrictions</b></td>
-        <td>[]string</td>
+        <td><b><a href="#executionspecexecutionstrategy">strategy</a></b></td>
+        <td>object</td>
         <td>
-          List of restriction strategys used to delimit the search space.<br/>
+          Defines the used strategy for the execution, either 'LinearSearch', 'BinarySearch' or 'InitialGuessSearch'.<br/>
         </td>
         <td>true</td>
       </tr><tr>
-        <td><b>strategy</b></td>
+        <td><b>loadGenerationDelay</b></td>
+        <td>integer</td>
+        <td>
+          Seconds to wait between the start of the SUT and the load generator.<br/>
+        </td>
+        <td>false</td>
+      </tr><tr>
+        <td><b>metric</b></td>
+        <td>string</td>
+        <td>
+          <br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### execution.spec.execution.strategy
+<sup><sup>[↩ Parent](#executionspecexecution)</sup></sup>
+
+
+
+Defines the used strategy for the execution, either 'LinearSearch', 'BinarySearch' or 'InitialGuessSearch'.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b>name</b></td>
         <td>string</td>
         <td>
-          Defines the used strategy for the execution, either 'LinearSearch' or 'BinarySearch'<br/>
+          <br/>
         </td>
         <td>true</td>
       </tr><tr>
-        <td><b>loadGenerationDelay</b></td>
-        <td>integer</td>
+        <td><b>guessStrategy</b></td>
+        <td>string</td>
         <td>
-          Seconds to wait between the start of the SUT and the load generator.<br/>
+          <br/>
+        </td>
+        <td>false</td>
+      </tr><tr>
+        <td><b>restrictions</b></td>
+        <td>[]string</td>
+        <td>
+          List of restriction strategies used to delimit the search space.<br/>
+        </td>
+        <td>false</td>
+      </tr><tr>
+        <td><b>searchStrategy</b></td>
+        <td>string</td>
+        <td>
+          <br/>
         </td>
         <td>false</td>
       </tr></tbody>
 </table>
 
 
-### execution.spec.load
+### execution.spec.loads
 <sup><sup>[↩ Parent](#executionspec)</sup></sup>
 
 
diff --git a/theodolite/crd/crd-execution.yaml b/theodolite/crd/crd-execution.yaml
index 92a8ca18d87009143620097caf2abfe8da202c82..0240fc6ee05f5a573b1f738d931d78c3bb9b5859 100644
--- a/theodolite/crd/crd-execution.yaml
+++ b/theodolite/crd/crd-execution.yaml
@@ -20,7 +20,7 @@ spec:
         properties:
           spec:
             type: object
-            required: ["benchmark", "load", "resources", "slos", "execution", "configOverrides"]
+            required: ["benchmark", "loads", "resources", "slos", "execution", "configOverrides"]
             properties:
               name:
                 description: This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten.
@@ -29,7 +29,7 @@ spec:
               benchmark:
                 description: The name of the benchmark this execution is referring to.
                 type: string
-              load: # definition of the load dimension
+              loads: # definition of the load dimension
                 description: Specifies the load values that are benchmarked.
                 type: object
                 required: ["loadType", "loadValues"]
@@ -80,25 +80,35 @@ spec:
               execution: # def execution config
                 description: Defines the overall parameter for the execution.
                 type: object
-                required: ["strategy", "duration", "repetitions", "restrictions"]
+                required: ["strategy", "duration", "repetitions"]
                 properties:
-                  strategy:
-                    description: Defines the used strategy for the execution, either 'LinearSearch' or 'BinarySearch'
+                  metric:
                     type: string
+                  strategy:
+                    description: Defines the used strategy for the execution, either 'LinearSearch', 'BinarySearch' or 'InitialGuessSearch'.
+                    type: object
+                    required: ["name"]
+                    properties:
+                      name:
+                        type: string
+                      restrictions:
+                        description: List of restriction strategies used to delimit the search space.
+                        type: array
+                        items:
+                          type: string
+                      guessStrategy:
+                        type: string
+                      searchStrategy:
+                        type: string
                   duration:
                     description: Defines the duration of each experiment in seconds.
                     type: integer
                   repetitions:
-                    description: Numper of repititions for each experiments.
+                    description: Number of repititions for each experiment.
                     type: integer
                   loadGenerationDelay:
                     description: Seconds to wait between the start of the SUT and the load generator.
                     type: integer
-                  restrictions:
-                    description: List of restriction strategys used to delimit the search space.
-                    type: array
-                    items:
-                      type: string
               configOverrides:
                 description:  List of patchers that are used to override existing configurations.
                 type: array
diff --git a/theodolite/examples/operator/example-execution.yaml b/theodolite/examples/operator/example-execution.yaml
index 576a74b90dfc38483de79502ac14d42f6bedfb49..b94aa9b2656f02f1b3f7fbf87edeceaa923e1ab8 100644
--- a/theodolite/examples/operator/example-execution.yaml
+++ b/theodolite/examples/operator/example-execution.yaml
@@ -4,7 +4,7 @@ metadata:
   name: theodolite-example-execution
 spec:
   benchmark: "example-benchmark"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
@@ -19,12 +19,14 @@ spec:
         externalSloUrl: "http://localhost:80/evaluate-slope"
         warmup: 60 # in seconds
   execution:
-    strategy: "LinearSearch"
+    strategy:
+      name: "RestrictionSearch"
+      restrictions:
+        - "LowerBound"
+      searchStrategy: "LinearSearch"
     duration: 300 # in seconds
     repetitions: 1
     loadGenerationDelay: 30 # in seconds
-    restrictions:
-      - "LowerBound"
   configOverrides: []
   # - patcher:
   #     type: "NodeSelectorPatcher"
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt
index cf2fac7337d79c1c5daf2b0fac070200cf27f9a5..f2b587cba90151af199da4b76a9cb8ad407f80ef 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt
+++ b/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt
@@ -2,13 +2,12 @@ package theodolite.benchmark
 
 import io.quarkus.runtime.annotations.RegisterForReflection
 import theodolite.util.ConfigurationOverride
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import theodolite.util.PatcherDefinition
 
 /**
  * A Benchmark contains:
- * - The [Resource]s that can be scaled for the benchmark.
- * - The [LoadDimension]s that can be scaled the benchmark.
+ * - The Resource that can be scaled for the benchmark.
+ * - The Load that can be scaled the benchmark.
  * - additional [ConfigurationOverride]s.
  */
 @RegisterForReflection
@@ -22,10 +21,12 @@ interface Benchmark {
      * @return a BenchmarkDeployment.
      */
     fun buildDeployment(
-        load: LoadDimension,
-        res: Resource,
-        configurationOverrides: List<ConfigurationOverride?>,
-        loadGenerationDelay: Long,
-        afterTeardownDelay: Long
+            load: Int,
+            loadPatcherDefinitions: List<PatcherDefinition>,
+            resource: Int,
+            resourcePatcherDefinitions: List<PatcherDefinition>,
+            configurationOverrides: List<ConfigurationOverride?>,
+            loadGenerationDelay: Long,
+            afterTeardownDelay: Long
     ): BenchmarkDeployment
 }
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt b/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
index f2dda487d390c5f771e4f47c0f9c7ebf2cf971e7..1010a8a344442b24f818d73a400a799153ed8947 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
+++ b/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
@@ -12,7 +12,7 @@ import kotlin.properties.Delegates
  * A BenchmarkExecution consists of:
  *  - A [name].
  *  - The [benchmark] that should be executed.
- *  - The [load] that should be checked in the benchmark.
+ *  - The [loads]s that should be checked in the benchmark.
  *  - The [resources] that should be checked in the benchmark.
  *  - A list of [slos] that are used for the evaluation of the experiments.
  *  - An [execution] that encapsulates: the strategy, the duration, and the restrictions
@@ -28,27 +28,42 @@ class BenchmarkExecution : KubernetesResource {
     var executionId: Int = 0
     lateinit var name: String
     lateinit var benchmark: String
-    lateinit var load: LoadDefinition
+    lateinit var loads: LoadDefinition
     lateinit var resources: ResourceDefinition
     lateinit var slos: List<Slo>
     lateinit var execution: Execution
     lateinit var configOverrides: MutableList<ConfigurationOverride?>
 
     /**
-     * This execution encapsulates the [strategy], the [duration], the [repetitions], and the [restrictions]
+     * This execution encapsulates the [strategy], the [duration], and the [repetitions],
      *  which are used for the concrete benchmark experiments.
      */
     @JsonDeserialize
     @RegisterForReflection
     class Execution : KubernetesResource {
-        lateinit var strategy: String
+        var metric = "demand"
+        lateinit var strategy: Strategy
         var duration by Delegates.notNull<Long>()
         var repetitions by Delegates.notNull<Int>()
-        lateinit var restrictions: List<String>
         var loadGenerationDelay = 0L
         var afterTeardownDelay = 5L
     }
 
+    /**
+     * This Strategy encapsulates the [restrictions], [guessStrategy] and [searchStrategy],
+     * which are used for restricting the resources, the guess Strategy for the
+     * [theodolite.strategies.searchstrategy.InitialGuessSearchStrategy] and the name of the actual
+     * [theodolite.strategies.searchstrategy.SearchStrategy] which is used.
+     */
+    @JsonDeserialize
+    @RegisterForReflection
+    class Strategy : KubernetesResource {
+        lateinit var name: String
+        var restrictions = emptyList<String>()
+        var guessStrategy = ""
+        var searchStrategy = ""
+    }
+
     /**
      * Measurable metric.
      * [sloType] determines the type of the metric.
@@ -68,8 +83,8 @@ class BenchmarkExecution : KubernetesResource {
     }
 
     /**
-     * Represents a Load that should be created and checked.
-     * It can be set to [loadValues].
+     * Represents the Loads that should be created and checked if the demand metric is in use or
+     * represents a Load that can be scaled to [loadValues] if the capacity metric is in use.
      */
     @JsonDeserialize
     @RegisterForReflection
@@ -79,7 +94,8 @@ class BenchmarkExecution : KubernetesResource {
     }
 
     /**
-     * Represents a resource that can be scaled to [resourceValues].
+     * Represents a resource that can be scaled to [resourceValues] if the demand metric is in use or
+     * represents the Resources that should be created and checked if the capacity metric is in use.
      */
     @JsonDeserialize
     @RegisterForReflection
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
index ddb83c54c7845651754ae82c9abf8780c77fdba1..599f723621db2b86c9163af9351ac896f82b2b86 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
+++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
@@ -82,19 +82,22 @@ class KubernetesBenchmark : KubernetesResource, Benchmark {
 
     /**
      * Builds a deployment.
-     * First loads all required resources and then patches them to the concrete load and resources for the experiment.
-     * Afterwards patches additional configurations(cluster depending) into the resources.
-     * @param load concrete load that will be benchmarked in this experiment.
-     * @param res concrete resource that will be scaled for this experiment.
+     * First loads all required resources and then patches them to the concrete load and resources for the experiment for the demand metric
+     * or loads all loads and then patches them to the concrete load and resources for the experiment.
+     * Afterwards patches additional configurations(cluster depending) into the resources (or loads).
+     * @param load concrete load that will be benchmarked in this experiment (demand metric), or scaled (capacity metric).
+     * @param resource concrete resource that will be scaled for this experiment (demand metric), or benchmarked (capacity metric).
      * @param configurationOverrides
      * @return a [BenchmarkDeployment]
      */
     override fun buildDeployment(
-        load: LoadDimension,
-        res: Resource,
+        load: Int,
+        loadPatcherDefinitions: List<PatcherDefinition>,
+        resource: Int,
+        resourcePatcherDefinitions: List<PatcherDefinition>,
         configurationOverrides: List<ConfigurationOverride?>,
         loadGenerationDelay: Long,
-        afterTeardownDelay: Long,
+        afterTeardownDelay: Long
     ): BenchmarkDeployment {
         logger.info { "Using $namespace as namespace." }
 
@@ -102,14 +105,14 @@ class KubernetesBenchmark : KubernetesResource, Benchmark {
         val appResources = loadResources(this.sut.resources).toResourceMap()
         val loadGenResources = loadResources(this.loadGenerator.resources).toResourceMap()
 
-        load.getType().forEach { patcherDefinition ->
+        // patch the load dimension the resources
+        loadPatcherDefinitions.forEach { patcherDefinition ->
             loadGenResources[patcherDefinition.resource] =
-                PatchHandler.patchResource(loadGenResources, patcherDefinition, load.get().toString())
+                PatchHandler.patchResource(loadGenResources, patcherDefinition, load.toString())
         }
-
-        res.getType().forEach { patcherDefinition ->
+        resourcePatcherDefinitions.forEach { patcherDefinition ->
             appResources[patcherDefinition.resource] =
-                PatchHandler.patchResource(appResources, patcherDefinition, res.get().toString())
+                PatchHandler.patchResource(appResources, patcherDefinition, resource.toString())
         }
 
         configurationOverrides.forEach { override ->
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
index b3cc174d2945bf13bc1cc29d4e60d8c9bfbaf7eb..9e460fd0befafef8a644de870a5b33ccdfcf2029 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
+++ b/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
@@ -1,10 +1,9 @@
 package theodolite.evaluation
 
 import theodolite.benchmark.BenchmarkExecution
+import theodolite.strategies.Metric
 import theodolite.util.EvaluationFailedException
 import theodolite.util.IOHandler
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 import java.text.Normalizer
 import java.time.Duration
 import java.time.Instant
@@ -29,17 +28,17 @@ class AnalysisExecutor(
      *  Analyses an experiment via prometheus data.
      *  First fetches data from prometheus, then documents them and afterwards evaluate it via a [slo].
      *  @param load of the experiment.
-     *  @param res of the experiment.
+     *  @param resource of the experiment.
      *  @param executionIntervals list of start and end points of experiments
      *  @return true if the experiment succeeded.
      */
-    fun analyze(load: LoadDimension, res: Resource, executionIntervals: List<Pair<Instant, Instant>>): Boolean {
+    fun analyze(load: Int, resource: Int, executionIntervals: List<Pair<Instant, Instant>>, metric: Metric): Boolean {
         var repetitionCounter = 1
 
         try {
             val ioHandler = IOHandler()
             val resultsFolder = ioHandler.getResultFolderURL()
-            val fileURL = "${resultsFolder}exp${executionId}_${load.get()}_${res.get()}_${slo.sloType.toSlug()}"
+            val fileURL = "${resultsFolder}exp${executionId}_${load}_${resource}_${slo.sloType.toSlug()}"
 
             val prometheusData = executionIntervals
                 .map { interval ->
@@ -61,13 +60,15 @@ class AnalysisExecutor(
             val sloChecker = SloCheckerFactory().create(
                 sloType = slo.sloType,
                 properties = slo.properties,
-                load = load
+                load = load,
+                resource = resource,
+                metric = metric
             )
 
             return sloChecker.evaluate(prometheusData)
 
         } catch (e: Exception) {
-            throw EvaluationFailedException("Evaluation failed for resource '${res.get()}' and load '${load.get()}", e)
+            throw EvaluationFailedException("Evaluation failed for resource '$resource' and load '$load ", e)
         }
     }
 
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt b/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
index f57cebfcb13d0e86919ec15a0a479d1258e318a6..7ab6a0255f6c078f0f365289baa1eb0300a3244a 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
+++ b/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
@@ -1,6 +1,7 @@
 package theodolite.evaluation
 
-import theodolite.util.LoadDimension
+import theodolite.strategies.Metric
+
 
 /**
  * Factory used to potentially create different [SloChecker]s.
@@ -41,7 +42,9 @@ class SloCheckerFactory {
     fun create(
         sloType: String,
         properties: MutableMap<String, String>,
-        load: LoadDimension
+        load: Int,
+        resource: Int,
+        metric: Metric
     ): SloChecker {
         return when (SloTypes.from(sloType)) {
             SloTypes.GENERIC -> ExternalSloChecker(
@@ -76,7 +79,7 @@ class SloCheckerFactory {
                     throw IllegalArgumentException("Threshold ratio needs to be an Double greater or equal 0.0")
                 }
                 // cast to int, as rounding is not really necessary
-                val threshold = (load.get() * thresholdRatio).toInt()
+                val threshold = (load * thresholdRatio).toInt()
 
                 ExternalSloChecker(
                     externalSlopeURL = properties["externalSloUrl"]
diff --git a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
index 3238f447be06ce6486bb7f6ca1758700f36ba558..55233246fedcd5163f5d3c954d32bd2056b2f31d 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
@@ -4,8 +4,7 @@ import mu.KotlinLogging
 import theodolite.benchmark.Benchmark
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.util.ConfigurationOverride
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import theodolite.util.PatcherDefinition
 import theodolite.util.Results
 import java.time.Duration
 import java.util.concurrent.atomic.AtomicBoolean
@@ -30,7 +29,9 @@ abstract class BenchmarkExecutor(
     val executionId: Int,
     val loadGenerationDelay: Long,
     val afterTeardownDelay: Long,
-    val executionName: String
+    val executionName: String,
+    val loadPatcherDefinitions: List<PatcherDefinition>,
+    val resourcePatcherDefinitions: List<PatcherDefinition>
 ) {
 
     var run: AtomicBoolean = AtomicBoolean(true)
@@ -39,12 +40,14 @@ abstract class BenchmarkExecutor(
      * Run a experiment for the given parametrization, evaluate the
      * experiment and save the result.
      *
-     * @param load load to be tested.
-     * @param res resources to be tested.
+     * @param load to be tested.
+     * @param resource to be tested.
      * @return True, if the number of resources are suitable for the
-     *     given load, false otherwise.
+     *     given load, false otherwise (demand metric), or
+     *     True, if there is a load suitable for the
+     *     given resource, false otherwise.
      */
-    abstract fun runExperiment(load: LoadDimension, res: Resource): Boolean
+    abstract fun runExperiment(load: Int, resource: Int): Boolean
 
     /**
      * Wait while the benchmark is running and log the number of minutes executed every 1 minute.
diff --git a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
index 2e938be3a6e503a5e7e3f94c18a9454e173db5b0..e2b6c0930764e282b92905066a488f76d036db4c 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
@@ -23,7 +23,9 @@ class BenchmarkExecutorImpl(
     executionId: Int,
     loadGenerationDelay: Long,
     afterTeardownDelay: Long,
-    executionName: String
+    executionName: String,
+    loadPatcherDefinitions: List<PatcherDefinition>,
+    resourcePatcherDefinitions: List<PatcherDefinition>
 ) : BenchmarkExecutor(
     benchmark,
     results,
@@ -34,24 +36,26 @@ class BenchmarkExecutorImpl(
     executionId,
     loadGenerationDelay,
     afterTeardownDelay,
-    executionName
+    executionName,
+    loadPatcherDefinitions,
+    resourcePatcherDefinitions
 ) {
     private val eventCreator = EventCreator()
     private val mode = Configuration.EXECUTION_MODE
 
-    override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
+    override fun runExperiment(load: Int, resource: Int): Boolean {
         var result = false
         val executionIntervals: MutableList<Pair<Instant, Instant>> = ArrayList()
 
         for (i in 1.rangeTo(repetitions)) {
             if (this.run.get()) {
                 logger.info { "Run repetition $i/$repetitions" }
-                executionIntervals.add(runSingleExperiment(load, res))
+                executionIntervals.add(runSingleExperiment(
+                        load, resource))
             } else {
                 break
             }
         }
-
         /**
          * Analyse the experiment, if [run] is true, otherwise the experiment was canceled by the user.
          */
@@ -60,26 +64,26 @@ class BenchmarkExecutorImpl(
                 AnalysisExecutor(slo = it, executionId = executionId)
                     .analyze(
                         load = load,
-                        res = res,
-                        executionIntervals = executionIntervals
+                        resource = resource,
+                        executionIntervals = executionIntervals,
+                        metric = this.results.metric
                     )
             }
 
             result = (false !in experimentResults)
-            this.results.setResult(Pair(load, res), result)
-        }
-
-        if(!this.run.get()) {
+            this.results.setResult(Pair(load, resource), result)
+        } else {
             throw ExecutionFailedException("The execution was interrupted")
         }
-
         return result
     }
 
-    private fun runSingleExperiment(load: LoadDimension, res: Resource): Pair<Instant, Instant> {
+    private fun runSingleExperiment(load: Int, resource: Int): Pair<Instant, Instant> {
         val benchmarkDeployment = benchmark.buildDeployment(
             load,
-            res,
+            this.loadPatcherDefinitions,
+            resource,
+            this.resourcePatcherDefinitions,
             this.configurationOverrides,
             this.loadGenerationDelay,
             this.afterTeardownDelay
@@ -94,7 +98,7 @@ class BenchmarkExecutorImpl(
                     executionName = executionName,
                     type = "NORMAL",
                     reason = "Start experiment",
-                    message = "load: ${load.get()}, resources: ${res.get()}")
+                    message = "load: $load, resources: $resource")
             }
         } catch (e: Exception) {
             this.run.set(false)
@@ -104,7 +108,7 @@ class BenchmarkExecutorImpl(
                     executionName = executionName,
                     type = "WARNING",
                     reason = "Start experiment failed",
-                    message = "load: ${load.get()}, resources: ${res.get()}")
+                    message = "load: $load, resources: $resource")
             }
             throw ExecutionFailedException("Error during setup the experiment", e)
         }
diff --git a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt b/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
index 29ac39c122f68636e08c6c5ecd5a6c01751edafb..cdfe68e7a93d64f2385bded31f94f77ab7b3be0e 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
@@ -3,8 +3,6 @@ package theodolite.execution
 import mu.KotlinLogging
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.benchmark.KubernetesBenchmark
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 
 private val logger = KotlinLogging.logger {}
 
@@ -26,8 +24,10 @@ class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val b
             logger.info { "Received shutdown signal -> Shutting down" }
             val deployment =
                 benchmark.buildDeployment(
-                    load = LoadDimension(0, emptyList()),
-                    res = Resource(0, emptyList()),
+                    load = 0,
+                    loadPatcherDefinitions = emptyList(),
+                    resource = 0,
+                    resourcePatcherDefinitions = emptyList(),
                     configurationOverrides = benchmarkExecution.configOverrides,
                     loadGenerationDelay = 0L,
                     afterTeardownDelay = 5L
diff --git a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
index 8596576e0a7984c32b6dabf90c6bbf06961d2bb1..3879e67239c9ba7140114ee605a2e71de3409c98 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
@@ -4,8 +4,8 @@ import mu.KotlinLogging
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.benchmark.KubernetesBenchmark
 import theodolite.patcher.PatcherDefinitionFactory
+import theodolite.strategies.Metric
 import theodolite.strategies.StrategyFactory
-import theodolite.strategies.searchstrategy.CompositeStrategy
 import theodolite.util.*
 import java.io.File
 import java.time.Duration
@@ -33,12 +33,12 @@ class TheodoliteExecutor(
     /**
      * Creates all required components to start Theodolite.
      *
-     * @return a [Config], that contains a list of [LoadDimension]s,
-     *          a list of [Resource]s , and the [CompositeStrategy].
-     * The [CompositeStrategy] is configured and able to find the minimum required resource for the given load.
+     * @return a [Config], that contains a list of LoadDimension s,
+     *          a list of Resource s , and the [restrictionSearch].
+     * The [searchStrategy] is configured and able to find the minimum required resource for the given load.
      */
     private fun buildConfig(): Config {
-        val results = Results()
+        val results = Results(Metric.from(config.execution.metric))
         val strategyFactory = StrategyFactory()
 
         val executionDuration = Duration.ofSeconds(config.execution.duration)
@@ -51,7 +51,7 @@ class TheodoliteExecutor(
 
         val loadDimensionPatcherDefinition =
             PatcherDefinitionFactory().createPatcherDefinition(
-                config.load.loadType,
+                config.loads.loadType,
                 this.kubernetesBenchmark.loadTypes
             )
 
@@ -66,14 +66,16 @@ class TheodoliteExecutor(
                 executionId = config.executionId,
                 loadGenerationDelay = config.execution.loadGenerationDelay,
                 afterTeardownDelay = config.execution.afterTeardownDelay,
-                executionName = config.name
+                executionName = config.name,
+                loadPatcherDefinitions = loadDimensionPatcherDefinition,
+                resourcePatcherDefinitions = resourcePatcherDefinition
             )
 
-        if (config.load.loadValues != config.load.loadValues.sorted()) {
-            config.load.loadValues = config.load.loadValues.sorted()
+        if (config.loads.loadValues != config.loads.loadValues.sorted()) {
+            config.loads.loadValues = config.loads.loadValues.sorted()
             logger.info {
                 "Load values are not sorted correctly, Theodolite sorts them in ascending order." +
-                        "New order is: ${config.load.loadValues}"
+                        "New order is: ${config.loads.loadValues}"
             }
         }
 
@@ -86,21 +88,12 @@ class TheodoliteExecutor(
         }
 
         return Config(
-            loads = config.load.loadValues.map { load -> LoadDimension(load, loadDimensionPatcherDefinition) },
-            resources = config.resources.resourceValues.map { resource ->
-                Resource(
-                    resource,
-                    resourcePatcherDefinition
-                )
-            },
-            compositeStrategy = CompositeStrategy(
-                benchmarkExecutor = executor,
-                searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy),
-                restrictionStrategies = strategyFactory.createRestrictionStrategy(
-                    results,
-                    config.execution.restrictions
-                )
-            )
+            loads = config.loads.loadValues,
+            loadPatcherDefinitions = loadDimensionPatcherDefinition,
+            resources = config.resources.resourceValues,
+            resourcePatcherDefinitions = resourcePatcherDefinition,
+            searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy, results),
+            metric = Metric.from(config.execution.metric)
         )
     }
 
@@ -125,24 +118,31 @@ class TheodoliteExecutor(
         )
 
         val config = buildConfig()
-        // execute benchmarks for each load
+
+        //execute benchmarks for each load for the demand metric, or for each resource amount for capacity metric
         try {
-            for (load in config.loads) {
-                if (executor.run.get()) {
-                    config.compositeStrategy.findSuitableResource(load, config.resources)
-                }
-            }
+            config.searchStrategy.applySearchStrategyByMetric(config.loads, config.resources, config.metric)
+
         } finally {
             ioHandler.writeToJSONFile(
-                config.compositeStrategy.benchmarkExecutor.results,
+                config.searchStrategy.benchmarkExecutor.results,
                 "${resultsFolder}exp${this.config.executionId}-result"
             )
-            // Create expXYZ_demand.csv file
-            ioHandler.writeToCSVFile(
-                "${resultsFolder}exp${this.config.executionId}_demand",
-                calculateDemandMetric(config.loads, config.compositeStrategy.benchmarkExecutor.results),
-                listOf("load","resources")
-            )
+            // Create expXYZ_demand.csv file or expXYZ_capacity.csv depending on metric
+            when(config.metric) {
+                Metric.DEMAND ->
+                    ioHandler.writeToCSVFile(
+                        "${resultsFolder}exp${this.config.executionId}_demand",
+                        calculateMetric(config.loads, config.searchStrategy.benchmarkExecutor.results),
+                        listOf("load","resources")
+                    )
+                Metric.CAPACITY ->
+                    ioHandler.writeToCSVFile(
+                        "${resultsFolder}exp${this.config.executionId}_capacity",
+                        calculateMetric(config.resources, config.searchStrategy.benchmarkExecutor.results),
+                        listOf("resource", "loads")
+                    )
+            }
         }
         kubernetesBenchmark.teardownInfrastructure()
     }
@@ -157,8 +157,8 @@ class TheodoliteExecutor(
         return executionID
     }
 
-    private fun calculateDemandMetric(loadDimensions: List<LoadDimension>, results: Results): List<List<String>> {
-        return loadDimensions.map { listOf(it.get().toString(), results.getMinRequiredInstances(it).get().toString()) }
+    private fun calculateMetric(xValues: List<Int>, results: Results): List<List<String>> {
+        return xValues.map { listOf(it.toString(), results.getOptYDimensionValue(it).toString()) }
     }
 
 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/Metric.kt b/theodolite/src/main/kotlin/theodolite/strategies/Metric.kt
new file mode 100644
index 0000000000000000000000000000000000000000..05383ca913a460641a6e632211787a2aec17e9d0
--- /dev/null
+++ b/theodolite/src/main/kotlin/theodolite/strategies/Metric.kt
@@ -0,0 +1,11 @@
+package theodolite.strategies
+
+enum class Metric(val value: String) {
+    DEMAND("demand"),
+    CAPACITY("capacity");
+
+    companion object {
+        fun from(metric: String): Metric =
+                values().find { it.value == metric } ?: throw IllegalArgumentException("Requested Metric does not exist")
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt b/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
index 829370e8ce1c181c1a4cb9fdd8ccf0ecefd48d3d..505681716966016548416bf40cefc2c9ad15d805 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
@@ -1,12 +1,10 @@
 package theodolite.strategies
 
+import theodolite.benchmark.BenchmarkExecution
 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.strategies.searchstrategy.*
 import theodolite.util.Results
 
 /**
@@ -18,18 +16,37 @@ class StrategyFactory {
      * Create a [SearchStrategy].
      *
      * @param executor The [theodolite.execution.BenchmarkExecutor] that executes individual experiments.
-     * @param searchStrategyString Specifies the [SearchStrategy]. Must either be the string 'LinearSearch',
-     * or 'BinarySearch'.
+     * @param searchStrategyObject Specifies the [SearchStrategy]. Must either be an object with name 'FullSearch',
+     * 'LinearSearch', 'BinarySearch', 'RestrictionSearch' or 'InitialGuessSearch'.
+     * @param results The [Results] saves the state of the Theodolite benchmark run.
      *
      * @throws IllegalArgumentException if the [SearchStrategy] was not one of the allowed options.
      */
-    fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyString: String): SearchStrategy {
-        return when (searchStrategyString) {
+    fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyObject: BenchmarkExecution.Strategy,
+                             results: Results): SearchStrategy {
+
+        var strategy : SearchStrategy = when (searchStrategyObject.name) {
             "FullSearch" -> FullSearch(executor)
             "LinearSearch" -> LinearSearch(executor)
             "BinarySearch" -> BinarySearch(executor)
-            else -> throw IllegalArgumentException("Search Strategy $searchStrategyString not found")
+            "RestrictionSearch" -> when (searchStrategyObject.searchStrategy){
+                "FullSearch" -> composeSearchRestrictionStrategy(executor, FullSearch(executor), results,
+                        searchStrategyObject.restrictions)
+                "LinearSearch" -> composeSearchRestrictionStrategy(executor, LinearSearch(executor), results,
+                        searchStrategyObject.restrictions)
+                "BinarySearch" -> composeSearchRestrictionStrategy(executor, BinarySearch(executor), results,
+                        searchStrategyObject.restrictions)
+                else -> throw IllegalArgumentException(
+                        "Search Strategy ${searchStrategyObject.searchStrategy} for RestrictionSearch not found")
+            }
+            "InitialGuessSearch" -> when (searchStrategyObject.guessStrategy){
+                "PrevResourceMinGuess" -> InitialGuessSearchStrategy(executor,PrevInstanceOptGuess(), results)
+                else -> throw IllegalArgumentException("Guess Strategy ${searchStrategyObject.guessStrategy} not found")
+            }
+            else -> throw IllegalArgumentException("Search Strategy $searchStrategyObject not found")
         }
+
+        return strategy
     }
 
     /**
@@ -37,12 +54,12 @@ class StrategyFactory {
      *
      * @param results The [Results] saves the state of the Theodolite benchmark run.
      * @param restrictionStrings Specifies the list of [RestrictionStrategy] that are used to restrict the amount
-     * of [theodolite.util.Resource] for a fixed LoadDimension. Must equal the string
-     * 'LowerBound'.
+     * of Resource for a fixed load or resource (depending on the metric).
+     * Must equal the string 'LowerBound'.
      *
      * @throws IllegalArgumentException if param searchStrategyString was not one of the allowed options.
      */
-    fun createRestrictionStrategy(results: Results, restrictionStrings: List<String>): Set<RestrictionStrategy> {
+    private fun createRestrictionStrategy(results: Results, restrictionStrings: List<String>): Set<RestrictionStrategy> {
         return restrictionStrings
             .map { restriction ->
                 when (restriction) {
@@ -51,4 +68,21 @@ class StrategyFactory {
                 }
             }.toSet()
     }
+
+    /**
+     * Create a RestrictionSearch, if the provided restriction list is not empty. Otherwise just return the given
+     * searchStrategy.
+     *
+     * @param executor The [theodolite.execution.BenchmarkExecutor] that executes individual experiments.
+     * @param searchStrategy The [SearchStrategy] to use.
+     * @param results The [Results] saves the state of the Theodolite benchmark run.
+     * @param restrictions The [RestrictionStrategy]'s to use.
+     */
+    private fun composeSearchRestrictionStrategy(executor: BenchmarkExecutor, searchStrategy: SearchStrategy,
+                                                 results: Results, restrictions: List<String>): SearchStrategy {
+        if(restrictions.isNotEmpty()){
+            return RestrictionSearch(executor,searchStrategy,createRestrictionStrategy(results, restrictions))
+        }
+        return searchStrategy
+    }
 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt b/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
index 13bfedfe055f2bd428137f89b2986f3967ec797c..1203d7293e3790aac2af653c9ceccd0c2ef544bd 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
@@ -1,24 +1,24 @@
 package theodolite.strategies.restriction
 
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 import theodolite.util.Results
 
 /**
- * The [LowerBoundRestriction] sets the lower bound of the resources to be examined to the value
- * needed to successfully execute the next smaller load.
+ * The [LowerBoundRestriction] sets the lower bound of the resources to be examined in the experiment to the value
+ * needed to successfully execute the previous smaller load (demand metric), or sets the lower bound of the loads
+ * to be examined in the experiment to the largest value, which still successfully executed the previous smaller
+ * resource (capacity metric).
  *
  * @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)
+    override fun apply(xValue: Int, yValues: List<Int>): List<Int> {
+        val maxXValue: Int? = this.results.getMaxBenchmarkedXDimensionValue(xValue)
+        var lowerBound: Int? = this.results.getOptYDimensionValue(maxXValue)
         if (lowerBound == null) {
-            lowerBound = resources[0]
+            lowerBound = yValues[0]
         }
-        return resources.filter { x -> x.get() >= lowerBound.get() }
+        return yValues.filter { x -> x >= lowerBound }
     }
 
 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
index 1ab7302d7898daad729b1c94c32d97138b5cdcf4..1ac9d201c734c84db4ec8837c8a242f2be8531b9 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
@@ -1,12 +1,10 @@
 package theodolite.strategies.restriction
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 import theodolite.util.Results
 
 /**
- * A 'Restriction Strategy' restricts a list of resources based on the current
+ * A 'Restriction Strategy' restricts a list of resources or loads depending on the metric based on the current
  * results of all previously performed benchmarks.
  *
  * @param results the [Results] object
@@ -14,12 +12,13 @@ import theodolite.util.Results
 @RegisterForReflection
 abstract class RestrictionStrategy(val results: Results) {
     /**
-     * Apply the restriction of the given resource list for the given load based on the results object.
+     * Apply the restriction of the given resource list for the given load based on the results object (demand metric),
+     * or apply the restriction of the given load list for the given resource based on the results object (capacity metric).
      *
-     * @param load [LoadDimension] for which a subset of resources are required.
-     * @param resources List of [Resource]s to be restricted.
+     * @param xValue The value to be examined in the experiment, can be load (demand metric) or resource (capacity metric).
+     * @param yValues List of values to be restricted, can be resources (demand metric) or loads (capacity metric).
      * @return Returns a list containing only elements that have not been filtered out by the
      * restriction (possibly empty).
      */
-    abstract fun apply(load: LoadDimension, resources: List<Resource>): List<Resource>
+    abstract fun apply(xValue: Int, yValues: List<Int>): List<Int>
 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
index 28e8194c699cd074026c8cb7e6f3ce4ec347023b..6e56c3b36c6e2889e4714c890a424e4f6765386e 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
@@ -2,8 +2,6 @@ package theodolite.strategies.searchstrategy
 
 import mu.KotlinLogging
 import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 
 private val logger = KotlinLogging.logger {}
 
@@ -13,48 +11,97 @@ private val logger = KotlinLogging.logger {}
  * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
  */
 class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
-    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
-        val result = binarySearch(load, resources, 0, resources.size - 1)
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
+        val result = binarySearchDemand(load, resources, 0, resources.size - 1)
         if (result == -1) {
             return null
         }
         return resources[result]
     }
 
+    override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? {
+        val result = binarySearchCapacity(resource, loads, 0, loads.size - 1)
+        if (result == -1) {
+            return null
+        }
+        return loads[result]
+    }
+
     /**
-     * Apply binary search.
+     * Apply binary search for the demand metric.
      *
-     * @param load the load dimension to perform experiments for
-     * @param resources the list in which binary search is performed
-     * @param lower lower bound for binary search (inclusive)
-     * @param upper upper bound for binary search (inclusive)
+     * @param load the load to perform experiments for.
+     * @param resources the list of resources in which binary search is performed.
+     * @param lower lower bound for binary search (inclusive).
+     * @param upper upper bound for binary search (inclusive).
      */
-    private fun binarySearch(load: LoadDimension, resources: List<Resource>, lower: Int, upper: Int): Int {
+    private fun binarySearchDemand(load: Int, resources: List<Int>, lower: Int, upper: Int): Int {
         if (lower > upper) {
             throw IllegalArgumentException()
         }
-        // special case:  length == 1 or 2
+        // special case:  length == 1, so lower and upper bounds are the same
         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
+            logger.info { "Running experiment with load '$load' and resource '$res'" }
+            if (this.benchmarkExecutor.runExperiment(load, res)) return lower
             else {
                 if (lower + 1 == resources.size) return -1
                 return lower + 1
             }
         } else {
             // apply binary search for a list with
-            // length > 2 and adjust upper and lower depending on the result for `resources[mid]`
+            // 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])) {
+            logger.info { "Running experiment with load '$load' and resource '$res'" }
+            if (this.benchmarkExecutor.runExperiment(load, res)) {
+                // case length = 2
                 if (mid == lower) {
                     return lower
                 }
-                return binarySearch(load, resources, lower, mid - 1)
+                return binarySearchDemand(load, resources, lower, mid - 1)
+            } else {
+                return binarySearchDemand(load, resources, mid + 1, upper)
+            }
+        }
+    }
+
+
+    /**
+     * Apply binary search for the capacity metric.
+     *
+     * @param resource the resource to perform experiments for.
+     * @param loads the list of loads in which binary search is performed.
+     * @param lower lower bound for binary search (inclusive).
+     * @param upper upper bound for binary search (inclusive).
+     */
+    private fun binarySearchCapacity(resource: Int, loads: List<Int>, lower: Int, upper: Int): Int {
+        if (lower > upper) {
+            throw IllegalArgumentException()
+        }
+        // length = 1, so lower and upper bounds are the same
+        if (lower == upper) {
+            val load = loads[lower]
+            logger.info { "Running experiment with load '$load' and resource '$resource'" }
+            if (this.benchmarkExecutor.runExperiment(load, resource)) return lower
+            else {
+                if (lower + 1 == loads.size) return -1
+                return lower - 1
+            }
+        } else {
+            // 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 + 1) / 2 //round to next int
+            val load = loads[mid]
+            logger.info { "Running experiment with load '$load' and resource '$resource'" }
+            if (this.benchmarkExecutor.runExperiment(load, resource)) {
+                // length = 2, so since we round down mid is equal to lower
+                if (mid == upper) {
+                    return upper
+                }
+                return binarySearchCapacity(resource, loads, mid + 1, upper)
             } else {
-                return binarySearch(load, resources, mid + 1, upper)
+                return binarySearchCapacity(resource, loads, lower, mid - 1)
             }
         }
     }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/CompositeStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/CompositeStrategy.kt
deleted file mode 100644
index d6ace6f564239e73a0d59f8eb7900f50018482c5..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/CompositeStrategy.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package theodolite.strategies.searchstrategy
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.execution.BenchmarkExecutor
-import theodolite.strategies.restriction.RestrictionStrategy
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-
-/**
- *  Composite strategy that combines a SearchStrategy and a set of RestrictionStrategy.
- *
- * @param searchStrategy the [SearchStrategy] that is executed as part of this [CompositeStrategy].
- * @param restrictionStrategies the set of [RestrictionStrategy] that are connected conjunctive to restrict the [Resource]
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
- */
-@RegisterForReflection
-class CompositeStrategy(
-    benchmarkExecutor: BenchmarkExecutor,
-    private val searchStrategy: SearchStrategy,
-    val restrictionStrategies: Set<RestrictionStrategy>
-) : SearchStrategy(benchmarkExecutor) {
-
-    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
-        var restrictedResources = resources.toList()
-        for (strategy in this.restrictionStrategies) {
-            restrictedResources = restrictedResources.intersect(strategy.apply(load, resources).toSet()).toList()
-        }
-        return this.searchStrategy.findSuitableResource(load, restrictedResources)
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
index 83c4abbdf44f1a1c2f3a27714d796580feedee49..6af6aa1602d18a089b9450f6e1eb84bca8edafa3 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
@@ -2,25 +2,24 @@ 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.
+ * [SearchStrategy] that executes an experiment for a load and a resource list (demand metric) or for a resource and a
+ * load list (capacity metric) in a linear-search-like fashion, but **without stopping** once the desired
+ * resource (demand) or load (capacity) is found.
  *
- * @see LinearSearch for a SearchStrategy that stops once a suitable resource amount is found.
+ * @see LinearSearch for a SearchStrategy that stops once the desired resource (demand) or load (capacity) 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
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
+        var minimalSuitableResources: Int? = null
         for (res in resources) {
-            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
+            logger.info { "Running experiment with load '$load' and resources '$res'" }
             val result = this.benchmarkExecutor.runExperiment(load, res)
             if (result && minimalSuitableResources == null) {
                 minimalSuitableResources = res
@@ -28,4 +27,13 @@ class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmar
         }
         return minimalSuitableResources
     }
+
+    override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? {
+        var maxSuitableLoad: Int? = null
+        for (load in loads) {
+            logger.info { "Running experiment with resources '$resource' and load '$load'" }
+            if (this.benchmarkExecutor.runExperiment(load, resource)) maxSuitableLoad = load
+        }
+        return maxSuitableLoad
+    }
 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
index 786a3baf159e94841c1f76c696f030718e8f768f..f243b8e4076d0cf0d2ef23bdd6b02b5da2d34152 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
@@ -1,22 +1,22 @@
 package theodolite.strategies.searchstrategy
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.Resource
 
 /**
  * Base class for the implementation of Guess strategies. Guess strategies are strategies to determine the resource
- * demand we start with in our initial guess search strategy.
+ * demand (demand metric) or load (capacity metric) we start with in our initial guess search strategy.
  */
 
 @RegisterForReflection
 abstract class GuessStrategy {
     /**
-     * Computing the resource demand for the initial guess search strategy to start with.
+     * Computing the resource demand (demand metric) or load (capacity metric) for the initial guess search strategy
+     * to start with.
      *
-     * @param resources List of all possible [Resource]s.
-     * @param lastLowestResource Previous resource demand needed for the given load.
+     * @param valuesToCheck List of all possible resources/loads.
+     * @param lastOptValue Previous minimal/maximal resource/load value for the given load/resource.
      *
-     * @return Returns the resource demand to start the initial guess search strategy with or null
+     * @return the resource/load to start the initial guess search strategy with or null
      */
-    abstract fun firstGuess(resources: List<Resource>, lastLowestResource: Resource?): Resource?
+    abstract fun firstGuess(valuesToCheck: List<Int>, lastOptValue: Int?): Int?
 }
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt
index d97fb62cc9d37dd50122199e5d089c491784e511..447d810942be74f0cdbee865e3f0bb5d58e61603 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt
@@ -2,8 +2,6 @@ package theodolite.strategies.searchstrategy
 
 import mu.KotlinLogging
 import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 import theodolite.util.Results
 
 private val logger = KotlinLogging.logger {}
@@ -16,42 +14,28 @@ private val logger = KotlinLogging.logger {}
  * @param guessStrategy Strategy that provides us with a guess for the first resource amount.
  * @param results current results of all previously performed benchmarks.
  */
-class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStrategy: GuessStrategy, results: Results) :
-        SearchStrategy(benchmarkExecutor, guessStrategy, results) {
+class InitialGuessSearchStrategy(
+        benchmarkExecutor: BenchmarkExecutor,
+        private val guessStrategy: GuessStrategy,
+        private var results: Results
+) : SearchStrategy(benchmarkExecutor) {
 
-    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
-
-        if(resources.isEmpty()) {
-            logger.info { "You need to specify resources to be checked for the InitialGuessSearchStrategy to work." }
-            return null
-        }
-
-        if(guessStrategy == null){
-            logger.info { "Your InitialGuessSearchStrategy doesn't have a GuessStrategy. This is not supported." }
-            return null
-        }
-
-        if(results == null){
-            logger.info { "The results need to be initialized." }
-            return null
-        }
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
 
-
-        var lastLowestResource : Resource? = null
+        var lastLowestResource : Int? = null
 
         // Getting the lastLowestResource from results and calling firstGuess() with it
         if (!results.isEmpty()) {
-            val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load)
-            lastLowestResource = this.results.getMinRequiredInstances(maxLoad)
-            if (lastLowestResource.get() == Int.MAX_VALUE) lastLowestResource = null
+            val maxLoad: Int? = this.results.getMaxBenchmarkedXDimensionValue(load)
+            lastLowestResource = this.results.getOptYDimensionValue(maxLoad)
         }
         lastLowestResource = this.guessStrategy.firstGuess(resources, lastLowestResource)
 
         if (lastLowestResource != null) {
-            val resourcesToCheck: List<Resource>
+            val resourcesToCheck: List<Int>
             val startIndex: Int = resources.indexOf(lastLowestResource)
 
-            logger.info { "Running experiment with load '${load.get()}' and resources '${lastLowestResource.get()}'" }
+            logger.info { "Running experiment with load '$load' and resources '$lastLowestResource'" }
 
             // If the first experiment passes, starting downward linear search
             // otherwise starting upward linear search
@@ -60,10 +44,10 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra
                 resourcesToCheck = resources.subList(0, startIndex).reversed()
                 if (resourcesToCheck.isEmpty()) return lastLowestResource
 
-                var currentMin: Resource = lastLowestResource
+                var currentMin: Int = lastLowestResource
                 for (res in resourcesToCheck) {
 
-                    logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
+                    logger.info { "Running experiment with load '$load' and resources '$res'" }
                     if (this.benchmarkExecutor.runExperiment(load, res)) {
                         currentMin = res
                     }
@@ -79,14 +63,69 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra
 
                 for (res in resourcesToCheck) {
 
-                    logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
+                    logger.info { "Running experiment with load '$load' and resources '$res'" }
                     if (this.benchmarkExecutor.runExperiment(load, res)) return res
                 }
             }
         }
         else {
-            logger.info { "InitialGuessSearchStrategy called without lastLowestResource value, which is needed as a " +
-                    "starting point!" }
+            logger.info { "lastLowestResource was null." }
+        }
+        return null
+    }
+
+    override fun findSuitableLoad(resource: Int, loads: List<Int>): Int?{
+
+        var lastMaxLoad : Int? = null
+
+        // Getting the lastLowestLoad from results and calling firstGuess() with it
+        if (!results.isEmpty()) {
+            val maxResource: Int? = this.results.getMaxBenchmarkedXDimensionValue(resource)
+            lastMaxLoad = this.results.getOptYDimensionValue(maxResource)
+        }
+        lastMaxLoad = this.guessStrategy.firstGuess(loads, lastMaxLoad)
+
+        if (lastMaxLoad != null) {
+            val loadsToCheck: List<Int>
+            val startIndex: Int = loads.indexOf(lastMaxLoad)
+
+            logger.info { "Running experiment with resource '$resource' and load '$lastMaxLoad'" }
+
+            // If the first experiment passes, starting upwards linear search
+            // otherwise starting downward linear search
+            if (!this.benchmarkExecutor.runExperiment(lastMaxLoad, resource)) {
+                // downward search
+
+                loadsToCheck = loads.subList(0, startIndex).reversed()
+                if (loadsToCheck.isNotEmpty()) {
+                    for (load in loadsToCheck) {
+
+                        logger.info { "Running experiment with resource '$resource' and load '$load'" }
+                        if (this.benchmarkExecutor.runExperiment(load, resource)) {
+                            return load
+                        }
+                    }
+                }
+            }
+            else {
+                // upward search
+                if (loads.size <= startIndex + 1) {
+                    return lastMaxLoad
+                }
+                loadsToCheck = loads.subList(startIndex + 1, loads.size)
+
+                var currentMax: Int = lastMaxLoad
+                for (load in loadsToCheck) {
+                    logger.info { "Running experiment with resource '$resource' and load '$load'" }
+                    if (this.benchmarkExecutor.runExperiment(load, resource)) {
+                        currentMax = load
+                    }
+                }
+                return currentMax
+            }
+        }
+        else {
+            logger.info { "lastMaxLoad was null." }
         }
         return null
     }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
index 85deaf6fa75437199bfc560404eb5b40bb4a986a..1991431a970e44bf70eccf834a2ecb0221502a71 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
@@ -2,24 +2,33 @@ 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.
+ *  Linear-search-like implementation for determining the smallest/biggest suitable number of resources/loads,
+ *  depending on the metric.
  *
  * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
  */
 class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
 
-    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
         for (res in resources) {
-
-            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
+            logger.info { "Running experiment with load '$load' and resources '$res'" }
             if (this.benchmarkExecutor.runExperiment(load, res)) return res
         }
         return null
     }
+
+    override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? {
+        var maxSuitableLoad: Int? = null
+        for (load in loads) {
+            logger.info { "Running experiment with resources '$resource' and load '$load'" }
+            if (this.benchmarkExecutor.runExperiment(load, resource)) {
+                maxSuitableLoad = load
+            } else break
+        }
+        return maxSuitableLoad
+    }
 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevInstanceOptGuess.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevInstanceOptGuess.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c919b475995a6a5366371336041d9633f0aa1993
--- /dev/null
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevInstanceOptGuess.kt
@@ -0,0 +1,28 @@
+package theodolite.strategies.searchstrategy
+
+
+/**
+ * [PrevInstanceOptGuess] is a [GuessStrategy] that implements the function [firstGuess],
+ * where it returns the optimal result of the previous run.
+ */
+
+class PrevInstanceOptGuess() : GuessStrategy(){
+
+    /**
+     * If the metric is
+     *
+     * - "demand", [valuesToCheck] is a List of resources and [lastOptValue] a resource value.
+     * - "capacity", [valuesToCheck] is a List of loads and [lastOptValue] a load value.
+     *
+     * @param valuesToCheck List of all possible resources/loads.
+     * @param lastOptValue Previous minimal/maximal resource/load value for the given load/resource.
+     *
+     * @return the value of [lastOptValue] if given otherwise the first element of the [valuesToCheck] list or null
+     */
+    override fun firstGuess(valuesToCheck: List<Int>, lastOptValue: Int?): Int? {
+
+        if (lastOptValue != null) return lastOptValue
+        else if(valuesToCheck.isNotEmpty()) return valuesToCheck[0]
+        else return null
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt
deleted file mode 100644
index 413eecea27279cd79bad155fbb7d5d18b674a12e..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package theodolite.strategies.searchstrategy
-
-import theodolite.util.Resource
-
-/**
- * This Guess strategy takes the minimal resource demand of the previous load, which is given as an argument for the
- * firstGuess function.
- */
-
-class PrevResourceMinGuess() : GuessStrategy(){
-
-    /**
-     * @param resources List of all possible [Resource]s.
-     * @param lastLowestResource Previous resource demand needed for the given load.
-     *
-     * @return the value of lastLowestResource if given otherwise the first element of the resource list or null
-     */
-    override fun firstGuess(resources: List<Resource>, lastLowestResource: Resource?): Resource? {
-
-        if (lastLowestResource != null) return lastLowestResource
-        else if(resources.isNotEmpty()) return resources[0]
-        else return null
-    }
-}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0a136d6ff43e6f62fc5ebe34c392816da3592bf1
--- /dev/null
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt
@@ -0,0 +1,43 @@
+package theodolite.strategies.searchstrategy
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+import theodolite.execution.BenchmarkExecutor
+import theodolite.strategies.restriction.RestrictionStrategy
+
+/**
+ *  Strategy that combines a SearchStrategy and a set of RestrictionStrategy.
+ *
+ * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
+ * @param searchStrategy the [SearchStrategy] that is executed as part of this [RestrictionSearch].
+ * @param restrictionStrategies the set of [RestrictionStrategy] that are connected conjunctive to restrict the Resource.
+ *
+ */
+@RegisterForReflection
+class RestrictionSearch(
+    benchmarkExecutor: BenchmarkExecutor,
+    private val searchStrategy: SearchStrategy,
+    private val restrictionStrategies: Set<RestrictionStrategy>
+) : SearchStrategy(benchmarkExecutor) {
+
+    /**
+     * Restricting the possible resources and calling findSuitableResource of the given [SearchStrategy].
+     */
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
+        var restrictedResources = resources
+        for (strategy in this.restrictionStrategies) {
+            restrictedResources = restrictedResources.intersect(strategy.apply(load, resources).toSet()).toList()
+        }
+        return this.searchStrategy.findSuitableResource(load, restrictedResources)
+    }
+
+    /**
+     * Restricting the possible loads and calling findSuitableLoad of the given [SearchStrategy].
+     */
+    override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? {
+        var restrictedLoads = loads
+        for (strategy in this.restrictionStrategies) {
+            restrictedLoads = restrictedLoads.intersect(strategy.apply(resource, loads).toSet()).toList()
+        }
+        return this.searchStrategy.findSuitableLoad(resource, restrictedLoads)
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
index 97c723f2cfe459081cbb327f6860e48319c8f4f1..962504c7d85fa5e28d73fe0cb9d844ed2be66a99 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
+++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
@@ -2,27 +2,63 @@ package theodolite.strategies.searchstrategy
 
 import io.quarkus.runtime.annotations.RegisterForReflection
 import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import theodolite.strategies.Metric
 import theodolite.util.Results
 
 /**
- *  Base class for the implementation for SearchStrategies. SearchStrategies determine the smallest suitable number of instances.
+ *  Base class for the implementation for SearchStrategies. SearchStrategies determine the smallest suitable number
+ *  of resources/loads for a load/resource (depending on the metric).
  *
  * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
  * @param guessStrategy Guess strategy for the initial resource amount in case the InitialGuessStrategy is selected.
  * @param results the [Results] object.
  */
 @RegisterForReflection
-abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor, val guessStrategy: GuessStrategy? = null,
-                              val results: Results? = null) {
+abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor) {
+
+
+    /**
+     * Calling findSuitableResource or findSuitableLoad for each load/resource depending on the chosen metric.
+     *
+     * @param loads List of possible loads for the experiments.
+     * @param resources List of possible resources for the experiments.
+     * @param metric The [Metric] for the experiments, either "demand" or "capacity".
+     */
+    fun applySearchStrategyByMetric(loads: List<Int>, resources: List<Int>, metric: Metric) {
+
+        when(metric) {
+            Metric.DEMAND ->
+                for (load in loads) {
+                    if (benchmarkExecutor.run.get()) {
+                        this.findSuitableResource(load, resources)
+                    }
+                }
+            Metric.CAPACITY ->
+                for (resource in resources) {
+                    if (benchmarkExecutor.run.get()) {
+                        this.findSuitableLoad(resource, loads)
+                    }
+                }
+        }
+    }
+
     /**
-     * Find smallest suitable resource from the specified resource list for the given load.
+     * Find the smallest suitable resource from the specified resource list for the given load.
      *
-     * @param load the [LoadDimension] to be tested.
-     * @param resources List of all possible [Resource]s.
+     * @param load the load to be tested.
+     * @param resources List of all possible resources.
      *
      * @return suitable resource for the specified load, or null if no suitable resource exists.
      */
-    abstract fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource?
+    abstract fun findSuitableResource(load: Int, resources: List<Int>): Int?
+
+    /**
+     * Find the biggest suitable load from the specified load list for the given resource amount.
+     *
+     * @param resource the resource to be tested.
+     * @param loads List of all possible loads.
+     *
+     * @return suitable load for the specified resource amount, or null if no suitable load exists.
+     */
+    abstract fun findSuitableLoad(resource: Int, loads: List<Int>) : Int?
 }
diff --git a/theodolite/src/main/kotlin/theodolite/util/Config.kt b/theodolite/src/main/kotlin/theodolite/util/Config.kt
index afbf784e9d6d72939615e367b54891ecd95a3608..675caea5fbd3b8e8c699019e10f43c36b9fbaebe 100644
--- a/theodolite/src/main/kotlin/theodolite/util/Config.kt
+++ b/theodolite/src/main/kotlin/theodolite/util/Config.kt
@@ -1,18 +1,23 @@
 package theodolite.util
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.strategies.searchstrategy.CompositeStrategy
+import theodolite.strategies.Metric
+import theodolite.strategies.searchstrategy.SearchStrategy
 
 /**
  * Config class that represents a configuration of a theodolite run.
  *
- * @param loads the [LoadDimension] of the execution
- * @param resources the [Resource] of the execution
- * @param compositeStrategy the [CompositeStrategy] of the execution
+ * @param loads the possible loads of the execution
+ * @param resources the possible resources of the execution
+ * @param searchStrategy the [SearchStrategy] of the execution
+ * @param metric the Metric of the execution
  */
 @RegisterForReflection
 data class Config(
-    val loads: List<LoadDimension>,
-    val resources: List<Resource>,
-    val compositeStrategy: CompositeStrategy
+        val loads: List<Int>,
+        val loadPatcherDefinitions : List<PatcherDefinition>,
+        val resources: List<Int>,
+        val resourcePatcherDefinitions : List<PatcherDefinition>,
+        val searchStrategy: SearchStrategy,
+        val metric: Metric
 )
diff --git a/theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt b/theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt
deleted file mode 100644
index cf26da979b05f0a2bd82289ce371715ea0d67c93..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package theodolite.util
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-
-/**
- * Representation of the load dimensions for a execution of theodolite.
- *
- * @param number the value of this [LoadDimension]
- * @param type [PatcherDefinition] of this [LoadDimension]
- */
-@RegisterForReflection
-data class LoadDimension(private val number: Int, private val type: List<PatcherDefinition>) {
-    /**
-     * @return the value of this load dimension.
-     */
-    fun get(): Int {
-        return this.number
-    }
-
-    /**
-     * @return the list of [PatcherDefinition]
-     */
-    fun getType(): List<PatcherDefinition> {
-        return this.type
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/util/Resource.kt b/theodolite/src/main/kotlin/theodolite/util/Resource.kt
deleted file mode 100644
index 1d6410aa4288e19817e3ba48bfd1bc0d85d006a2..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/util/Resource.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package theodolite.util
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-
-/**
- * Representation of the resources for an execution of Theodolite.
- */
-@RegisterForReflection
-data class Resource(private val number: Int, private val type: List<PatcherDefinition>) {
-
-    /**
-     * @return the value of this resource.
-     */
-    fun get(): Int {
-        return this.number
-    }
-
-    /**
-     * @return the list of [PatcherDefinition]
-     */
-    fun getType(): List<PatcherDefinition> {
-        return this.type
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/util/Results.kt b/theodolite/src/main/kotlin/theodolite/util/Results.kt
index 2221c2e64f6dbc1776122f20793aa8d04d621d9d..418ac50f285996affd7db1c15fc44a22f1677d29 100644
--- a/theodolite/src/main/kotlin/theodolite/util/Results.kt
+++ b/theodolite/src/main/kotlin/theodolite/util/Results.kt
@@ -1,6 +1,7 @@
 package theodolite.util
 
 import io.quarkus.runtime.annotations.RegisterForReflection
+import theodolite.strategies.Metric
 
 /**
  * Central class that saves the state of an execution of Theodolite. For an execution, it is used to save the result of
@@ -8,80 +9,111 @@ import io.quarkus.runtime.annotations.RegisterForReflection
  * perform the [theodolite.strategies.restriction.RestrictionStrategy].
  */
 @RegisterForReflection
-class Results {
-    private val results: MutableMap<Pair<LoadDimension, Resource>, Boolean> = mutableMapOf()
+class Results (val metric: Metric) {
+    // (load, resource) -> Boolean map
+    private val results: MutableMap<Pair<Int, Int>, Boolean> = mutableMapOf()
+
+    // if metric is "demand"  : load     -> resource
+    // if metric is "capacity": resource -> load
+    private var optInstances: MutableMap<Int, Int> = mutableMapOf()
+
 
     /**
-     * Set the result for an experiment.
+     * Set the result for an experiment and update the [optInstances] list accordingly.
      *
-     * @param experiment A pair that identifies the experiment by the [LoadDimension] and [Resource].
+     * @param experiment A pair that identifies the experiment by the Load and Resource.
      * @param successful the result of the experiment. Successful == true and Unsuccessful == false.
      */
-    fun setResult(experiment: Pair<LoadDimension, Resource>, successful: Boolean) {
+    fun setResult(experiment: Pair<Int, Int>, successful: Boolean) {
         this.results[experiment] = successful
+
+        when (metric) {
+            Metric.DEMAND ->
+                if (successful) {
+                    if (optInstances.containsKey(experiment.first)) {
+                        if (optInstances[experiment.first]!! > experiment.second) {
+                            optInstances[experiment.first] = experiment.second
+                        }
+                    } else {
+                        optInstances[experiment.first] = experiment.second
+                    }
+                } else if (!optInstances.containsKey(experiment.first)) {
+                    optInstances[experiment.first] = Int.MAX_VALUE
+                }
+            Metric.CAPACITY ->
+                if (successful) {
+                    if (optInstances.containsKey(experiment.second)) {
+                        if (optInstances[experiment.second]!! < experiment.first) {
+                            optInstances[experiment.second] = experiment.first
+                        }
+                    } else {
+                        optInstances[experiment.second] = experiment.first
+                    }
+                } else if (!optInstances.containsKey(experiment.second)) {
+                    optInstances[experiment.second] = Int.MIN_VALUE
+                }
+        }
     }
 
     /**
      * Get the result for an experiment.
      *
-     * @param experiment A pair that identifies the experiment by the [LoadDimension] and [Resource].
+     * @param experiment A pair that identifies the experiment by the Load and Resource.
      * @return true if the experiment was successful and false otherwise. If the result has not been reported so far,
      * null is returned.
      *
-     * @see Resource
      */
-    fun getResult(experiment: Pair<LoadDimension, Resource>): Boolean? {
+    fun getResult(experiment: Pair<Int, Int>): Boolean? {
         return this.results[experiment]
     }
 
     /**
-     * Get the smallest suitable number of instances for a specified [LoadDimension].
+     * Get the smallest suitable number of instances for a specified x-Value.
+     * The x-Value corresponds to the...
+     * - load, if the metric is "demand".
+     * - resource, if the metric is "capacity".
      *
-     * @param load the [LoadDimension]
+     * @param xValue the Value of the x-dimension of the current metric
      *
-     * @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
-     * yet, a Resource with the constant value Int.MIN_VALUE is returned.
+     * @return the smallest suitable number of resources/loads (depending on metric).
+     * If there is no experiment that has been executed yet, there is no experiment
+     * for the given [xValue] or there is none marked successful yet, null is returned.
      */
-    fun getMinRequiredInstances(load: LoadDimension?): Resource {
-        if (this.results.isEmpty()) {
-            return Resource(Int.MIN_VALUE, emptyList())
-        }
-
-        var minRequiredInstances = Resource(Int.MAX_VALUE, emptyList())
-        for (experiment in results) {
-            // Get all successful experiments for requested load
-            if (experiment.key.first == load && experiment.value) {
-                if (experiment.key.second.get() < minRequiredInstances.get()) {
-                    // Found new smallest resources
-                    minRequiredInstances = experiment.key.second
-                }
+    fun getOptYDimensionValue(xValue: Int?): Int? {
+        if (xValue != null) {
+            val res = optInstances[xValue]
+            if (res != Int.MAX_VALUE && res != Int.MIN_VALUE) {
+                return res
             }
         }
-        return minRequiredInstances
+        return null
     }
 
     /**
-     * Get the largest [LoadDimension] that has been reported executed successfully (or unsuccessfully) so far, for a
-     * [LoadDimension] and is smaller than the given [LoadDimension].
+     * Get the largest x-Value that has been tested and reported so far (successful or unsuccessful),
+     * which is smaller than the specified x-Value.
+     *
+     * The x-Value corresponds to the...
+     * - load, if the metric is "demand".
+     * - resource, if the metric is "capacity".
      *
-     * @param load the [LoadDimension]
+     * @param xValue the Value of the x-dimension of the current metric
      *
-     * @return the largest [LoadDimension] or null, if there is none for this [LoadDimension]
+     * @return the largest tested x-Value or null, if there wasn't any tested which is smaller than the [xValue].
      */
-    fun getMaxBenchmarkedLoad(load: LoadDimension): LoadDimension? {
-        var maxBenchmarkedLoad: LoadDimension? = null
-        for (experiment in results) {
-            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
+    fun getMaxBenchmarkedXDimensionValue(xValue: Int): Int? {
+        var maxBenchmarkedXValue: Int? = null
+        for (instance in optInstances) {
+            val instanceXValue= instance.key
+            if (instanceXValue <= xValue) {
+                if (maxBenchmarkedXValue == null) {
+                    maxBenchmarkedXValue = instanceXValue
+                } else if (maxBenchmarkedXValue < instanceXValue) {
+                    maxBenchmarkedXValue = instanceXValue
                 }
             }
         }
-        return maxBenchmarkedLoad
+        return maxBenchmarkedXValue
     }
 
     /**
diff --git a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt b/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
index 1af6f548b219697009c688ace712a9f7f5620bd0..de7a1f8f170bb4c25aeb328d3f68e3a027712a62 100644
--- a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
@@ -5,11 +5,10 @@ import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Test
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.strategies.searchstrategy.InitialGuessSearchStrategy
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import theodolite.strategies.Metric
 import theodolite.util.Results
 import mu.KotlinLogging
-import theodolite.strategies.searchstrategy.PrevResourceMinGuess
+import theodolite.strategies.searchstrategy.PrevInstanceOptGuess
 
 private val logger = KotlinLogging.logger {}
 
@@ -27,23 +26,23 @@ class InitialGuessSearchStrategyTest {
             arrayOf(false, false, false, false, false, false, true),
             arrayOf(false, false, false, false, false, false, false)
         )
-        val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
         val benchmark = TestBenchmark()
-        val guessStrategy = PrevResourceMinGuess()
+        val guessStrategy = PrevInstanceOptGuess()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
         val strategy = InitialGuessSearchStrategy(benchmarkExecutor,guessStrategy, results)
 
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
+        val actual: ArrayList<Int?> = ArrayList()
+        val expected: ArrayList<Int?> = ArrayList(listOf(0, 2, 2, 3, 4, 6))
         expected.add(null)
 
         for (load in mockLoads) {
-            val returnVal : Resource? = strategy.findSuitableResource(load, mockResources)
+            val returnVal : Int? = strategy.findSuitableResource(load, mockResources)
             if(returnVal != null) {
-                logger.info { "returnVal '${returnVal.get()}'" }
+                logger.info { "returnVal '${returnVal}'" }
             }
             else {
                 logger.info { "returnVal is null." }
@@ -65,23 +64,23 @@ class InitialGuessSearchStrategyTest {
             arrayOf(false, false, false, false, false, false, true),
             arrayOf(false, false, false, false, false, false, false)
         )
-        val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
         val benchmark = TestBenchmark()
-        val guessStrategy = PrevResourceMinGuess()
+        val guessStrategy = PrevInstanceOptGuess()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
         val strategy = InitialGuessSearchStrategy(benchmarkExecutor,guessStrategy, results)
 
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 1, 4, 6).map { x -> Resource(x, emptyList()) })
+        val actual: ArrayList<Int?> = ArrayList()
+        val expected: ArrayList<Int?> = ArrayList(listOf(0, 2, 2, 1, 4, 6))
         expected.add(null)
 
         for (load in mockLoads) {
-            val returnVal : Resource? = strategy.findSuitableResource(load, mockResources)
+            val returnVal : Int? = strategy.findSuitableResource(load, mockResources)
             if(returnVal != null) {
-                logger.info { "returnVal '${returnVal.get()}'" }
+                logger.info { "returnVal '${returnVal}'" }
             }
             else {
                 logger.info { "returnVal is null." }
@@ -103,24 +102,24 @@ class InitialGuessSearchStrategyTest {
                 arrayOf(false, false, false, false, false, false, true),
                 arrayOf(false, false, false, false, false, false, false)
         )
-        val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
         val benchmark = TestBenchmark()
-        val guessStrategy = PrevResourceMinGuess()
+        val guessStrategy = PrevInstanceOptGuess()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
         val strategy = InitialGuessSearchStrategy(benchmarkExecutor, guessStrategy, results)
 
-        val actual: ArrayList<Resource?> = ArrayList()
-        var expected: ArrayList<Resource?> = ArrayList(listOf(2, 3, 0, 4, 6).map { x -> Resource(x, emptyList()) })
+        val actual: ArrayList<Int?> = ArrayList()
+        var expected: ArrayList<Int?> = ArrayList(listOf(2, 3, 0, 4, 6))
         expected.add(null)
         expected = ArrayList(listOf(null) + expected)
 
         for (load in mockLoads) {
-            val returnVal : Resource? = strategy.findSuitableResource(load, mockResources)
+            val returnVal : Int? = strategy.findSuitableResource(load, mockResources)
             if(returnVal != null) {
-                logger.info { "returnVal '${returnVal.get()}'" }
+                logger.info { "returnVal '${returnVal}'" }
             }
             else {
                 logger.info { "returnVal is null." }
diff --git a/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt b/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt
similarity index 56%
rename from theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt
rename to theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt
index 580d9e747bde687a91ffb1bce2e7c9dfb6f166a2..1e973852d8448d0bff3410d5bb84bc5543be497a 100644
--- a/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt
@@ -4,19 +4,20 @@ import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Test
 import theodolite.benchmark.BenchmarkExecution
+import theodolite.strategies.Metric
 import theodolite.strategies.restriction.LowerBoundRestriction
 import theodolite.strategies.searchstrategy.BinarySearch
-import theodolite.strategies.searchstrategy.CompositeStrategy
+import theodolite.strategies.searchstrategy.FullSearch
+import theodolite.strategies.searchstrategy.RestrictionSearch
 import theodolite.strategies.searchstrategy.LinearSearch
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 import theodolite.util.Results
 
 @QuarkusTest
-class CompositeStrategyTest {
+class RestrictionSearchTest {
+
 
     @Test
-    fun testEnd2EndLinearSearch() {
+    fun restrictionSearchTestLinearSearch() {
         val mockResults = arrayOf(
             arrayOf(true, true, true, true, true, true, true),
             arrayOf(false, false, true, true, true, true, true),
@@ -26,19 +27,52 @@ class CompositeStrategyTest {
             arrayOf(false, false, false, false, false, false, true),
             arrayOf(false, false, false, false, false, false, false)
         )
-        val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
         val benchmark = TestBenchmark()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
         val linearSearch = LinearSearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
-            CompositeStrategy(benchmarkExecutor, linearSearch, setOf(lowerBoundRestriction))
+            RestrictionSearch(benchmarkExecutor, linearSearch, setOf(lowerBoundRestriction))
+
+        val actual: ArrayList<Int?> = ArrayList()
+        val expected: ArrayList<Int?> = ArrayList(listOf(0, 2, 2, 3, 4, 6))
+        expected.add(null)
+
+        for (load in mockLoads) {
+            actual.add(strategy.findSuitableResource(load, mockResources))
+        }
+
+        assertEquals(actual, expected)
+    }
+
+    @Test
+    fun restrictionSearchTestFullSearch() {
+        val mockResults = arrayOf(
+                arrayOf(true, true, true, true, true, true, true),
+                arrayOf(false, false, true, true, true, true, true),
+                arrayOf(false, false, true, true, true, true, true),
+                arrayOf(false, false, false, true, true, true, true),
+                arrayOf(false, false, false, false, true, true, true),
+                arrayOf(false, false, false, false, false, false, true),
+                arrayOf(false, false, false, false, false, false, false)
+        )
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
+        val benchmark = TestBenchmark()
+        val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
+        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val fullSearch = FullSearch(benchmarkExecutor)
+        val lowerBoundRestriction = LowerBoundRestriction(results)
+        val strategy =
+                RestrictionSearch(benchmarkExecutor, fullSearch, setOf(lowerBoundRestriction))
 
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
+        val actual: ArrayList<Int?> = ArrayList()
+        val expected: ArrayList<Int?> = ArrayList(listOf(0, 2, 2, 3, 4, 6))
         expected.add(null)
 
         for (load in mockLoads) {
@@ -49,7 +83,7 @@ class CompositeStrategyTest {
     }
 
     @Test
-    fun testEnd2EndBinarySearch() {
+    fun restrictionSearchTestBinarySearch() {
         val mockResults = arrayOf(
             arrayOf(true, true, true, true, true, true, true),
             arrayOf(false, false, true, true, true, true, true),
@@ -59,20 +93,19 @@ class CompositeStrategyTest {
             arrayOf(false, false, false, false, false, false, true),
             arrayOf(false, false, false, false, false, false, false)
         )
-        val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
         val benchmark = TestBenchmark()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutorImpl =
             TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 0)
         val binarySearch = BinarySearch(benchmarkExecutorImpl)
         val lowerBoundRestriction = LowerBoundRestriction(results)
-        val strategy =
-            CompositeStrategy(benchmarkExecutorImpl, binarySearch, setOf(lowerBoundRestriction))
+        val strategy = RestrictionSearch(benchmarkExecutorImpl, binarySearch, setOf(lowerBoundRestriction))
 
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
+        val actual: ArrayList<Int?> = ArrayList()
+        val expected: ArrayList<Int?> = ArrayList(listOf(0, 2, 2, 3, 4, 6))
         expected.add(null)
 
         for (load in mockLoads) {
@@ -83,7 +116,7 @@ class CompositeStrategyTest {
     }
 
     @Test
-    fun testEnd2EndBinarySearch2() {
+    fun restrictionSearchTestBinarySearch2() {
         val mockResults = arrayOf(
             arrayOf(true, true, true, true, true, true, true, true),
             arrayOf(false, false, true, true, true, true, true, true),
@@ -93,20 +126,20 @@ class CompositeStrategyTest {
             arrayOf(false, false, false, false, false, false, true, true),
             arrayOf(false, false, false, false, false, false, false, true)
         )
-        val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..7).map { number -> Resource(number, emptyList()) }
-        val results = Results()
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..7).toList()
+        val results = Results(Metric.from("demand"))
         val benchmark = TestBenchmark()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 0)
         val binarySearch = BinarySearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
-            CompositeStrategy(benchmarkExecutor, binarySearch, setOf(lowerBoundRestriction))
+            RestrictionSearch(benchmarkExecutor, binarySearch, setOf(lowerBoundRestriction))
 
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> =
-            ArrayList(listOf(0, 2, 2, 3, 4, 6, 7).map { x -> Resource(x, emptyList()) })
+        val actual: ArrayList<Int?> = ArrayList()
+        val expected: ArrayList<Int?> =
+            ArrayList(listOf(0, 2, 2, 3, 4, 6, 7))
 
         for (load in mockLoads) {
             actual.add(strategy.findSuitableResource(load, mockResources))
diff --git a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt b/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
index b08c1a18a3013e1573e4892f01698b5e509f9609..335b0f8c59ac7642c30a12e494890e8f2c52ccda 100644
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
+++ b/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
@@ -3,8 +3,7 @@ package theodolite
 import theodolite.benchmark.Benchmark
 import theodolite.benchmark.BenchmarkDeployment
 import theodolite.util.ConfigurationOverride
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import theodolite.util.PatcherDefinition
 
 class TestBenchmark : Benchmark {
 
@@ -15,11 +14,13 @@ class TestBenchmark : Benchmark {
     }
 
     override fun buildDeployment(
-        load: LoadDimension,
-        res: Resource,
-        configurationOverrides: List<ConfigurationOverride?>,
-        loadGenerationDelay: Long,
-        afterTeardownDelay: Long
+            load: Int,
+            loadPatcherDefinitions: List<PatcherDefinition>,
+            resource: Int,
+            resourcePatcherDefinitions: List<PatcherDefinition>,
+            configurationOverrides: List<ConfigurationOverride?>,
+            loadGenerationDelay: Long,
+            afterTeardownDelay: Long
     ): BenchmarkDeployment {
         return TestBenchmarkDeployment()
     }
diff --git a/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt b/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
index 2efddc48cb93a0870d1716c58a7018145c16e2ff..a5346896f6d20b6d9c0a828d2d3798c70c0861c4 100644
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
+++ b/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
@@ -3,8 +3,6 @@ package theodolite
 import theodolite.benchmark.Benchmark
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
 import theodolite.util.Results
 import java.time.Duration
 
@@ -27,12 +25,14 @@ class TestBenchmarkExecutorImpl(
         executionId = executionId,
         loadGenerationDelay = loadGenerationDelay,
         afterTeardownDelay = afterTeardownDelay,
-        executionName = "test-execution"
+        executionName = "test-execution",
+        loadPatcherDefinitions = emptyList(),
+        resourcePatcherDefinitions = emptyList()
     ) {
 
-    override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
-        val result = this.mockResults[load.get()][res.get()]
-        this.results.setResult(Pair(load, res), result)
+    override fun runExperiment(load: Int, resource: Int): Boolean {
+        val result = this.mockResults[load][resource]
+        this.results.setResult(Pair(load, resource), result)
         return result
     }
 }
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
index 9274e283b48a6fd9b30d5ce0aff3cb8b995e0ce5..961c813f432d13fd2b373c74adaa00df4049a334 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
@@ -36,16 +36,24 @@ class ExecutionCRDummy(name: String, benchmark: String) {
         resourceDef.resourceType = ""
         resourceDef.resourceValues = emptyList()
 
+        val strat = BenchmarkExecution.Strategy()
+        strat.name = ""
+        strat.restrictions = emptyList()
+        strat.guessStrategy = ""
+        strat.searchStrategy = ""
+
+
         val exec = BenchmarkExecution.Execution()
         exec.afterTeardownDelay = 0
         exec.duration = 0
         exec.loadGenerationDelay = 0
         exec.repetitions = 1
-        exec.restrictions = emptyList()
-        exec.strategy = ""
+        exec.metric = ""
+        exec.strategy = strat
+
 
         execution.benchmark = benchmark
-        execution.load = loadType
+        execution.loads = loadType
         execution.resources = resourceDef
         execution.slos = emptyList()
         execution.execution = exec
diff --git a/theodolite/src/test/kotlin/theodolite/model/crd/CRDExecutionTest.kt b/theodolite/src/test/kotlin/theodolite/model/crd/CRDExecutionTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1150141ecc6a7147c930375af5bc965b81647e5a
--- /dev/null
+++ b/theodolite/src/test/kotlin/theodolite/model/crd/CRDExecutionTest.kt
@@ -0,0 +1,90 @@
+package theodolite.model.crd
+
+import io.fabric8.kubernetes.api.model.KubernetesResourceList
+import io.fabric8.kubernetes.client.dsl.MixedOperation
+import io.fabric8.kubernetes.client.dsl.Resource
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer
+import io.quarkus.test.junit.QuarkusTest
+import io.quarkus.test.kubernetes.client.KubernetesTestServer
+import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.mockito.internal.matchers.apachecommons.ReflectionEquals
+import org.apache.commons.lang3.builder.EqualsBuilder
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.instanceOf
+import org.mockito.kotlin.isA
+import org.mockito.kotlin.mock
+import theodolite.benchmark.BenchmarkExecution
+import theodolite.execution.operator.*
+import theodolite.util.ConfigurationOverride
+import java.io.FileInputStream
+
+
+// TODO move somewhere else
+typealias ExecutionClient = MixedOperation<ExecutionCRD, KubernetesResourceList<ExecutionCRD>, Resource<ExecutionCRD>>
+
+@WithKubernetesTestServer
+@QuarkusTest
+internal class CRDExecutionTest {
+
+     @KubernetesTestServer
+     private lateinit var server: KubernetesServer
+
+     lateinit var executionClient: ExecutionClient
+
+     lateinit var controller: TheodoliteController
+
+     lateinit var stateHandler: ExecutionStateHandler
+
+     lateinit var eventHandler: ExecutionEventHandler
+
+     @BeforeEach
+     fun setUp() {
+          server.before()
+
+          this.server.client
+                  .apiextensions().v1()
+                  .customResourceDefinitions()
+                  .load(FileInputStream("crd/crd-execution.yaml"))
+                  .create()
+
+          this.executionClient = this.server.client.resources(ExecutionCRD::class.java)
+
+          this.controller = mock()
+          this.stateHandler = ExecutionStateHandler(server.client)
+          this.eventHandler = ExecutionEventHandler(this.controller, this.stateHandler)
+     }
+
+     @AfterEach
+     fun tearDown() {
+          server.after()
+     }
+
+     @Test
+     fun checkParsingCRDTest(){
+          // BenchmarkExecution from yaml
+          val execution = executionClient.load(ClassLoader.getSystemResourceAsStream("k8s-resource-files/test-execution.yaml")).create().spec
+
+          assertEquals(0, execution.executionId)
+          assertEquals("test", execution.name)
+          assertEquals("uc1-kstreams", execution.benchmark)
+          assertEquals(mutableListOf<ConfigurationOverride?>(), execution.configOverrides)
+
+          assertEquals("NumSensors", execution.loads.loadType)
+          assertEquals(listOf(25000, 50000, 75000, 100000, 125000, 150000),execution.loads.loadValues)
+
+          assertEquals("Instances", execution.resources.resourceType)
+          assertEquals(listOf(1, 2, 3, 4, 5), execution.resources.resourceValues)
+
+          assertEquals("demand", execution.execution.metric)
+          assertEquals(300, execution.execution.duration)
+          assertEquals(1, execution.execution.repetitions)
+
+          assertEquals("RestrictionSearch", execution.execution.strategy.name)
+          assertEquals("LinearSearch", execution.execution.strategy.searchStrategy)
+          assertEquals(listOf("LowerBound"), execution.execution.strategy.restrictions)
+     }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt b/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
index b368647e314a4d803b444268c8218aefbee00ad4..e659d5f542910611af96d7eb6a68140ebd43065b 100644
--- a/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
@@ -4,22 +4,17 @@ 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
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import theodolite.strategies.Metric
 import theodolite.util.Results
 
 internal class LowerBoundRestrictionTest {
 
     @Test
     fun testNoPreviousResults() {
-        val results = Results()
+        val results = Results(Metric.from("demand"))
         val strategy = LowerBoundRestriction(results)
-        val load = buildLoadDimension(10000)
-        val resources = listOf(
-            buildResourcesDimension(1),
-            buildResourcesDimension(2),
-            buildResourcesDimension(3)
-        )
+        val load = 10000
+        val resources = listOf(1, 2, 3)
         val restriction = strategy.apply(load, resources)
 
         assertEquals(3, restriction.size)
@@ -28,17 +23,13 @@ internal class LowerBoundRestrictionTest {
 
     @Test
     fun testWithSuccessfulPreviousResults() {
-        val results = Results()
+        val results = Results(Metric.from("demand"))
         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 load = 30000
+        val resources = listOf(1, 2, 3)
         val restriction = strategy.apply(load, resources)
 
         assertEquals(2, restriction.size)
@@ -49,70 +40,54 @@ internal class LowerBoundRestrictionTest {
     @Disabled
     fun testWithNoSuccessfulPreviousResults() {
         // This test is currently not implemented this way, but might later be the desired behavior.
-        val results = Results()
+        val results = Results(Metric.from("demand"))
         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 load = 30000
+        val resources = listOf(1, 2, 3)
         val restriction = strategy.apply(load, resources)
 
         assertEquals(0, restriction.size)
-        assertEquals(emptyList<Resource>(), restriction)
+        assertEquals(emptyList<Int>(), restriction)
     }
 
 
     @Test
     fun testNoPreviousResults2() {
-        val results = Results()
+        val results = Results(Metric.from("demand"))
         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()))
+        val minRequiredInstances = results.getOptYDimensionValue(20000)
 
         assertNotNull(minRequiredInstances)
-        assertEquals(2, minRequiredInstances!!.get())
+        assertEquals(2, minRequiredInstances!!)
     }
 
     @Test
     @Disabled
     fun testMinRequiredInstancesWhenNotSuccessful() {
         // This test is currently not implemented this way, but might later be the desired behavior.
-        val results = Results()
+        val results = Results(Metric.from("demand"))
         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()))
+        val minRequiredInstances = results.getOptYDimensionValue(20000)
 
         assertNotNull(minRequiredInstances)
-        assertEquals(2, minRequiredInstances!!.get())
+        assertEquals(2, minRequiredInstances!!)
     }
 
-    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
-        )
+    private fun Results.setResult(load: Int, resource: Int, successful: Boolean) {
+        this.setResult(Pair(load, resource),successful)
     }
 }
diff --git a/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt
index 3b31f389bdeb35e6016a56a98abb1e13bf83ae18..cec18832ad99a01dc7977b64a19111f57f49d7f4 100644
--- a/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt
@@ -69,14 +69,14 @@ internal class IOHandlerTest {
     fun testWriteToJSONFile() {
         temporaryFolder.create()
         val folder = temporaryFolder.newFolder(FOLDER_URL)
-        val testContent = Resource(0, emptyList())
+        val testContentResource = 0
 
         IOHandler().writeToJSONFile(
             fileURL = "${folder.absolutePath}/test-file.json",
-            objectToSave = testContent
+            objectToSave = testContentResource
         )
 
-        val expected = GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting().create().toJson(testContent)
+        val expected = GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting().create().toJson(testContentResource)
 
         assertEquals(
             expected,
diff --git a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt b/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
index 9cfc2ae78e7a8846e3f0fa136699509145e5de22..d453587a9aeeee1ad48cf750a614009ef6be9aff 100644
--- a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
@@ -3,73 +3,89 @@ 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
+import theodolite.strategies.Metric
 
 @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)
+    fun testMinRequiredInstancesWhenSuccessfulDemand() {
+        val results = Results(Metric.from("demand"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(10000, 2), true)
+        results.setResult(Pair(20000, 1), false)
+        results.setResult(Pair(20000, 2), true)
 
-        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
+        val minRequiredInstances = results.getOptYDimensionValue(20000)
 
         assertNotNull(minRequiredInstances)
-        assertEquals(2, minRequiredInstances!!.get())
+        assertEquals(2, minRequiredInstances)
     }
 
     @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)
+    fun testGetMaxBenchmarkedLoadWhenAllSuccessfulDemand() {
+        val results = Results(Metric.from("demand"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(10000, 2), true)
 
-        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
+        val test1 = results.getMaxBenchmarkedXDimensionValue(100000)
 
-        assertNotNull(minRequiredInstances)
-        assertEquals(2, minRequiredInstances!!.get())
+        assertNotNull(test1)
+        assertEquals(10000, test1)
+    }
+
+    @Test
+    fun testGetMaxBenchmarkedLoadWhenLargestNotSuccessfulDemand() {
+        val results = Results(Metric.from("demand"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(10000, 2), true)
+        results.setResult(Pair(20000, 1), false)
+
+        val test2 = results.getMaxBenchmarkedXDimensionValue(100000)
+
+        assertNotNull(test2)
+        assertEquals(20000, test2)
     }
 
-    private fun Results.setResult(load: Int, resources: Int, successful: Boolean) {
-        this.setResult(
-            Pair(
-                LoadDimension(load, emptyList()),
-                Resource(resources, emptyList())
-            ),
-            successful
-        )
+    @Test
+    fun testMaxRequiredInstancesWhenSuccessfulCapacity() {
+        val results = Results(Metric.from("capacity"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(20000, 1), false)
+        results.setResult(Pair(10000, 2), true)
+        results.setResult(Pair(20000, 2), true)
+
+        val maxRequiredInstances = results.getOptYDimensionValue(2)
+
+        assertNotNull(maxRequiredInstances)
+        assertEquals(20000, maxRequiredInstances)
     }
 
 
     @Test
-    fun testGetMaxBenchmarkedLoadWhenAllSuccessful() {
-        val results = Results()
-        results.setResult(10000, 1, true)
-        results.setResult(10000, 2, true)
+    fun testGetMaxBenchmarkedLoadWhenAllSuccessfulCapacity() {
+        val results = Results(Metric.from("capacity"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(10000, 2), true)
 
-        val test1 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get()
+        val test1 = results.getMaxBenchmarkedXDimensionValue(5)
 
-        assertEquals(10000, test1)
+        assertNotNull(test1)
+        assertEquals(2, test1)
     }
 
     @Test
-    fun testGetMaxBenchmarkedLoadWhenLargestNotSuccessful() {
-        val results = Results()
-        results.setResult(10000, 1, true)
-        results.setResult(10000, 2, true)
-        results.setResult(20000, 1, false)
+    fun testGetMaxBenchmarkedLoadWhenLargestNotSuccessfulCapacity() {
+        val results = Results(Metric.from("capacity"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(20000, 1), true)
+        results.setResult(Pair(10000, 2), false)
 
-        val test2 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get()
 
-        assertEquals(20000, test2)
+        val test2 = results.getMaxBenchmarkedXDimensionValue(5)
+
+        assertNotNull(test2)
+        assertEquals(2, test2)
     }
 }
diff --git a/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml b/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml
index 1407a9952b7454053d204454841d51cfb4d7dbf4..e250d8a9610be6c645ec2da4d6de5b9b59aaa929 100644
--- a/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml
+++ b/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml
@@ -5,7 +5,7 @@ metadata:
 spec:
   name: test
   benchmark: "uc1-kstreams"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
@@ -19,10 +19,12 @@ spec:
       offset: 0
       warmup: 60 # in seconds
   execution:
-    strategy: "LinearSearch"
+    strategy:
+      name: "RestrictionSearch"
+      restrictions:
+        - "LowerBound"
+      searchStrategy: "LinearSearch"
     duration: 300 # in seconds
     repetitions: 1
     loadGenerationDelay: 30 # in seconds
-    restrictions:
-      - "LowerBound"
   configOverrides: []
diff --git a/theodolite/src/test/resources/k8s-resource-files/test-execution-update.yaml b/theodolite/src/test/resources/k8s-resource-files/test-execution-update.yaml
index c075702da218397352f1dc1e5b283534fbb4d718..80476ba5c01a7c49b5058448117bc25e960eacee 100644
--- a/theodolite/src/test/resources/k8s-resource-files/test-execution-update.yaml
+++ b/theodolite/src/test/resources/k8s-resource-files/test-execution-update.yaml
@@ -5,7 +5,7 @@ metadata:
 spec:
   name: test
   benchmark: "uc1-kstreams-update"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
@@ -20,10 +20,12 @@ spec:
         externalSloUrl: "http://localhost:80/evaluate-slope"
         warmup: 60 # in seconds
   execution:
-    strategy: "LinearSearch"
+    strategy:
+      name: "RestrictionSearch"
+      restrictions:
+        - "LowerBound"
+      searchStrategy: "LinearSearch"
     duration: 300 # in seconds
     repetitions: 1
     loadGenerationDelay: 30 # in seconds
-    restrictions:
-      - "LowerBound"
   configOverrides: []
diff --git a/theodolite/src/test/resources/k8s-resource-files/test-execution.yaml b/theodolite/src/test/resources/k8s-resource-files/test-execution.yaml
index e12c851da5d8a79f57b1fa59b86239c219370c0f..2df4760cd6deab72cae0303bb669852b3140baa6 100644
--- a/theodolite/src/test/resources/k8s-resource-files/test-execution.yaml
+++ b/theodolite/src/test/resources/k8s-resource-files/test-execution.yaml
@@ -5,7 +5,7 @@ metadata:
 spec:
   name: test
   benchmark: "uc1-kstreams"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
@@ -20,10 +20,12 @@ spec:
         externalSloUrl: "http://localhost:80/evaluate-slope"
         warmup: 60 # in seconds
   execution:
-    strategy: "LinearSearch"
+    strategy:
+      name: "RestrictionSearch"
+      restrictions:
+        - "LowerBound"
+      searchStrategy: "LinearSearch"
     duration: 300 # in seconds
     repetitions: 1
     loadGenerationDelay: 30 # in seconds
-    restrictions:
-      - "LowerBound"
   configOverrides: []