diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index af3ca77a897a2ddea9ee8d7c6e4e30fa7f369e94..a1aefe7f900ea2b03c0ce2c8ed8e9827a8fe2f57 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -48,7 +48,8 @@ default:
         export PUBLISHED_IMAGE_TAG=$DOCKER_TAG_NAME$CI_COMMIT_SHORT_SHA
       fi
     - "[ $DOCKERFILE ] && KANIKO_DOCKERFILE=\"--dockerfile $DOCKERFILE\""
-    - /kaniko/executor --context `pwd`/$CONTEXT $KANIKO_DOCKERFILE $KANIKO_D
+    - "BUILD_ARGS=$(printenv | sed -n 's/BUILD_ARG_/--build-arg=/p')"
+    - /kaniko/executor --context `pwd`/$CONTEXT $KANIKO_DOCKERFILE $KANIKO_D $BUILD_ARGS
     - echo "PUBLISHED_IMAGE_TAG=$PUBLISHED_IMAGE_TAG" >> $CI_PROJECT_DIR/build.env
   artifacts:
     reports:
@@ -135,6 +136,38 @@ lint-helm:
   - when: manual
     allow_failure: true
 
+test-helm:
+  stage: smoketest
+  extends: .dind
+  needs:
+    - lint-helm
+    # - deploy-theodolite
+  image: ghcr.io/cau-se/theodolite-build-k3d-helm:20.10.12
+  variables:
+    CLUSTERNAME: "$CI_PROJECT_NAME-$CI_PIPELINE_ID"
+  cache:
+    paths:
+      - helm/charts
+  before_script:
+    - k3d help
+    - k3d version
+    #- k3d cluster create testgitlabci --agents 1 --wait -p "30000:30000@agent[0]"
+    - k3d cluster create $CLUSTERNAME --agents 1 --wait -p "30000:30000@agent:0" # k3d 5.0
+    # show cluster info
+    - kubectl cluster-info
+    - helm version
+  script:
+    # Display initial pods, etc.
+    - cd helm
+    - helm dependencies update .
+    - helm install theodolite . -f preconfigs/minimal.yaml --wait
+    - helm test theodolite
+    - kubectl get nodes -o wide
+    - kubectl get pods --all-namespaces -o wide
+    - kubectl get services --all-namespaces -o wide
+  after_script:
+    - k3d cluster delete $CLUSTERNAME
+
 
 # Theodolite Benchmarks
 
@@ -235,7 +268,7 @@ spotbugs-benchmarks:
     - changes:
       - theodolite-benchmarks/*
       - theodolite-benchmarks/$JAVA_PROJECT_NAME/**/*
-      - theodolite-benchmarks/{$JAVA_PROJECT_DEPS}/**/*
+      - theodolite-benchmarks/{commons,$JAVA_PROJECT_DEPS}/**/*
       if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $IMAGE_NAME && $JAVA_PROJECT_NAME && $JAVA_PROJECT_DEPS"
     - if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $IMAGE_NAME && $JAVA_PROJECT_NAME"
       when: manual
@@ -851,3 +884,24 @@ deploy-buildimage-docker-compose-jq:
     - if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $CI_PIPELINE_SOURCE == 'web'"
       when: manual
       allow_failure: true
+
+deploy-buildimage-k3d-helm:
+  stage: deploy
+  extends:
+    - .kaniko-push
+  needs: []
+  variables:
+    DOCKER_VERSION: 20.10.12
+    BUILD_ARG_DOCKER_VERSION: $DOCKER_VERSION
+    BUILD_ARG_KUBECTL: v1.21.3
+    IMAGE_NAME: theodolite-build-k3d-helm
+    IMAGE_TAG: $DOCKER_VERSION
+  before_script:
+    - cd buildimages/k3d-helm
+  rules:
+    - changes:
+      - buildimages/k3d-helm/Dockerfile
+      if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW"
+    - if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $CI_PIPELINE_SOURCE == 'web'"
+      when: manual
+      allow_failure: true
diff --git a/buildimages/k3d-helm/Dockerfile b/buildimages/k3d-helm/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..496cddd68a230a7ea8b0f73adb9ffa37e35e6719
--- /dev/null
+++ b/buildimages/k3d-helm/Dockerfile
@@ -0,0 +1,14 @@
+ARG DOCKER_VERSION=latest
+
+FROM docker:${DOCKER_VERSION}
+
+ARG KUBECTL_VERSION=v1.21.3
+
+RUN apk add -U wget bash openssl
+# install kubectl
+RUN wget -q -O /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl && \
+    chmod +x /usr/local/bin/kubectl
+# install k3d
+RUN wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
+# install Helm
+RUN wget -q -O - https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
index fc60fc6f6fddbb9b18a85ed1f472a444e0ed4cea..4acb2ba79d5cde699cf9dd4d379bf17c3c93e068 100644
--- a/docs/Gemfile.lock
+++ b/docs/Gemfile.lock
@@ -239,7 +239,7 @@ GEM
       jekyll-seo-tag (~> 2.1)
     minitest (5.15.0)
     multipart-post (2.1.1)
-    nokogiri (1.13.4-x86_64-linux)
+    nokogiri (1.13.6-x86_64-linux)
       racc (~> 1.4)
     octokit (4.22.0)
       faraday (>= 0.9)
diff --git a/docs/api-reference/crds.md b/docs/api-reference/crds.md
index fb3f02ac941870dd085d06027d972e6003c7aadb..87c4e9046396456e2177098c8085aa995534735b 100644
--- a/docs/api-reference/crds.md
+++ b/docs/api-reference/crds.md
@@ -114,6 +114,13 @@ Resource Types:
           A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object.<br/>
         </td>
         <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecslosindex">slos</a></b></td>
+        <td>[]object</td>
+        <td>
+          List of resource values for the specified resource type.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b><a href="#benchmarkspecsut">sut</a></b></td>
         <td>object</td>
@@ -146,6 +153,15 @@ Resource Types:
             <i>Default</i>: <br/>
         </td>
         <td>false</td>
+      </tr><tr>
+        <td><b>waitForResourcesEnabled</b></td>
+        <td>boolean</td>
+        <td>
+          If true, Theodolite waits to create the resource for the SUT until the infrastructure resources are ready, and analogously, Theodolite waits to create the load-gen resource until the resources of the SUT are ready.<br/>
+          <br/>
+            <i>Default</i>: false<br/>
+        </td>
+        <td>false</td>
       </tr></tbody>
 </table>
 
@@ -214,17 +230,87 @@ The loadGenResourceSets specifies all Kubernetes resources required to start the
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexec">exec</a></b></td>
+        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexdelete">delete</a></b></td>
         <td>object</td>
         <td>
-          Specifies command to be executed.<br/>
+          Specifies deletion of a resource.<br/>
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexselector">selector</a></b></td>
+        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexec">exec</a></b></td>
         <td>object</td>
         <td>
-          The selector specifies which resource should be selected for the execution of the command.<br/>
+          Specifies a command that gets executed within a Container of a Pod<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.loadGenerator.afterActions[index].delete
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindex)</sup></sup>
+
+
+
+Specifies deletion of a resource.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexdeleteselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          Defines how to select the resource to delete.<br/>
+        </td>
+        <td>true</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.loadGenerator.afterActions[index].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexdelete)</sup></sup>
+
+
+
+Defines how to select the resource to delete.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b>apiVersion</b></td>
+        <td>string</td>
+        <td>
+          Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>kind</b></td>
+        <td>string</td>
+        <td>
+          Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>nameRegex</b></td>
+        <td>string</td>
+        <td>
+          Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/>
+          <br/>
+            <i>Default</i>: *<br/>
         </td>
         <td>false</td>
       </tr></tbody>
@@ -236,7 +322,7 @@ The loadGenResourceSets specifies all Kubernetes resources required to start the
 
 
 
-Specifies command to be executed.
+Specifies a command that gets executed within a Container of a Pod
 
 <table>
     <thead>
@@ -253,20 +339,27 @@ Specifies command to be executed.
         <td>
           The command to be executed as string array.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexecselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          The selector specifies which resource should be selected for the execution of the command.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b>timeoutSeconds</b></td>
         <td>integer</td>
         <td>
           Specifies the timeout (in seconds) for the specified command.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.loadGenerator.afterActions[index].selector
-<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindex)</sup></sup>
+### benchmark.spec.loadGenerator.afterActions[index].exec.selector
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexexec)</sup></sup>
 
 
 
@@ -291,7 +384,7 @@ The selector specifies which resource should be selected for the execution of th
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexselectorpod">pod</a></b></td>
+        <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexecselectorpod">pod</a></b></td>
         <td>object</td>
         <td>
           Specifies the pod.<br/>
@@ -301,8 +394,8 @@ The selector specifies which resource should be selected for the execution of th
 </table>
 
 
-### benchmark.spec.loadGenerator.afterActions[index].selector.pod
-<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexselector)</sup></sup>
+### benchmark.spec.loadGenerator.afterActions[index].exec.selector.pod
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexexecselector)</sup></sup>
 
 
 
@@ -347,17 +440,87 @@ Specifies the pod.
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexec">exec</a></b></td>
+        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexdelete">delete</a></b></td>
         <td>object</td>
         <td>
-          Specifies command to be executed.<br/>
+          Specifies deletion of a resource.<br/>
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexselector">selector</a></b></td>
+        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexec">exec</a></b></td>
         <td>object</td>
         <td>
-          The selector specifies which resource should be selected for the execution of the command.<br/>
+          Specifies a command that gets executed within a Container of a Pod<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.loadGenerator.beforeActions[index].delete
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindex)</sup></sup>
+
+
+
+Specifies deletion of a resource.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexdeleteselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          Defines how to select the resource to delete.<br/>
+        </td>
+        <td>true</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.loadGenerator.beforeActions[index].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexdelete)</sup></sup>
+
+
+
+Defines how to select the resource to delete.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b>apiVersion</b></td>
+        <td>string</td>
+        <td>
+          Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>kind</b></td>
+        <td>string</td>
+        <td>
+          Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>nameRegex</b></td>
+        <td>string</td>
+        <td>
+          Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/>
+          <br/>
+            <i>Default</i>: *<br/>
         </td>
         <td>false</td>
       </tr></tbody>
@@ -369,7 +532,7 @@ Specifies the pod.
 
 
 
-Specifies command to be executed.
+Specifies a command that gets executed within a Container of a Pod
 
 <table>
     <thead>
@@ -386,20 +549,27 @@ Specifies command to be executed.
         <td>
           The command to be executed as string array.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexecselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          The selector specifies which resource should be selected for the execution of the command.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b>timeoutSeconds</b></td>
         <td>integer</td>
         <td>
           Specifies the timeout (in seconds) for the specified command.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.loadGenerator.beforeActions[index].selector
-<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindex)</sup></sup>
+### benchmark.spec.loadGenerator.beforeActions[index].exec.selector
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexexec)</sup></sup>
 
 
 
@@ -424,7 +594,7 @@ The selector specifies which resource should be selected for the execution of th
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexselectorpod">pod</a></b></td>
+        <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexecselectorpod">pod</a></b></td>
         <td>object</td>
         <td>
           Specifies the pod.<br/>
@@ -434,8 +604,8 @@ The selector specifies which resource should be selected for the execution of th
 </table>
 
 
-### benchmark.spec.loadGenerator.beforeActions[index].selector.pod
-<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexselector)</sup></sup>
+### benchmark.spec.loadGenerator.beforeActions[index].exec.selector.pod
+<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexexecselector)</sup></sup>
 
 
 
@@ -727,6 +897,63 @@ The fileSystem resourceSet loads the Kubernetes manifests from the filesystem.
 </table>
 
 
+### benchmark.spec.slos[index]
+<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup>
+
+
+
+
+
+<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>
+          The name of the SLO.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>offset</b></td>
+        <td>integer</td>
+        <td>
+          Hours by which the start and end timestamp will be shifted (for different timezones).<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>prometheusUrl</b></td>
+        <td>string</td>
+        <td>
+          Connection string for Promehteus.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>sloType</b></td>
+        <td>string</td>
+        <td>
+          The type of the SLO. It must match 'lag trend'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>properties</b></td>
+        <td>map[string]string</td>
+        <td>
+          (Optional) SLO specific additional arguments.<br/>
+          <br/>
+            <i>Default</i>: map[]<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
 ### benchmark.spec.sut
 <sup><sup>[↩ Parent](#benchmarkspec)</sup></sup>
 
@@ -747,7 +974,7 @@ The appResourceSets specifies all Kubernetes resources required to start the sut
         <td><b><a href="#benchmarkspecsutafteractionsindex">afterActions</a></b></td>
         <td>[]object</td>
         <td>
-          <br/>
+          SUT after actions are executed after the teardown of the SUT.<br/>
           <br/>
             <i>Default</i>: []<br/>
         </td>
@@ -791,17 +1018,87 @@ The appResourceSets specifies all Kubernetes resources required to start the sut
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecsutafteractionsindexexec">exec</a></b></td>
+        <td><b><a href="#benchmarkspecsutafteractionsindexdelete">delete</a></b></td>
         <td>object</td>
         <td>
-          Specifies command to be executed.<br/>
+          Specifies deletion of a resource.<br/>
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecsutafteractionsindexselector">selector</a></b></td>
+        <td><b><a href="#benchmarkspecsutafteractionsindexexec">exec</a></b></td>
         <td>object</td>
         <td>
-          The selector specifies which resource should be selected for the execution of the command.<br/>
+          Specifies a command that gets executed within a Container of a Pod<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.sut.afterActions[index].delete
+<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindex)</sup></sup>
+
+
+
+Specifies deletion of a resource.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecsutafteractionsindexdeleteselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          Defines how to select the resource to delete.<br/>
+        </td>
+        <td>true</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.sut.afterActions[index].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexdelete)</sup></sup>
+
+
+
+Defines how to select the resource to delete.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b>apiVersion</b></td>
+        <td>string</td>
+        <td>
+          Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>kind</b></td>
+        <td>string</td>
+        <td>
+          Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>nameRegex</b></td>
+        <td>string</td>
+        <td>
+          Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/>
+          <br/>
+            <i>Default</i>: *<br/>
         </td>
         <td>false</td>
       </tr></tbody>
@@ -813,7 +1110,7 @@ The appResourceSets specifies all Kubernetes resources required to start the sut
 
 
 
-Specifies command to be executed.
+Specifies a command that gets executed within a Container of a Pod
 
 <table>
     <thead>
@@ -830,20 +1127,27 @@ Specifies command to be executed.
         <td>
           The command to be executed as string array.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecsutafteractionsindexexecselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          The selector specifies which resource should be selected for the execution of the command.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b>timeoutSeconds</b></td>
         <td>integer</td>
         <td>
           Specifies the timeout (in seconds) for the specified command.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.sut.afterActions[index].selector
-<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindex)</sup></sup>
+### benchmark.spec.sut.afterActions[index].exec.selector
+<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexexec)</sup></sup>
 
 
 
@@ -868,7 +1172,7 @@ The selector specifies which resource should be selected for the execution of th
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecsutafteractionsindexselectorpod">pod</a></b></td>
+        <td><b><a href="#benchmarkspecsutafteractionsindexexecselectorpod">pod</a></b></td>
         <td>object</td>
         <td>
           Specifies the pod.<br/>
@@ -878,8 +1182,8 @@ The selector specifies which resource should be selected for the execution of th
 </table>
 
 
-### benchmark.spec.sut.afterActions[index].selector.pod
-<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexselector)</sup></sup>
+### benchmark.spec.sut.afterActions[index].exec.selector.pod
+<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexexecselector)</sup></sup>
 
 
 
@@ -902,17 +1206,78 @@ Specifies the pod.
           <br/>
             <i>Default</i>: map[]<br/>
         </td>
-        <td>false</td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.sut.beforeActions[index]
+<sup><sup>[↩ Parent](#benchmarkspecsut)</sup></sup>
+
+
+
+
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexdelete">delete</a></b></td>
+        <td>object</td>
+        <td>
+          Specifies deletion of a resource.<br/>
+        </td>
+        <td>false</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexexec">exec</a></b></td>
+        <td>object</td>
+        <td>
+          Specifies a command that gets executed within a Container of a Pod<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.sut.beforeActions[index].delete
+<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindex)</sup></sup>
+
+
+
+Specifies deletion of a resource.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexdeleteselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          Defines how to select the resource to delete.<br/>
+        </td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.sut.beforeActions[index]
-<sup><sup>[↩ Parent](#benchmarkspecsut)</sup></sup>
-
+### benchmark.spec.sut.beforeActions[index].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexdelete)</sup></sup>
 
 
 
+Defines how to select the resource to delete.
 
 <table>
     <thead>
@@ -924,17 +1289,26 @@ Specifies the pod.
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecsutbeforeactionsindexexec">exec</a></b></td>
-        <td>object</td>
+        <td><b>apiVersion</b></td>
+        <td>string</td>
         <td>
-          Specifies command to be executed.<br/>
+          Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecsutbeforeactionsindexselector">selector</a></b></td>
-        <td>object</td>
+        <td><b>kind</b></td>
+        <td>string</td>
         <td>
-          The selector specifies which resource should be selected for the execution of the command.<br/>
+          Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>nameRegex</b></td>
+        <td>string</td>
+        <td>
+          Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/>
+          <br/>
+            <i>Default</i>: *<br/>
         </td>
         <td>false</td>
       </tr></tbody>
@@ -946,7 +1320,7 @@ Specifies the pod.
 
 
 
-Specifies command to be executed.
+Specifies a command that gets executed within a Container of a Pod
 
 <table>
     <thead>
@@ -963,20 +1337,27 @@ Specifies command to be executed.
         <td>
           The command to be executed as string array.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexexecselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          The selector specifies which resource should be selected for the execution of the command.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b>timeoutSeconds</b></td>
         <td>integer</td>
         <td>
           Specifies the timeout (in seconds) for the specified command.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.sut.beforeActions[index].selector
-<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindex)</sup></sup>
+### benchmark.spec.sut.beforeActions[index].exec.selector
+<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexexec)</sup></sup>
 
 
 
@@ -1001,7 +1382,7 @@ The selector specifies which resource should be selected for the execution of th
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecsutbeforeactionsindexselectorpod">pod</a></b></td>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexexecselectorpod">pod</a></b></td>
         <td>object</td>
         <td>
           Specifies the pod.<br/>
@@ -1011,8 +1392,8 @@ The selector specifies which resource should be selected for the execution of th
 </table>
 
 
-### benchmark.spec.sut.beforeActions[index].selector.pod
-<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexselector)</sup></sup>
+### benchmark.spec.sut.beforeActions[index].exec.selector.pod
+<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexexecselector)</sup></sup>
 
 
 
@@ -1206,17 +1587,87 @@ The fileSystem resourceSet loads the Kubernetes manifests from the filesystem.
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexec">exec</a></b></td>
+        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexdelete">delete</a></b></td>
         <td>object</td>
         <td>
-          Specifies command to be executed.<br/>
+          Specifies deletion of a resource.<br/>
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexselector">selector</a></b></td>
+        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexec">exec</a></b></td>
         <td>object</td>
         <td>
-          The selector specifies which resource should be selected for the execution of the command.<br/>
+          Specifies a command that gets executed within a Container of a Pod<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.infrastructure.afterActions[index].delete
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindex)</sup></sup>
+
+
+
+Specifies deletion of a resource.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexdeleteselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          Defines how to select the resource to delete.<br/>
+        </td>
+        <td>true</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.infrastructure.afterActions[index].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexdelete)</sup></sup>
+
+
+
+Defines how to select the resource to delete.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b>apiVersion</b></td>
+        <td>string</td>
+        <td>
+          Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>kind</b></td>
+        <td>string</td>
+        <td>
+          Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>nameRegex</b></td>
+        <td>string</td>
+        <td>
+          Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/>
+          <br/>
+            <i>Default</i>: *<br/>
         </td>
         <td>false</td>
       </tr></tbody>
@@ -1228,7 +1679,7 @@ The fileSystem resourceSet loads the Kubernetes manifests from the filesystem.
 
 
 
-Specifies command to be executed.
+Specifies a command that gets executed within a Container of a Pod
 
 <table>
     <thead>
@@ -1245,20 +1696,27 @@ Specifies command to be executed.
         <td>
           The command to be executed as string array.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexecselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          The selector specifies which resource should be selected for the execution of the command.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b>timeoutSeconds</b></td>
         <td>integer</td>
         <td>
           Specifies the timeout (in seconds) for the specified command.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.infrastructure.afterActions[index].selector
-<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindex)</sup></sup>
+### benchmark.spec.infrastructure.afterActions[index].exec.selector
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexexec)</sup></sup>
 
 
 
@@ -1283,7 +1741,7 @@ The selector specifies which resource should be selected for the execution of th
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexselectorpod">pod</a></b></td>
+        <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexecselectorpod">pod</a></b></td>
         <td>object</td>
         <td>
           Specifies the pod.<br/>
@@ -1293,8 +1751,8 @@ The selector specifies which resource should be selected for the execution of th
 </table>
 
 
-### benchmark.spec.infrastructure.afterActions[index].selector.pod
-<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexselector)</sup></sup>
+### benchmark.spec.infrastructure.afterActions[index].exec.selector.pod
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexexecselector)</sup></sup>
 
 
 
@@ -1339,17 +1797,87 @@ Specifies the pod.
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexec">exec</a></b></td>
+        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexdelete">delete</a></b></td>
         <td>object</td>
         <td>
-          Specifies command to be executed.<br/>
+          Specifies deletion of a resource.<br/>
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexselector">selector</a></b></td>
+        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexec">exec</a></b></td>
         <td>object</td>
         <td>
-          The selector specifies which resource should be selected for the execution of the command.<br/>
+          Specifies a command that gets executed within a Container of a Pod<br/>
+        </td>
+        <td>false</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.infrastructure.beforeActions[index].delete
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindex)</sup></sup>
+
+
+
+Specifies deletion of a resource.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexdeleteselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          Defines how to select the resource to delete.<br/>
+        </td>
+        <td>true</td>
+      </tr></tbody>
+</table>
+
+
+### benchmark.spec.infrastructure.beforeActions[index].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexdelete)</sup></sup>
+
+
+
+Defines how to select the resource to delete.
+
+<table>
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Description</th>
+            <th>Required</th>
+        </tr>
+    </thead>
+    <tbody><tr>
+        <td><b>apiVersion</b></td>
+        <td>string</td>
+        <td>
+          Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>kind</b></td>
+        <td>string</td>
+        <td>
+          Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/>
+        </td>
+        <td>true</td>
+      </tr><tr>
+        <td><b>nameRegex</b></td>
+        <td>string</td>
+        <td>
+          Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/>
+          <br/>
+            <i>Default</i>: *<br/>
         </td>
         <td>false</td>
       </tr></tbody>
@@ -1361,7 +1889,7 @@ Specifies the pod.
 
 
 
-Specifies command to be executed.
+Specifies a command that gets executed within a Container of a Pod
 
 <table>
     <thead>
@@ -1378,20 +1906,27 @@ Specifies command to be executed.
         <td>
           The command to be executed as string array.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
+      </tr><tr>
+        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexecselector">selector</a></b></td>
+        <td>object</td>
+        <td>
+          The selector specifies which resource should be selected for the execution of the command.<br/>
+        </td>
+        <td>true</td>
       </tr><tr>
         <td><b>timeoutSeconds</b></td>
         <td>integer</td>
         <td>
           Specifies the timeout (in seconds) for the specified command.<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
 
-### benchmark.spec.infrastructure.beforeActions[index].selector
-<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindex)</sup></sup>
+### benchmark.spec.infrastructure.beforeActions[index].exec.selector
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexexec)</sup></sup>
 
 
 
@@ -1416,7 +1951,7 @@ The selector specifies which resource should be selected for the execution of th
         </td>
         <td>false</td>
       </tr><tr>
-        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexselectorpod">pod</a></b></td>
+        <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexecselectorpod">pod</a></b></td>
         <td>object</td>
         <td>
           Specifies the pod.<br/>
@@ -1426,8 +1961,8 @@ The selector specifies which resource should be selected for the execution of th
 </table>
 
 
-### benchmark.spec.infrastructure.beforeActions[index].selector.pod
-<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexselector)</sup></sup>
+### benchmark.spec.infrastructure.beforeActions[index].exec.selector.pod
+<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexexecselector)</sup></sup>
 
 
 
@@ -1765,7 +2300,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/>
@@ -1778,13 +2313,6 @@ Contains the Kafka configuration.
           Specifies the scaling resource that is benchmarked.<br/>
         </td>
         <td>true</td>
-      </tr><tr>
-        <td><b><a href="#executionspecslosindex">slos</a></b></td>
-        <td>[]object</td>
-        <td>
-          List of resource values for the specified resource type.<br/>
-        </td>
-        <td>true</td>
       </tr><tr>
         <td><b>name</b></td>
         <td>string</td>
@@ -1794,6 +2322,13 @@ Contains the Kafka configuration.
             <i>Default</i>: <br/>
         </td>
         <td>false</td>
+      </tr><tr>
+        <td><b><a href="#executionspecslosindex">slos</a></b></td>
+        <td>[]object</td>
+        <td>
+          List of SLOs with their properties, which differ from the benchmark definition.<br/>
+        </td>
+        <td>false</td>
       </tr></tbody>
 </table>
 
@@ -1906,35 +2441,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>
 
 
@@ -2019,24 +2602,10 @@ Specifies the scaling resource that is benchmarked.
         </tr>
     </thead>
     <tbody><tr>
-        <td><b>offset</b></td>
-        <td>integer</td>
-        <td>
-          Hours by which the start and end timestamp will be shifted (for different timezones).<br/>
-        </td>
-        <td>true</td>
-      </tr><tr>
-        <td><b>prometheusUrl</b></td>
-        <td>string</td>
-        <td>
-          Connection string for Promehteus.<br/>
-        </td>
-        <td>true</td>
-      </tr><tr>
-        <td><b>sloType</b></td>
+        <td><b>name</b></td>
         <td>string</td>
         <td>
-          The type of the SLO. It must match 'lag trend'.<br/>
+          The name of the SLO. It must match a SLO specified in the Benchmark.<br/>
         </td>
         <td>true</td>
       </tr><tr>
@@ -2047,7 +2616,7 @@ Specifies the scaling resource that is benchmarked.
           <br/>
             <i>Default</i>: map[]<br/>
         </td>
-        <td>false</td>
+        <td>true</td>
       </tr></tbody>
 </table>
 
diff --git a/docs/index.yaml b/docs/index.yaml
index c6cf4f6dcbeaf4b4ede37bca925025db950a2a77..956bb83b19ebbae4cddc4da6f07a0d937cf3dc2d 100644
--- a/docs/index.yaml
+++ b/docs/index.yaml
@@ -1,41 +1,6 @@
 apiVersion: v1
 entries:
   theodolite:
-  - apiVersion: v2
-    appVersion: 0.7.0
-    created: "2022-05-11T13:49:02.457130925+02:00"
-    dependencies:
-    - condition: grafana.enabled
-      name: grafana
-      repository: https://grafana.github.io/helm-charts
-      version: 6.17.5
-    - condition: kube-prometheus-stack.enabled
-      name: kube-prometheus-stack
-      repository: https://prometheus-community.github.io/helm-charts
-      version: 20.0.1
-    - condition: cp-helm-charts.enabled
-      name: cp-helm-charts
-      repository: https://soerenhenning.github.io/cp-helm-charts
-      version: 0.6.0
-    - condition: strimzi.enabled
-      name: strimzi-kafka-operator
-      repository: https://strimzi.io/charts/
-      version: 0.28.0
-    description: Theodolite is a framework for benchmarking the horizontal and vertical
-      scalability of cloud-native applications.
-    digest: af10134baa30bb07423f78240fe1c609381e1c616585883cf5d3aded2d86a2b1
-    home: https://www.theodolite.rocks
-    maintainers:
-    - email: soeren.henning@email.uni-kiel.de
-      name: Sören Henning
-      url: https://www.se.informatik.uni-kiel.de/en/team/soeren-henning-m-sc
-    name: theodolite
-    sources:
-    - https://github.com/cau-se/theodolite
-    type: application
-    urls:
-    - https://github.com/cau-se/theodolite/releases/download/v0.7.0/theodolite-0.7.0%20copy.tgz
-    version: 0.7.0
   - apiVersion: v2
     appVersion: 0.7.0
     created: "2022-05-11T13:49:02.491041789+02:00"
diff --git a/docs/installation.md b/docs/installation.md
index d1c7ac3d1dd68d244c556e1ade53b50330aec6ed..2b80920bb0d9adbde11be32b710afe436b98bb0e 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -102,4 +102,16 @@ kubectl delete crd prometheuses.monitoring.coreos.com
 kubectl delete crd prometheusrules.monitoring.coreos.com
 kubectl delete crd servicemonitors.monitoring.coreos.com
 kubectl delete crd thanosrulers.monitoring.coreos.com
+# CRDs for Strimzi
+kubectl delete crd kafkabridges.kafka.strimzi.io
+kubectl delete crd kafkaconnectors.kafka.strimzi.io
+kubectl delete crd kafkaconnects.kafka.strimzi.io
+kubectl delete crd kafkamirrormaker2s.kafka.strimzi.io
+kubectl delete crd kafkamirrormakers.kafka.strimzi.io
+kubectl delete crd kafkarebalances.kafka.strimzi.io
+kubectl delete crd kafkas.kafka.strimzi.io
+kubectl delete crd kafkatopics.kafka.strimzi.io
+kubectl delete crd kafkausers.kafka.strimzi.io
+kubectl delete crd strimzipodsets.core.strimzi.io
+
 ```
diff --git a/helm/templates/strimzi/entity-role-binding.yaml b/helm/templates/strimzi/entity-role-binding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..adb5394f866e0e8d61f1549e884461a529b655d1
--- /dev/null
+++ b/helm/templates/strimzi/entity-role-binding.yaml
@@ -0,0 +1,18 @@
+{{- if not (index .Values "strimzi-kafka-operator" "createGlobalResources") -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  labels:
+    app: strimzi
+  name: strimzi-cluster-operator-entity-operator-delegation-namespaced
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: strimzi-entity-operator-namespaced
+subjects:
+- kind: ServiceAccount
+  name: strimzi-cluster-operator
+  namespace: {{ .Release.Namespace }}
+{{- end }}
+
diff --git a/helm/templates/strimzi/entity-role.yaml b/helm/templates/strimzi/entity-role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9a2230a9336151a444738c3cd069bbe961c2825b
--- /dev/null
+++ b/helm/templates/strimzi/entity-role.yaml
@@ -0,0 +1,46 @@
+{{- if not (index .Values "strimzi-kafka-operator" "createGlobalResources") -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: strimzi-entity-operator-namespaced
+  labels:
+    app: {{ template "theodolite.name" . }}-strimzi
+rules:
+- apiGroups:
+  - "kafka.strimzi.io"
+  resources:
+    # The entity operator runs the KafkaTopic assembly operator, which needs to access and manage KafkaTopic resources
+  - kafkatopics
+  - kafkatopics/status
+  # The entity operator runs the KafkaUser assembly operator, which needs to access and manage KafkaUser resources
+  - kafkausers
+  - kafkausers/status
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - patch
+  - update
+  - delete
+- apiGroups:
+  - ""
+  resources:
+  - events
+  verbs:
+    # The entity operator needs to be able to create events
+  - create
+- apiGroups:
+  - ""
+  resources:
+    # The entity operator user-operator needs to access and manage secrets to store generated credentials
+  - secrets
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+{{- end }}
diff --git a/helm/templates/strimzi/operator-role-binding.yaml b/helm/templates/strimzi/operator-role-binding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..82b48bd0fa7d1535c08b0e5c005088dc65df6999
--- /dev/null
+++ b/helm/templates/strimzi/operator-role-binding.yaml
@@ -0,0 +1,18 @@
+{{- if not (index .Values "strimzi-kafka-operator" "createGlobalResources") -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  labels:
+    app: strimzi
+  name: strimzi-cluster-operator-namespaced
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: strimzi-cluster-operator-namespaced
+subjects:
+- kind: ServiceAccount
+  name: strimzi-cluster-operator
+  namespace: {{ .Release.Namespace }}
+{{- end }}
+
diff --git a/helm/templates/strimzi/operator-role.yaml b/helm/templates/strimzi/operator-role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d5098ffc3af43d55208ddfc5e10535e73d22ac06
--- /dev/null
+++ b/helm/templates/strimzi/operator-role.yaml
@@ -0,0 +1,213 @@
+{{- if not (index .Values "strimzi-kafka-operator" "createGlobalResources") -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: strimzi-cluster-operator-namespaced
+  labels:
+    app: strimzi-cluster-operator-namespaced
+rules:
+- apiGroups:
+  - "rbac.authorization.k8s.io"
+  resources:
+    # The cluster operator needs to access and manage rolebindings to grant Strimzi components cluster permissions
+  - rolebindings
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - "rbac.authorization.k8s.io"
+  resources:
+    # The cluster operator needs to access and manage roles to grant the entity operator permissions
+  - roles
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - ""
+  resources:
+    # The cluster operator needs to access and delete pods, this is to allow it to monitor pod health and coordinate rolling updates
+  - pods
+    # The cluster operator needs to access and manage service accounts to grant Strimzi components cluster permissions
+  - serviceaccounts
+    # The cluster operator needs to access and manage config maps for Strimzi components configuration
+  - configmaps
+    # The cluster operator needs to access and manage services and endpoints to expose Strimzi components to network traffic
+  - services
+  - endpoints
+    # The cluster operator needs to access and manage secrets to handle credentials
+  - secrets
+    # The cluster operator needs to access and manage persistent volume claims to bind them to Strimzi components for persistent data
+  - persistentvolumeclaims
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - "kafka.strimzi.io"
+  resources:
+    # The cluster operator runs the KafkaAssemblyOperator, which needs to access and manage Kafka resources
+  - kafkas
+  - kafkas/status
+    # The cluster operator runs the KafkaConnectAssemblyOperator, which needs to access and manage KafkaConnect resources
+  - kafkaconnects
+  - kafkaconnects/status
+    # The cluster operator runs the KafkaConnectorAssemblyOperator, which needs to access and manage KafkaConnector resources
+  - kafkaconnectors
+  - kafkaconnectors/status
+    # The cluster operator runs the KafkaMirrorMakerAssemblyOperator, which needs to access and manage KafkaMirrorMaker resources
+  - kafkamirrormakers
+  - kafkamirrormakers/status
+    # The cluster operator runs the KafkaBridgeAssemblyOperator, which needs to access and manage BridgeMaker resources
+  - kafkabridges
+  - kafkabridges/status
+    # The cluster operator runs the KafkaMirrorMaker2AssemblyOperator, which needs to access and manage KafkaMirrorMaker2 resources
+  - kafkamirrormaker2s
+  - kafkamirrormaker2s/status
+    # The cluster operator runs the KafkaRebalanceAssemblyOperator, which needs to access and manage KafkaRebalance resources
+  - kafkarebalances
+  - kafkarebalances/status
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - "core.strimzi.io"
+  resources:
+    # The cluster operator uses StrimziPodSets to manage the Kafka and ZooKeeper pods
+  - strimzipodsets
+  - strimzipodsets/status
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+    # The cluster operator needs the extensions api as the operator supports Kubernetes version 1.11+
+    # apps/v1 was introduced in Kubernetes 1.14
+  - "extensions"
+  resources:
+    # The cluster operator needs to access and manage deployments to run deployment based Strimzi components
+  - deployments
+  - deployments/scale
+    # The cluster operator needs to access replica sets to manage Strimzi components and to determine error states
+  - replicasets
+    # The cluster operator needs to access and manage replication controllers to manage replicasets
+  - replicationcontrollers
+    # The cluster operator needs to access and manage network policies to lock down communication between Strimzi components
+  - networkpolicies
+    # The cluster operator needs to access and manage ingresses which allow external access to the services in a cluster
+  - ingresses
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - "apps"
+  resources:
+    # The cluster operator needs to access and manage deployments to run deployment based Strimzi components
+  - deployments
+  - deployments/scale
+  - deployments/status
+    # The cluster operator needs to access and manage stateful sets to run stateful sets based Strimzi components
+  - statefulsets
+    # The cluster operator needs to access replica-sets to manage Strimzi components and to determine error states
+  - replicasets
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - ""
+  resources:
+    # The cluster operator needs to be able to create events and delegate permissions to do so
+  - events
+  verbs:
+  - create
+- apiGroups:
+    # Kafka Connect Build on OpenShift requirement
+  - build.openshift.io
+  resources:
+  - buildconfigs
+  - buildconfigs/instantiate
+  - builds
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - networking.k8s.io
+  resources:
+    # The cluster operator needs to access and manage network policies to lock down communication between Strimzi components
+  - networkpolicies
+    # The cluster operator needs to access and manage ingresses which allow external access to the services in a cluster
+  - ingresses
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - route.openshift.io
+  resources:
+    # The cluster operator needs to access and manage routes to expose Strimzi components for external access
+  - routes
+  - routes/custom-host
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+- apiGroups:
+  - policy
+  resources:
+    # The cluster operator needs to access and manage pod disruption budgets this limits the number of concurrent disruptions
+    # that a Strimzi component experiences, allowing for higher availability
+  - poddisruptionbudgets
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+  - update
+{{- end }}
diff --git a/helm/templates/tests/test-connection.yaml b/helm/templates/tests/test-prometheus-connection.yaml
similarity index 73%
rename from helm/templates/tests/test-connection.yaml
rename to helm/templates/tests/test-prometheus-connection.yaml
index 7af87e98920c11bcfaccb27724e6f29fc76771a0..313a0825adf5d654642c6e1d8ff6beb4ee59df97 100644
--- a/helm/templates/tests/test-connection.yaml
+++ b/helm/templates/tests/test-prometheus-connection.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.prometheus.enabled }}
 apiVersion: v1
 kind: Pod
 metadata:
@@ -5,7 +6,8 @@ metadata:
   labels:
     {{- include "theodolite.labels" . | nindent 4 }}
   annotations:
-    "helm.sh/hook": test-success
+    "helm.sh/hook": test
+    "helm.sh/hook-delete-policy": hook-succeeded
 spec:
   containers:
     - name: wget
@@ -13,3 +15,4 @@ spec:
       command: ['wget']
       args: ['http://prometheus-operated:9090']
   restartPolicy: Never
+{{- end }}
diff --git a/helm/values.yaml b/helm/values.yaml
index 34a32ce60927a751f645b7f8ff4af46793865797..eb4cfc4b29fee97ab2be88a3ce2ded766a122b20 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -159,7 +159,7 @@ cp-helm-charts:
   pollIntervalSeconds: 15
 
 strimzi-kafka-operator:
-  createGlobalResources: true
+  createGlobalResources: false # Might disable some of Strimzi's features
 
 strimzi:
   enabled: true
diff --git a/slo-checker/generic/app/main.py b/slo-checker/generic/app/main.py
index f36c8739da00128ad94feb1f2d7871df7e2ff137..e483c26b4f421d00e093ad70ff8d12d0a9bb9e62 100644
--- a/slo-checker/generic/app/main.py
+++ b/slo-checker/generic/app/main.py
@@ -37,7 +37,7 @@ def aggr_query(values: dict, warmup: int, aggr_func):
     df = pd.DataFrame.from_dict(values)
     df.columns = ['timestamp', 'value']
     filtered = df[df['timestamp'] >= (df['timestamp'][0] + warmup)]
-    filtered['value'] = filtered['value'].astype(int)
+    filtered['value'] = filtered['value'].astype(float).astype(int)
     return filtered['value'].aggregate(aggr_func)
 
 def check_result(result, operator: str, threshold):
diff --git a/slo-checker/generic/resources/test-1-rep-success.json b/slo-checker/generic/resources/test-1-rep-success.json
index b70f461cf620d8eee8c4d9d93feb46db7498626f..9a6db686ec632f72f0d1981657826a8443b4c348 100644
--- a/slo-checker/generic/resources/test-1-rep-success.json
+++ b/slo-checker/generic/resources/test-1-rep-success.json
@@ -260,7 +260,7 @@
                     ],
                     [
                         1.634624989695E9,
-                        "1854284"
+                        "3970.0000000000005"
                     ]
                 ]
             }
diff --git a/theodolite-benchmarks/beam-commons/build.gradle b/theodolite-benchmarks/beam-commons/build.gradle
index 64ac2bb51ae1e6d741749a81e5c6c9e296d14d68..34a98212cdca9b347027c8e1c915044d55514b9c 100644
--- a/theodolite-benchmarks/beam-commons/build.gradle
+++ b/theodolite-benchmarks/beam-commons/build.gradle
@@ -13,8 +13,7 @@ repositories {
 }
 
 dependencies {
-  implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+  implementation project(':commons')
 
   implementation group: 'org.apache.beam', name: 'beam-sdks-java-core', version: '2.35.0'
   implementation('org.apache.beam:beam-sdks-java-io-kafka:2.35.0'){
diff --git a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/BeamService.java b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/BeamService.java
index 0165fa644e1853353e73caeaf0b9d2df0f8e9aea..4897f4171f96dea72d1c5c002c5f817a5f3e2ba2 100644
--- a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/BeamService.java
+++ b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/BeamService.java
@@ -10,7 +10,7 @@ import org.apache.beam.sdk.options.PipelineOptionsFactory;
 import org.apache.commons.configuration2.Configuration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import titan.ccp.common.configuration.ServiceConfigurations;
+import rocks.theodolite.benchmarks.commons.commons.configuration.ServiceConfigurations;
 
 /**
  * A general Apache Beam-based microservice. It is configured by Beam pipeline, a Beam runner and
diff --git a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/ActivePowerRecordDeserializer.java b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/ActivePowerRecordDeserializer.java
index 0c8d3a4a847cf9422c4e364a31024fb3d0c3f87a..8ab579d0cb2be846c715d5f16430371eb5952d2d 100644
--- a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/ActivePowerRecordDeserializer.java
+++ b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/ActivePowerRecordDeserializer.java
@@ -2,7 +2,8 @@ package rocks.theodolite.benchmarks.commons.beam.kafka;
 
 import io.confluent.kafka.streams.serdes.avro.SpecificAvroDeserializer;
 import org.apache.kafka.common.serialization.Deserializer;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+
 
 /**
  * A Kafka {@link Deserializer} for typed Schema Registry {@link ActivePowerRecord}.
diff --git a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/EventTimePolicy.java b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/EventTimePolicy.java
index 62e56341518839b96ad059e1c496ea1babb4674d..a63b5f4939566134a0aeec765fe084ea5bcc41ff 100644
--- a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/EventTimePolicy.java
+++ b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/EventTimePolicy.java
@@ -5,7 +5,7 @@ import org.apache.beam.sdk.io.kafka.KafkaRecord;
 import org.apache.beam.sdk.io.kafka.TimestampPolicy;
 import org.apache.beam.sdk.transforms.windowing.BoundedWindow;
 import org.joda.time.Instant;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * TimeStampPolicy to use event time based on the timestamp of the record value.
diff --git a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/KafkaActivePowerTimestampReader.java b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/KafkaActivePowerTimestampReader.java
index e22d5c8eedcd545364511a1461208f30bcb0a75c..31cd3e6be851bc0f0711cc17a591df6620951dc7 100644
--- a/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/KafkaActivePowerTimestampReader.java
+++ b/theodolite-benchmarks/beam-commons/src/main/java/rocks/theodolite/benchmarks/commons/beam/kafka/KafkaActivePowerTimestampReader.java
@@ -8,7 +8,7 @@ import org.apache.beam.sdk.values.KV;
 import org.apache.beam.sdk.values.PBegin;
 import org.apache.beam.sdk.values.PCollection;
 import org.apache.kafka.common.serialization.StringDeserializer;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Simple {@link PTransform} that reads from Kafka using {@link KafkaIO} with event time.
diff --git a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.beam.gradle b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.beam.gradle
index 5849bd93221794d135f1c6cb3bcb62d2174724b5..7783baaa215a12bba79f26e70d8ac8073252a780 100644
--- a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.beam.gradle
+++ b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.beam.gradle
@@ -22,8 +22,7 @@ def apacheBeamVersion =  '2.35.0'
 
 dependencies {
     // These dependencies are used internally, and not exposed to consumers on their own compile classpath.
-    implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-    implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+    implementation project(':commons')
     implementation 'com.google.guava:guava:24.1-jre'
     implementation 'org.slf4j:slf4j-simple:1.7.25'
     implementation project(':beam-commons')
diff --git a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.flink.gradle b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.flink.gradle
index 7671e602211b6d9e923a3b2a4c87f40fff84c6ec..5665de9d8ea42b88ef915189234ead634c66215c 100644
--- a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.flink.gradle
+++ b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.flink.gradle
@@ -35,9 +35,7 @@ repositories {
 }
 
 dependencies {
-    // Special version required because of https://issues.apache.org/jira/browse/FLINK-13703
-    implementation('org.industrial-devops:titan-ccp-common:0.1.0-flink-ready-SNAPSHOT') { changing = true }
-    implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+    implementation project(':commons')
 
     implementation 'org.apache.kafka:kafka-clients:2.2.0'
     implementation 'com.google.guava:guava:30.1-jre'
diff --git a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.hazelcastjet.gradle b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.hazelcastjet.gradle
index b092c97cf0e79895d4d6aafc594979b8f48dd167..0bade8fddc045f19b13074966d29996e26a72e77 100644
--- a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.hazelcastjet.gradle
+++ b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.hazelcastjet.gradle
@@ -17,13 +17,12 @@ repositories {
 }
 
 dependencies {
-  implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+  implementation project(':commons')
+
   implementation 'com.google.guava:guava:24.1-jre'
   implementation 'org.slf4j:slf4j-api:1.7.30'
   implementation 'org.slf4j:slf4j-simple:1.7.30'
 
-
   implementation 'io.confluent:kafka-avro-serializer:5.3.0'
 
   implementation 'com.hazelcast.jet:hazelcast-jet:4.5'
diff --git a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.kstreams.gradle b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.kstreams.gradle
index bf533915a8fdf4a712754857702373264a30f80a..f43b9bafe3b8135cb4606f109648fc1acb4fe024 100644
--- a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.kstreams.gradle
+++ b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.kstreams.gradle
@@ -20,8 +20,7 @@ repositories {
 
 dependencies {
     // These dependencies are used internally, and not exposed to consumers on their own compile classpath.
-    implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-    implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+    implementation project(':commons')
     implementation 'org.apache.kafka:kafka-streams:3.1.0'
     implementation 'com.google.guava:guava:24.1-jre'
     implementation 'org.slf4j:slf4j-simple:1.7.25'
diff --git a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.load-generator.gradle b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.load-generator.gradle
index fb4fd89d1fe8a6d625a3ba7b459e9b0961befdbc..b4927d53d0ed976a0f0dcecd6d096e3d6c7d9273 100644
--- a/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.load-generator.gradle
+++ b/theodolite-benchmarks/buildSrc/src/main/groovy/theodolite.load-generator.gradle
@@ -20,8 +20,7 @@ repositories {
 
 dependencies {
   // These dependencies are used internally, and not exposed to consumers on their own compile classpath.
-  implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+  implementation project(':commons')
   implementation 'org.slf4j:slf4j-simple:1.7.25'
 
   // These dependencies are used for the workload-generator-commmon
diff --git a/theodolite-benchmarks/commons/.settings/org.eclipse.jdt.ui.prefs b/theodolite-benchmarks/commons/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b2a15f439cf1844efe56f1ac0d82a2884e66cb9d
--- /dev/null
+++ b/theodolite-benchmarks/commons/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,286 @@
+cleanup.add_all=false
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=true
+cleanup.always_use_this_for_non_static_method_access=true
+cleanup.array_with_curly=false
+cleanup.arrays_fill=false
+cleanup.bitwise_conditional_expression=false
+cleanup.boolean_literal=false
+cleanup.boolean_value_rather_than_comparison=true
+cleanup.break_loop=false
+cleanup.collection_cloning=false
+cleanup.comparing_on_criteria=false
+cleanup.comparison_statement=false
+cleanup.controlflow_merge=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=true
+cleanup.convert_to_enhanced_for_loop_if_loop_var_used=true
+cleanup.convert_to_switch_expressions=false
+cleanup.correct_indentation=true
+cleanup.do_while_rather_than_while=true
+cleanup.double_negation=false
+cleanup.else_if=false
+cleanup.embedded_if=false
+cleanup.evaluate_nullable=false
+cleanup.extract_increment=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.hash=false
+cleanup.if_condition=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.instanceof=false
+cleanup.instanceof_keyword=false
+cleanup.invert_equals=false
+cleanup.join=false
+cleanup.lazy_logical_operator=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=true
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=true
+cleanup.map_cloning=false
+cleanup.merge_conditional_blocks=false
+cleanup.multi_catch=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.no_string_creation=false
+cleanup.no_super=false
+cleanup.number_suffix=false
+cleanup.objects_equals=false
+cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=true
+cleanup.operand_factorization=false
+cleanup.organize_imports=true
+cleanup.overridden_assignment=false
+cleanup.plain_replacement=false
+cleanup.precompile_regex=false
+cleanup.primitive_comparison=false
+cleanup.primitive_parsing=false
+cleanup.primitive_rather_than_wrapper=true
+cleanup.primitive_serialization=false
+cleanup.pull_out_if_from_if_else=false
+cleanup.pull_up_assignment=false
+cleanup.push_down_negation=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.reduce_indentation=false
+cleanup.redundant_comparator=false
+cleanup.redundant_falling_through_block_end=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_modifiers=false
+cleanup.remove_redundant_semicolons=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_array_creation=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.return_expression=false
+cleanup.simplify_lambda_expression_and_method_ref=false
+cleanup.single_used_field=false
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.standard_comparison=false
+cleanup.static_inner_class=false
+cleanup.strictly_equal_or_different=false
+cleanup.stringbuffer_to_stringbuilder=false
+cleanup.stringbuilder=false
+cleanup.stringbuilder_for_local_vars=true
+cleanup.stringconcat_to_textblock=false
+cleanup.substring=false
+cleanup.switch=false
+cleanup.system_property=false
+cleanup.system_property_boolean=false
+cleanup.system_property_file_encoding=false
+cleanup.system_property_file_separator=false
+cleanup.system_property_line_separator=false
+cleanup.system_property_path_separator=false
+cleanup.ternary_operator=false
+cleanup.try_with_resource=false
+cleanup.unlooped_while=false
+cleanup.unreachable_block=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_autoboxing=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_directly_map_method=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=true
+cleanup.use_string_is_blank=false
+cleanup.use_this_for_non_static_field_access=true
+cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+cleanup.use_this_for_non_static_method_access=true
+cleanup.use_this_for_non_static_method_access_only_if_necessary=false
+cleanup.use_unboxing=false
+cleanup.use_var=false
+cleanup.useless_continue=false
+cleanup.useless_return=false
+cleanup.valueof_rather_than_instantiation=false
+cleanup_profile=_CAU-SE-Style
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_CAU-SE-Style
+formatter_settings_version=21
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=true
+sp_cleanup.always_use_this_for_non_static_method_access=true
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=true
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
+sp_cleanup.correct_indentation=true
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=true
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
+sp_cleanup.organize_imports=true
+sp_cleanup.overridden_assignment=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=true
+sp_cleanup.use_string_is_blank=false
+sp_cleanup.use_this_for_non_static_field_access=true
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+sp_cleanup.use_this_for_non_static_method_access=true
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=false
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=true
+sp_cleanup.useless_return=true
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/theodolite-benchmarks/commons/.settings/qa.eclipse.plugin.checkstyle.prefs b/theodolite-benchmarks/commons/.settings/qa.eclipse.plugin.checkstyle.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..4fa4266c755f4ff8da465ab7341cd70ffb24ecf7
--- /dev/null
+++ b/theodolite-benchmarks/commons/.settings/qa.eclipse.plugin.checkstyle.prefs
@@ -0,0 +1,4 @@
+configFilePath=../config/checkstyle.xml
+customModulesJarPaths=
+eclipse.preferences.version=1
+enabled=false
diff --git a/theodolite-benchmarks/commons/.settings/qa.eclipse.plugin.pmd.prefs b/theodolite-benchmarks/commons/.settings/qa.eclipse.plugin.pmd.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..40bfd0ecdbbe324bb54e4b9f9f32ba95cf5b0c2a
--- /dev/null
+++ b/theodolite-benchmarks/commons/.settings/qa.eclipse.plugin.pmd.prefs
@@ -0,0 +1,4 @@
+customRulesJars=
+eclipse.preferences.version=1
+enabled=false
+ruleSetFilePath=../config/pmd.xml
diff --git a/theodolite-benchmarks/commons/build.gradle b/theodolite-benchmarks/commons/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..2b00b6619f813ec83031585b86e51a0f1a0e43ed
--- /dev/null
+++ b/theodolite-benchmarks/commons/build.gradle
@@ -0,0 +1,93 @@
+plugins {
+    // common java conventions
+    id 'theodolite.java-commons'
+    // avro plugin
+    id "com.github.davidmc24.gradle.plugin.avro-base" version "1.3.0"
+}
+
+
+
+repositories {
+    mavenCentral()
+    maven {
+        url "https://oss.sonatype.org/content/repositories/snapshots/"
+    }
+    maven {
+        url 'https://packages.confluent.io/maven/'
+    }
+}
+
+dependencies {
+    // These dependencies is exported to consumers, that is to say found on their compile classpath.
+    api 'org.apache.commons:commons-configuration2:2.0'
+    api "org.apache.avro:avro:1.11.0"
+    api 'org.apache.kafka:kafka-streams:2.4.0' // needed in flink uc3
+
+    // These dependencies are used internally, and not exposed to consumers on their own compile classpath.
+    implementation 'commons-beanutils:commons-beanutils:1.9.2' // necessary for commons-configuration2
+    implementation 'com.google.code.gson:gson:2.8.2'
+    implementation 'com.google.guava:guava:24.1-jre'
+    implementation 'org.slf4j:slf4j-api:1.7.25'
+    implementation 'org.apache.kafka:kafka-clients:2.4.0'
+    implementation ('io.confluent:kafka-streams-avro-serde:5.3.2') {
+        // Kafka client is already included from Kafka Streams in version 2.4.0
+        exclude group: 'org.apache.kafka', module: 'kafka-clients'
+    }
+
+    // Use JUnit test framework
+    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
+    testImplementation 'com.github.stefanbirkner:system-rules:1.17.0'
+}
+
+
+// Local sources
+sourceSets {
+    main {
+        java {
+            srcDir 'src/main/java'
+            srcDir 'src-gen/main/java'
+        }
+    }
+}
+
+
+// Local avro creation
+avro {
+    fieldVisibility = "PRIVATE"
+    // Setters required for flink because of https://issues.apache.org/jira/browse/FLINK-13703
+    createSetters = true
+}
+
+task("generateAvroProtocol", type: com.github.davidmc24.gradle.plugin.avro.GenerateAvroProtocolTask) {
+    group 'Generate Sources'
+    source file("src/main/avro")
+    include("**/*.avdl")
+    outputDir = file("build/generated-avro-main-avpr")
+}
+
+task("generateAvroSchema", type: com.github.davidmc24.gradle.plugin.avro.GenerateAvroSchemaTask) {
+    group 'Generate Sources'
+    dependsOn generateAvroProtocol
+    source file("src/main/avro")
+    source file("build/generated-avro-main-avpr")
+    include("**/*.avpr")
+    outputDir = file("src-gen/main/avro")
+}
+
+task ("generateAvroJava", type: com.github.davidmc24.gradle.plugin.avro.GenerateAvroJavaTask) {
+    group 'Generate Sources'
+    dependsOn generateAvroSchema
+    source file("src-gen/main/avro")
+    outputDir = file("src-gen/main/java")
+}
+
+tasks.withType(Checkstyle) {
+    source = fileTree('src/main/java')
+}
+
+tasks.withType(Pmd) {
+    exclude '**/commons/src-gen/.*'
+}
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/ActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/ActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..91f1168632267b6d69f1b22aed658897d95958b1
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/ActivePowerRecord.avsc
@@ -0,0 +1,18 @@
+{
+  "type" : "record",
+  "name" : "ActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string",
+    "doc" : "*"
+  }, {
+    "name" : "timestamp",
+    "type" : "long",
+    "doc" : "*"
+  }, {
+    "name" : "valueInW",
+    "type" : "double",
+    "doc" : "*"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/AggregatedActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/AggregatedActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..336476e8417a5b7245eea1a1c6b2b454fcc11001
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/AggregatedActivePowerRecord.avsc
@@ -0,0 +1,26 @@
+{
+  "type" : "record",
+  "name" : "AggregatedActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string",
+    "doc" : "*"
+  }, {
+    "name" : "timestamp",
+    "type" : "long",
+    "doc" : "*"
+  }, {
+    "name" : "count",
+    "type" : "long",
+    "doc" : "*"
+  }, {
+    "name" : "sumInW",
+    "type" : "double",
+    "doc" : "*"
+  }, {
+    "name" : "averageInW",
+    "type" : "double",
+    "doc" : "*"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/DayOfWeekActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/DayOfWeekActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..c029937dd0d17e0a14bb613a59dff6f72635f009
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/DayOfWeekActivePowerRecord.avsc
@@ -0,0 +1,33 @@
+{
+  "type" : "record",
+  "name" : "DayOfWeekActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string"
+  }, {
+    "name" : "dayOfWeek",
+    "type" : "int"
+  }, {
+    "name" : "periodStart",
+    "type" : "long"
+  }, {
+    "name" : "periodEnd",
+    "type" : "long"
+  }, {
+    "name" : "count",
+    "type" : "long"
+  }, {
+    "name" : "mean",
+    "type" : "double"
+  }, {
+    "name" : "populationVariance",
+    "type" : "double"
+  }, {
+    "name" : "min",
+    "type" : "double"
+  }, {
+    "name" : "max",
+    "type" : "double"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/HourOfDayActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/HourOfDayActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..3ad6d6ade5d2f29718db04e066565a11f2db412d
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/HourOfDayActivePowerRecord.avsc
@@ -0,0 +1,33 @@
+{
+  "type" : "record",
+  "name" : "HourOfDayActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string"
+  }, {
+    "name" : "hourOfDay",
+    "type" : "int"
+  }, {
+    "name" : "periodStart",
+    "type" : "long"
+  }, {
+    "name" : "periodEnd",
+    "type" : "long"
+  }, {
+    "name" : "count",
+    "type" : "long"
+  }, {
+    "name" : "mean",
+    "type" : "double"
+  }, {
+    "name" : "populationVariance",
+    "type" : "double"
+  }, {
+    "name" : "min",
+    "type" : "double"
+  }, {
+    "name" : "max",
+    "type" : "double"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/HourOfWeekActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/HourOfWeekActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..74739f5bd074ba330cee631c433ea4ab1c1fa8d9
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/HourOfWeekActivePowerRecord.avsc
@@ -0,0 +1,36 @@
+{
+  "type" : "record",
+  "name" : "HourOfWeekActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string"
+  }, {
+    "name" : "dayOfWeek",
+    "type" : "int"
+  }, {
+    "name" : "hourOfDay",
+    "type" : "int"
+  }, {
+    "name" : "periodStart",
+    "type" : "long"
+  }, {
+    "name" : "periodEnd",
+    "type" : "long"
+  }, {
+    "name" : "count",
+    "type" : "long"
+  }, {
+    "name" : "mean",
+    "type" : "double"
+  }, {
+    "name" : "populationVariance",
+    "type" : "double"
+  }, {
+    "name" : "min",
+    "type" : "double"
+  }, {
+    "name" : "max",
+    "type" : "double"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/MonthOfYearActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/MonthOfYearActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..70dd7eda5b5aaa6bb27b2ebca4ac7f4b251c630f
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/MonthOfYearActivePowerRecord.avsc
@@ -0,0 +1,33 @@
+{
+  "type" : "record",
+  "name" : "MonthOfYearActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string"
+  }, {
+    "name" : "monthOfYear",
+    "type" : "int"
+  }, {
+    "name" : "periodStart",
+    "type" : "long"
+  }, {
+    "name" : "periodEnd",
+    "type" : "long"
+  }, {
+    "name" : "count",
+    "type" : "long"
+  }, {
+    "name" : "mean",
+    "type" : "double"
+  }, {
+    "name" : "populationVariance",
+    "type" : "double"
+  }, {
+    "name" : "min",
+    "type" : "double"
+  }, {
+    "name" : "max",
+    "type" : "double"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/YearActivePowerRecord.avsc b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/YearActivePowerRecord.avsc
new file mode 100644
index 0000000000000000000000000000000000000000..2bfc06b6649630fbde85f068e5b3a9d0312f5424
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/avro/rocks/theodolite/benchmarks/commons/model/records/YearActivePowerRecord.avsc
@@ -0,0 +1,33 @@
+{
+  "type" : "record",
+  "name" : "YearActivePowerRecord",
+  "namespace" : "rocks.theodolite.benchmarks.commons.model.records",
+  "fields" : [ {
+    "name" : "identifier",
+    "type" : "string"
+  }, {
+    "name" : "year",
+    "type" : "int"
+  }, {
+    "name" : "periodStart",
+    "type" : "long"
+  }, {
+    "name" : "periodEnd",
+    "type" : "long"
+  }, {
+    "name" : "count",
+    "type" : "long"
+  }, {
+    "name" : "mean",
+    "type" : "double"
+  }, {
+    "name" : "populationVariance",
+    "type" : "double"
+  }, {
+    "name" : "min",
+    "type" : "double"
+  }, {
+    "name" : "max",
+    "type" : "double"
+  } ]
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/ActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/ActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..27e0f39076e5384a89e3d8a91e4b08808244aa2a
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/ActivePowerRecord.java
@@ -0,0 +1,492 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class ActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = -5809432381123606133L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"ActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"},\"doc\":\"*\"},{\"name\":\"timestamp\",\"type\":\"long\",\"doc\":\"*\"},{\"name\":\"valueInW\",\"type\":\"double\",\"doc\":\"*\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<ActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<ActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<ActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<ActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<ActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<ActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<ActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<ActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this ActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a ActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a ActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static ActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  /** * */
+  private java.lang.String identifier;
+  /** * */
+  private long timestamp;
+  /** * */
+  private double valueInW;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public ActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier *
+   * @param timestamp *
+   * @param valueInW *
+   */
+  public ActivePowerRecord(java.lang.String identifier, java.lang.Long timestamp, java.lang.Double valueInW) {
+    this.identifier = identifier;
+    this.timestamp = timestamp;
+    this.valueInW = valueInW;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return timestamp;
+    case 2: return valueInW;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: timestamp = (java.lang.Long)value$; break;
+    case 2: valueInW = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return *
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'timestamp' field.
+   * @return *
+   */
+  public long getTimestamp() {
+    return timestamp;
+  }
+
+
+  /**
+   * Sets the value of the 'timestamp' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setTimestamp(long value) {
+    this.timestamp = value;
+  }
+
+  /**
+   * Gets the value of the 'valueInW' field.
+   * @return *
+   */
+  public double getValueInW() {
+    return valueInW;
+  }
+
+
+  /**
+   * Sets the value of the 'valueInW' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setValueInW(double value) {
+    this.valueInW = value;
+  }
+
+  /**
+   * Creates a new ActivePowerRecord RecordBuilder.
+   * @return A new ActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new ActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new ActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new ActivePowerRecord RecordBuilder by copying an existing ActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new ActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for ActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<ActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<ActivePowerRecord> {
+
+    /** * */
+    private java.lang.String identifier;
+    /** * */
+    private long timestamp;
+    /** * */
+    private double valueInW;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.timestamp)) {
+        this.timestamp = data().deepCopy(fields()[1].schema(), other.timestamp);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.valueInW)) {
+        this.valueInW = data().deepCopy(fields()[2].schema(), other.valueInW);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing ActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.timestamp)) {
+        this.timestamp = data().deepCopy(fields()[1].schema(), other.timestamp);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.valueInW)) {
+        this.valueInW = data().deepCopy(fields()[2].schema(), other.valueInW);
+        fieldSetFlags()[2] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * *
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * *
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * *
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'timestamp' field.
+      * *
+      * @return The value.
+      */
+    public long getTimestamp() {
+      return timestamp;
+    }
+
+
+    /**
+      * Sets the value of the 'timestamp' field.
+      * *
+      * @param value The value of 'timestamp'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder setTimestamp(long value) {
+      validate(fields()[1], value);
+      this.timestamp = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'timestamp' field has been set.
+      * *
+      * @return True if the 'timestamp' field has been set, false otherwise.
+      */
+    public boolean hasTimestamp() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'timestamp' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder clearTimestamp() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'valueInW' field.
+      * *
+      * @return The value.
+      */
+    public double getValueInW() {
+      return valueInW;
+    }
+
+
+    /**
+      * Sets the value of the 'valueInW' field.
+      * *
+      * @param value The value of 'valueInW'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder setValueInW(double value) {
+      validate(fields()[2], value);
+      this.valueInW = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'valueInW' field has been set.
+      * *
+      * @return True if the 'valueInW' field has been set, false otherwise.
+      */
+    public boolean hasValueInW() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'valueInW' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord.Builder clearValueInW() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public ActivePowerRecord build() {
+      try {
+        ActivePowerRecord record = new ActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.timestamp = fieldSetFlags()[1] ? this.timestamp : (java.lang.Long) defaultValue(fields()[1]);
+        record.valueInW = fieldSetFlags()[2] ? this.valueInW : (java.lang.Double) defaultValue(fields()[2]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<ActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<ActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<ActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<ActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeLong(this.timestamp);
+
+    out.writeDouble(this.valueInW);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.timestamp = in.readLong();
+
+      this.valueInW = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 3; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.timestamp = in.readLong();
+          break;
+
+        case 2:
+          this.valueInW = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/AggregatedActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/AggregatedActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..7aa6e0b5f988bae1f63d8a2817a1fed2b4880b6a
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/AggregatedActivePowerRecord.java
@@ -0,0 +1,664 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class AggregatedActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = 334342381382209426L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AggregatedActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"},\"doc\":\"*\"},{\"name\":\"timestamp\",\"type\":\"long\",\"doc\":\"*\"},{\"name\":\"count\",\"type\":\"long\",\"doc\":\"*\"},{\"name\":\"sumInW\",\"type\":\"double\",\"doc\":\"*\"},{\"name\":\"averageInW\",\"type\":\"double\",\"doc\":\"*\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<AggregatedActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<AggregatedActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<AggregatedActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<AggregatedActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<AggregatedActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<AggregatedActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<AggregatedActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<AggregatedActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this AggregatedActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a AggregatedActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a AggregatedActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static AggregatedActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  /** * */
+  private java.lang.String identifier;
+  /** * */
+  private long timestamp;
+  /** * */
+  private long count;
+  /** * */
+  private double sumInW;
+  /** * */
+  private double averageInW;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public AggregatedActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier *
+   * @param timestamp *
+   * @param count *
+   * @param sumInW *
+   * @param averageInW *
+   */
+  public AggregatedActivePowerRecord(java.lang.String identifier, java.lang.Long timestamp, java.lang.Long count, java.lang.Double sumInW, java.lang.Double averageInW) {
+    this.identifier = identifier;
+    this.timestamp = timestamp;
+    this.count = count;
+    this.sumInW = sumInW;
+    this.averageInW = averageInW;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return timestamp;
+    case 2: return count;
+    case 3: return sumInW;
+    case 4: return averageInW;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: timestamp = (java.lang.Long)value$; break;
+    case 2: count = (java.lang.Long)value$; break;
+    case 3: sumInW = (java.lang.Double)value$; break;
+    case 4: averageInW = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return *
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'timestamp' field.
+   * @return *
+   */
+  public long getTimestamp() {
+    return timestamp;
+  }
+
+
+  /**
+   * Sets the value of the 'timestamp' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setTimestamp(long value) {
+    this.timestamp = value;
+  }
+
+  /**
+   * Gets the value of the 'count' field.
+   * @return *
+   */
+  public long getCount() {
+    return count;
+  }
+
+
+  /**
+   * Sets the value of the 'count' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setCount(long value) {
+    this.count = value;
+  }
+
+  /**
+   * Gets the value of the 'sumInW' field.
+   * @return *
+   */
+  public double getSumInW() {
+    return sumInW;
+  }
+
+
+  /**
+   * Sets the value of the 'sumInW' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setSumInW(double value) {
+    this.sumInW = value;
+  }
+
+  /**
+   * Gets the value of the 'averageInW' field.
+   * @return *
+   */
+  public double getAverageInW() {
+    return averageInW;
+  }
+
+
+  /**
+   * Sets the value of the 'averageInW' field.
+   * *
+   * @param value the value to set.
+   */
+  public void setAverageInW(double value) {
+    this.averageInW = value;
+  }
+
+  /**
+   * Creates a new AggregatedActivePowerRecord RecordBuilder.
+   * @return A new AggregatedActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new AggregatedActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new AggregatedActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new AggregatedActivePowerRecord RecordBuilder by copying an existing AggregatedActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new AggregatedActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for AggregatedActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<AggregatedActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<AggregatedActivePowerRecord> {
+
+    /** * */
+    private java.lang.String identifier;
+    /** * */
+    private long timestamp;
+    /** * */
+    private long count;
+    /** * */
+    private double sumInW;
+    /** * */
+    private double averageInW;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.timestamp)) {
+        this.timestamp = data().deepCopy(fields()[1].schema(), other.timestamp);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.count)) {
+        this.count = data().deepCopy(fields()[2].schema(), other.count);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+      if (isValidValue(fields()[3], other.sumInW)) {
+        this.sumInW = data().deepCopy(fields()[3].schema(), other.sumInW);
+        fieldSetFlags()[3] = other.fieldSetFlags()[3];
+      }
+      if (isValidValue(fields()[4], other.averageInW)) {
+        this.averageInW = data().deepCopy(fields()[4].schema(), other.averageInW);
+        fieldSetFlags()[4] = other.fieldSetFlags()[4];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing AggregatedActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.timestamp)) {
+        this.timestamp = data().deepCopy(fields()[1].schema(), other.timestamp);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.count)) {
+        this.count = data().deepCopy(fields()[2].schema(), other.count);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.sumInW)) {
+        this.sumInW = data().deepCopy(fields()[3].schema(), other.sumInW);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.averageInW)) {
+        this.averageInW = data().deepCopy(fields()[4].schema(), other.averageInW);
+        fieldSetFlags()[4] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * *
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * *
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * *
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'timestamp' field.
+      * *
+      * @return The value.
+      */
+    public long getTimestamp() {
+      return timestamp;
+    }
+
+
+    /**
+      * Sets the value of the 'timestamp' field.
+      * *
+      * @param value The value of 'timestamp'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder setTimestamp(long value) {
+      validate(fields()[1], value);
+      this.timestamp = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'timestamp' field has been set.
+      * *
+      * @return True if the 'timestamp' field has been set, false otherwise.
+      */
+    public boolean hasTimestamp() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'timestamp' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder clearTimestamp() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'count' field.
+      * *
+      * @return The value.
+      */
+    public long getCount() {
+      return count;
+    }
+
+
+    /**
+      * Sets the value of the 'count' field.
+      * *
+      * @param value The value of 'count'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder setCount(long value) {
+      validate(fields()[2], value);
+      this.count = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'count' field has been set.
+      * *
+      * @return True if the 'count' field has been set, false otherwise.
+      */
+    public boolean hasCount() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'count' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder clearCount() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'sumInW' field.
+      * *
+      * @return The value.
+      */
+    public double getSumInW() {
+      return sumInW;
+    }
+
+
+    /**
+      * Sets the value of the 'sumInW' field.
+      * *
+      * @param value The value of 'sumInW'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder setSumInW(double value) {
+      validate(fields()[3], value);
+      this.sumInW = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'sumInW' field has been set.
+      * *
+      * @return True if the 'sumInW' field has been set, false otherwise.
+      */
+    public boolean hasSumInW() {
+      return fieldSetFlags()[3];
+    }
+
+
+    /**
+      * Clears the value of the 'sumInW' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder clearSumInW() {
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'averageInW' field.
+      * *
+      * @return The value.
+      */
+    public double getAverageInW() {
+      return averageInW;
+    }
+
+
+    /**
+      * Sets the value of the 'averageInW' field.
+      * *
+      * @param value The value of 'averageInW'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder setAverageInW(double value) {
+      validate(fields()[4], value);
+      this.averageInW = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'averageInW' field has been set.
+      * *
+      * @return True if the 'averageInW' field has been set, false otherwise.
+      */
+    public boolean hasAverageInW() {
+      return fieldSetFlags()[4];
+    }
+
+
+    /**
+      * Clears the value of the 'averageInW' field.
+      * *
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord.Builder clearAverageInW() {
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public AggregatedActivePowerRecord build() {
+      try {
+        AggregatedActivePowerRecord record = new AggregatedActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.timestamp = fieldSetFlags()[1] ? this.timestamp : (java.lang.Long) defaultValue(fields()[1]);
+        record.count = fieldSetFlags()[2] ? this.count : (java.lang.Long) defaultValue(fields()[2]);
+        record.sumInW = fieldSetFlags()[3] ? this.sumInW : (java.lang.Double) defaultValue(fields()[3]);
+        record.averageInW = fieldSetFlags()[4] ? this.averageInW : (java.lang.Double) defaultValue(fields()[4]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<AggregatedActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<AggregatedActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<AggregatedActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<AggregatedActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeLong(this.timestamp);
+
+    out.writeLong(this.count);
+
+    out.writeDouble(this.sumInW);
+
+    out.writeDouble(this.averageInW);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.timestamp = in.readLong();
+
+      this.count = in.readLong();
+
+      this.sumInW = in.readDouble();
+
+      this.averageInW = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 5; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.timestamp = in.readLong();
+          break;
+
+        case 2:
+          this.count = in.readLong();
+          break;
+
+        case 3:
+          this.sumInW = in.readDouble();
+          break;
+
+        case 4:
+          this.averageInW = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/DayOfWeekActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/DayOfWeekActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e6917a6393f6b7deea3237384f08094a9cfc200
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/DayOfWeekActivePowerRecord.java
@@ -0,0 +1,945 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class DayOfWeekActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = 874988617222069934L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"DayOfWeekActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"dayOfWeek\",\"type\":\"int\"},{\"name\":\"periodStart\",\"type\":\"long\"},{\"name\":\"periodEnd\",\"type\":\"long\"},{\"name\":\"count\",\"type\":\"long\"},{\"name\":\"mean\",\"type\":\"double\"},{\"name\":\"populationVariance\",\"type\":\"double\"},{\"name\":\"min\",\"type\":\"double\"},{\"name\":\"max\",\"type\":\"double\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<DayOfWeekActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<DayOfWeekActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<DayOfWeekActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<DayOfWeekActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<DayOfWeekActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<DayOfWeekActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<DayOfWeekActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<DayOfWeekActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this DayOfWeekActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a DayOfWeekActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a DayOfWeekActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static DayOfWeekActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  private java.lang.String identifier;
+  private int dayOfWeek;
+  private long periodStart;
+  private long periodEnd;
+  private long count;
+  private double mean;
+  private double populationVariance;
+  private double min;
+  private double max;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public DayOfWeekActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier The new value for identifier
+   * @param dayOfWeek The new value for dayOfWeek
+   * @param periodStart The new value for periodStart
+   * @param periodEnd The new value for periodEnd
+   * @param count The new value for count
+   * @param mean The new value for mean
+   * @param populationVariance The new value for populationVariance
+   * @param min The new value for min
+   * @param max The new value for max
+   */
+  public DayOfWeekActivePowerRecord(java.lang.String identifier, java.lang.Integer dayOfWeek, java.lang.Long periodStart, java.lang.Long periodEnd, java.lang.Long count, java.lang.Double mean, java.lang.Double populationVariance, java.lang.Double min, java.lang.Double max) {
+    this.identifier = identifier;
+    this.dayOfWeek = dayOfWeek;
+    this.periodStart = periodStart;
+    this.periodEnd = periodEnd;
+    this.count = count;
+    this.mean = mean;
+    this.populationVariance = populationVariance;
+    this.min = min;
+    this.max = max;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return dayOfWeek;
+    case 2: return periodStart;
+    case 3: return periodEnd;
+    case 4: return count;
+    case 5: return mean;
+    case 6: return populationVariance;
+    case 7: return min;
+    case 8: return max;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: dayOfWeek = (java.lang.Integer)value$; break;
+    case 2: periodStart = (java.lang.Long)value$; break;
+    case 3: periodEnd = (java.lang.Long)value$; break;
+    case 4: count = (java.lang.Long)value$; break;
+    case 5: mean = (java.lang.Double)value$; break;
+    case 6: populationVariance = (java.lang.Double)value$; break;
+    case 7: min = (java.lang.Double)value$; break;
+    case 8: max = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return The value of the 'identifier' field.
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'dayOfWeek' field.
+   * @return The value of the 'dayOfWeek' field.
+   */
+  public int getDayOfWeek() {
+    return dayOfWeek;
+  }
+
+
+  /**
+   * Sets the value of the 'dayOfWeek' field.
+   * @param value the value to set.
+   */
+  public void setDayOfWeek(int value) {
+    this.dayOfWeek = value;
+  }
+
+  /**
+   * Gets the value of the 'periodStart' field.
+   * @return The value of the 'periodStart' field.
+   */
+  public long getPeriodStart() {
+    return periodStart;
+  }
+
+
+  /**
+   * Sets the value of the 'periodStart' field.
+   * @param value the value to set.
+   */
+  public void setPeriodStart(long value) {
+    this.periodStart = value;
+  }
+
+  /**
+   * Gets the value of the 'periodEnd' field.
+   * @return The value of the 'periodEnd' field.
+   */
+  public long getPeriodEnd() {
+    return periodEnd;
+  }
+
+
+  /**
+   * Sets the value of the 'periodEnd' field.
+   * @param value the value to set.
+   */
+  public void setPeriodEnd(long value) {
+    this.periodEnd = value;
+  }
+
+  /**
+   * Gets the value of the 'count' field.
+   * @return The value of the 'count' field.
+   */
+  public long getCount() {
+    return count;
+  }
+
+
+  /**
+   * Sets the value of the 'count' field.
+   * @param value the value to set.
+   */
+  public void setCount(long value) {
+    this.count = value;
+  }
+
+  /**
+   * Gets the value of the 'mean' field.
+   * @return The value of the 'mean' field.
+   */
+  public double getMean() {
+    return mean;
+  }
+
+
+  /**
+   * Sets the value of the 'mean' field.
+   * @param value the value to set.
+   */
+  public void setMean(double value) {
+    this.mean = value;
+  }
+
+  /**
+   * Gets the value of the 'populationVariance' field.
+   * @return The value of the 'populationVariance' field.
+   */
+  public double getPopulationVariance() {
+    return populationVariance;
+  }
+
+
+  /**
+   * Sets the value of the 'populationVariance' field.
+   * @param value the value to set.
+   */
+  public void setPopulationVariance(double value) {
+    this.populationVariance = value;
+  }
+
+  /**
+   * Gets the value of the 'min' field.
+   * @return The value of the 'min' field.
+   */
+  public double getMin() {
+    return min;
+  }
+
+
+  /**
+   * Sets the value of the 'min' field.
+   * @param value the value to set.
+   */
+  public void setMin(double value) {
+    this.min = value;
+  }
+
+  /**
+   * Gets the value of the 'max' field.
+   * @return The value of the 'max' field.
+   */
+  public double getMax() {
+    return max;
+  }
+
+
+  /**
+   * Sets the value of the 'max' field.
+   * @param value the value to set.
+   */
+  public void setMax(double value) {
+    this.max = value;
+  }
+
+  /**
+   * Creates a new DayOfWeekActivePowerRecord RecordBuilder.
+   * @return A new DayOfWeekActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new DayOfWeekActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new DayOfWeekActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new DayOfWeekActivePowerRecord RecordBuilder by copying an existing DayOfWeekActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new DayOfWeekActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for DayOfWeekActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<DayOfWeekActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<DayOfWeekActivePowerRecord> {
+
+    private java.lang.String identifier;
+    private int dayOfWeek;
+    private long periodStart;
+    private long periodEnd;
+    private long count;
+    private double mean;
+    private double populationVariance;
+    private double min;
+    private double max;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.dayOfWeek)) {
+        this.dayOfWeek = data().deepCopy(fields()[1].schema(), other.dayOfWeek);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = other.fieldSetFlags()[3];
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = other.fieldSetFlags()[4];
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = other.fieldSetFlags()[5];
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = other.fieldSetFlags()[6];
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = other.fieldSetFlags()[7];
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = other.fieldSetFlags()[8];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing DayOfWeekActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.dayOfWeek)) {
+        this.dayOfWeek = data().deepCopy(fields()[1].schema(), other.dayOfWeek);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = true;
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = true;
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = true;
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = true;
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'dayOfWeek' field.
+      * @return The value.
+      */
+    public int getDayOfWeek() {
+      return dayOfWeek;
+    }
+
+
+    /**
+      * Sets the value of the 'dayOfWeek' field.
+      * @param value The value of 'dayOfWeek'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setDayOfWeek(int value) {
+      validate(fields()[1], value);
+      this.dayOfWeek = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'dayOfWeek' field has been set.
+      * @return True if the 'dayOfWeek' field has been set, false otherwise.
+      */
+    public boolean hasDayOfWeek() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'dayOfWeek' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearDayOfWeek() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodStart' field.
+      * @return The value.
+      */
+    public long getPeriodStart() {
+      return periodStart;
+    }
+
+
+    /**
+      * Sets the value of the 'periodStart' field.
+      * @param value The value of 'periodStart'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setPeriodStart(long value) {
+      validate(fields()[2], value);
+      this.periodStart = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodStart' field has been set.
+      * @return True if the 'periodStart' field has been set, false otherwise.
+      */
+    public boolean hasPeriodStart() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'periodStart' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearPeriodStart() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodEnd' field.
+      * @return The value.
+      */
+    public long getPeriodEnd() {
+      return periodEnd;
+    }
+
+
+    /**
+      * Sets the value of the 'periodEnd' field.
+      * @param value The value of 'periodEnd'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setPeriodEnd(long value) {
+      validate(fields()[3], value);
+      this.periodEnd = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodEnd' field has been set.
+      * @return True if the 'periodEnd' field has been set, false otherwise.
+      */
+    public boolean hasPeriodEnd() {
+      return fieldSetFlags()[3];
+    }
+
+
+    /**
+      * Clears the value of the 'periodEnd' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearPeriodEnd() {
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'count' field.
+      * @return The value.
+      */
+    public long getCount() {
+      return count;
+    }
+
+
+    /**
+      * Sets the value of the 'count' field.
+      * @param value The value of 'count'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setCount(long value) {
+      validate(fields()[4], value);
+      this.count = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'count' field has been set.
+      * @return True if the 'count' field has been set, false otherwise.
+      */
+    public boolean hasCount() {
+      return fieldSetFlags()[4];
+    }
+
+
+    /**
+      * Clears the value of the 'count' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearCount() {
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'mean' field.
+      * @return The value.
+      */
+    public double getMean() {
+      return mean;
+    }
+
+
+    /**
+      * Sets the value of the 'mean' field.
+      * @param value The value of 'mean'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setMean(double value) {
+      validate(fields()[5], value);
+      this.mean = value;
+      fieldSetFlags()[5] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'mean' field has been set.
+      * @return True if the 'mean' field has been set, false otherwise.
+      */
+    public boolean hasMean() {
+      return fieldSetFlags()[5];
+    }
+
+
+    /**
+      * Clears the value of the 'mean' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearMean() {
+      fieldSetFlags()[5] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'populationVariance' field.
+      * @return The value.
+      */
+    public double getPopulationVariance() {
+      return populationVariance;
+    }
+
+
+    /**
+      * Sets the value of the 'populationVariance' field.
+      * @param value The value of 'populationVariance'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setPopulationVariance(double value) {
+      validate(fields()[6], value);
+      this.populationVariance = value;
+      fieldSetFlags()[6] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'populationVariance' field has been set.
+      * @return True if the 'populationVariance' field has been set, false otherwise.
+      */
+    public boolean hasPopulationVariance() {
+      return fieldSetFlags()[6];
+    }
+
+
+    /**
+      * Clears the value of the 'populationVariance' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearPopulationVariance() {
+      fieldSetFlags()[6] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'min' field.
+      * @return The value.
+      */
+    public double getMin() {
+      return min;
+    }
+
+
+    /**
+      * Sets the value of the 'min' field.
+      * @param value The value of 'min'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setMin(double value) {
+      validate(fields()[7], value);
+      this.min = value;
+      fieldSetFlags()[7] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'min' field has been set.
+      * @return True if the 'min' field has been set, false otherwise.
+      */
+    public boolean hasMin() {
+      return fieldSetFlags()[7];
+    }
+
+
+    /**
+      * Clears the value of the 'min' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearMin() {
+      fieldSetFlags()[7] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'max' field.
+      * @return The value.
+      */
+    public double getMax() {
+      return max;
+    }
+
+
+    /**
+      * Sets the value of the 'max' field.
+      * @param value The value of 'max'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder setMax(double value) {
+      validate(fields()[8], value);
+      this.max = value;
+      fieldSetFlags()[8] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'max' field has been set.
+      * @return True if the 'max' field has been set, false otherwise.
+      */
+    public boolean hasMax() {
+      return fieldSetFlags()[8];
+    }
+
+
+    /**
+      * Clears the value of the 'max' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.DayOfWeekActivePowerRecord.Builder clearMax() {
+      fieldSetFlags()[8] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public DayOfWeekActivePowerRecord build() {
+      try {
+        DayOfWeekActivePowerRecord record = new DayOfWeekActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.dayOfWeek = fieldSetFlags()[1] ? this.dayOfWeek : (java.lang.Integer) defaultValue(fields()[1]);
+        record.periodStart = fieldSetFlags()[2] ? this.periodStart : (java.lang.Long) defaultValue(fields()[2]);
+        record.periodEnd = fieldSetFlags()[3] ? this.periodEnd : (java.lang.Long) defaultValue(fields()[3]);
+        record.count = fieldSetFlags()[4] ? this.count : (java.lang.Long) defaultValue(fields()[4]);
+        record.mean = fieldSetFlags()[5] ? this.mean : (java.lang.Double) defaultValue(fields()[5]);
+        record.populationVariance = fieldSetFlags()[6] ? this.populationVariance : (java.lang.Double) defaultValue(fields()[6]);
+        record.min = fieldSetFlags()[7] ? this.min : (java.lang.Double) defaultValue(fields()[7]);
+        record.max = fieldSetFlags()[8] ? this.max : (java.lang.Double) defaultValue(fields()[8]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<DayOfWeekActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<DayOfWeekActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<DayOfWeekActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<DayOfWeekActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeInt(this.dayOfWeek);
+
+    out.writeLong(this.periodStart);
+
+    out.writeLong(this.periodEnd);
+
+    out.writeLong(this.count);
+
+    out.writeDouble(this.mean);
+
+    out.writeDouble(this.populationVariance);
+
+    out.writeDouble(this.min);
+
+    out.writeDouble(this.max);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.dayOfWeek = in.readInt();
+
+      this.periodStart = in.readLong();
+
+      this.periodEnd = in.readLong();
+
+      this.count = in.readLong();
+
+      this.mean = in.readDouble();
+
+      this.populationVariance = in.readDouble();
+
+      this.min = in.readDouble();
+
+      this.max = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 9; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.dayOfWeek = in.readInt();
+          break;
+
+        case 2:
+          this.periodStart = in.readLong();
+          break;
+
+        case 3:
+          this.periodEnd = in.readLong();
+          break;
+
+        case 4:
+          this.count = in.readLong();
+          break;
+
+        case 5:
+          this.mean = in.readDouble();
+          break;
+
+        case 6:
+          this.populationVariance = in.readDouble();
+          break;
+
+        case 7:
+          this.min = in.readDouble();
+          break;
+
+        case 8:
+          this.max = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/HourOfDayActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/HourOfDayActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..491a91f4dfe5d439d094d66290d82d77001e72c9
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/HourOfDayActivePowerRecord.java
@@ -0,0 +1,945 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class HourOfDayActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = 6460936513507715126L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"HourOfDayActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"hourOfDay\",\"type\":\"int\"},{\"name\":\"periodStart\",\"type\":\"long\"},{\"name\":\"periodEnd\",\"type\":\"long\"},{\"name\":\"count\",\"type\":\"long\"},{\"name\":\"mean\",\"type\":\"double\"},{\"name\":\"populationVariance\",\"type\":\"double\"},{\"name\":\"min\",\"type\":\"double\"},{\"name\":\"max\",\"type\":\"double\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<HourOfDayActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<HourOfDayActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<HourOfDayActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<HourOfDayActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<HourOfDayActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<HourOfDayActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<HourOfDayActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<HourOfDayActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this HourOfDayActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a HourOfDayActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a HourOfDayActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static HourOfDayActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  private java.lang.String identifier;
+  private int hourOfDay;
+  private long periodStart;
+  private long periodEnd;
+  private long count;
+  private double mean;
+  private double populationVariance;
+  private double min;
+  private double max;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public HourOfDayActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier The new value for identifier
+   * @param hourOfDay The new value for hourOfDay
+   * @param periodStart The new value for periodStart
+   * @param periodEnd The new value for periodEnd
+   * @param count The new value for count
+   * @param mean The new value for mean
+   * @param populationVariance The new value for populationVariance
+   * @param min The new value for min
+   * @param max The new value for max
+   */
+  public HourOfDayActivePowerRecord(java.lang.String identifier, java.lang.Integer hourOfDay, java.lang.Long periodStart, java.lang.Long periodEnd, java.lang.Long count, java.lang.Double mean, java.lang.Double populationVariance, java.lang.Double min, java.lang.Double max) {
+    this.identifier = identifier;
+    this.hourOfDay = hourOfDay;
+    this.periodStart = periodStart;
+    this.periodEnd = periodEnd;
+    this.count = count;
+    this.mean = mean;
+    this.populationVariance = populationVariance;
+    this.min = min;
+    this.max = max;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return hourOfDay;
+    case 2: return periodStart;
+    case 3: return periodEnd;
+    case 4: return count;
+    case 5: return mean;
+    case 6: return populationVariance;
+    case 7: return min;
+    case 8: return max;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: hourOfDay = (java.lang.Integer)value$; break;
+    case 2: periodStart = (java.lang.Long)value$; break;
+    case 3: periodEnd = (java.lang.Long)value$; break;
+    case 4: count = (java.lang.Long)value$; break;
+    case 5: mean = (java.lang.Double)value$; break;
+    case 6: populationVariance = (java.lang.Double)value$; break;
+    case 7: min = (java.lang.Double)value$; break;
+    case 8: max = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return The value of the 'identifier' field.
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'hourOfDay' field.
+   * @return The value of the 'hourOfDay' field.
+   */
+  public int getHourOfDay() {
+    return hourOfDay;
+  }
+
+
+  /**
+   * Sets the value of the 'hourOfDay' field.
+   * @param value the value to set.
+   */
+  public void setHourOfDay(int value) {
+    this.hourOfDay = value;
+  }
+
+  /**
+   * Gets the value of the 'periodStart' field.
+   * @return The value of the 'periodStart' field.
+   */
+  public long getPeriodStart() {
+    return periodStart;
+  }
+
+
+  /**
+   * Sets the value of the 'periodStart' field.
+   * @param value the value to set.
+   */
+  public void setPeriodStart(long value) {
+    this.periodStart = value;
+  }
+
+  /**
+   * Gets the value of the 'periodEnd' field.
+   * @return The value of the 'periodEnd' field.
+   */
+  public long getPeriodEnd() {
+    return periodEnd;
+  }
+
+
+  /**
+   * Sets the value of the 'periodEnd' field.
+   * @param value the value to set.
+   */
+  public void setPeriodEnd(long value) {
+    this.periodEnd = value;
+  }
+
+  /**
+   * Gets the value of the 'count' field.
+   * @return The value of the 'count' field.
+   */
+  public long getCount() {
+    return count;
+  }
+
+
+  /**
+   * Sets the value of the 'count' field.
+   * @param value the value to set.
+   */
+  public void setCount(long value) {
+    this.count = value;
+  }
+
+  /**
+   * Gets the value of the 'mean' field.
+   * @return The value of the 'mean' field.
+   */
+  public double getMean() {
+    return mean;
+  }
+
+
+  /**
+   * Sets the value of the 'mean' field.
+   * @param value the value to set.
+   */
+  public void setMean(double value) {
+    this.mean = value;
+  }
+
+  /**
+   * Gets the value of the 'populationVariance' field.
+   * @return The value of the 'populationVariance' field.
+   */
+  public double getPopulationVariance() {
+    return populationVariance;
+  }
+
+
+  /**
+   * Sets the value of the 'populationVariance' field.
+   * @param value the value to set.
+   */
+  public void setPopulationVariance(double value) {
+    this.populationVariance = value;
+  }
+
+  /**
+   * Gets the value of the 'min' field.
+   * @return The value of the 'min' field.
+   */
+  public double getMin() {
+    return min;
+  }
+
+
+  /**
+   * Sets the value of the 'min' field.
+   * @param value the value to set.
+   */
+  public void setMin(double value) {
+    this.min = value;
+  }
+
+  /**
+   * Gets the value of the 'max' field.
+   * @return The value of the 'max' field.
+   */
+  public double getMax() {
+    return max;
+  }
+
+
+  /**
+   * Sets the value of the 'max' field.
+   * @param value the value to set.
+   */
+  public void setMax(double value) {
+    this.max = value;
+  }
+
+  /**
+   * Creates a new HourOfDayActivePowerRecord RecordBuilder.
+   * @return A new HourOfDayActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new HourOfDayActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new HourOfDayActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new HourOfDayActivePowerRecord RecordBuilder by copying an existing HourOfDayActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new HourOfDayActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for HourOfDayActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<HourOfDayActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<HourOfDayActivePowerRecord> {
+
+    private java.lang.String identifier;
+    private int hourOfDay;
+    private long periodStart;
+    private long periodEnd;
+    private long count;
+    private double mean;
+    private double populationVariance;
+    private double min;
+    private double max;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.hourOfDay)) {
+        this.hourOfDay = data().deepCopy(fields()[1].schema(), other.hourOfDay);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = other.fieldSetFlags()[3];
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = other.fieldSetFlags()[4];
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = other.fieldSetFlags()[5];
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = other.fieldSetFlags()[6];
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = other.fieldSetFlags()[7];
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = other.fieldSetFlags()[8];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing HourOfDayActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.hourOfDay)) {
+        this.hourOfDay = data().deepCopy(fields()[1].schema(), other.hourOfDay);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = true;
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = true;
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = true;
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = true;
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'hourOfDay' field.
+      * @return The value.
+      */
+    public int getHourOfDay() {
+      return hourOfDay;
+    }
+
+
+    /**
+      * Sets the value of the 'hourOfDay' field.
+      * @param value The value of 'hourOfDay'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setHourOfDay(int value) {
+      validate(fields()[1], value);
+      this.hourOfDay = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'hourOfDay' field has been set.
+      * @return True if the 'hourOfDay' field has been set, false otherwise.
+      */
+    public boolean hasHourOfDay() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'hourOfDay' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearHourOfDay() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodStart' field.
+      * @return The value.
+      */
+    public long getPeriodStart() {
+      return periodStart;
+    }
+
+
+    /**
+      * Sets the value of the 'periodStart' field.
+      * @param value The value of 'periodStart'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setPeriodStart(long value) {
+      validate(fields()[2], value);
+      this.periodStart = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodStart' field has been set.
+      * @return True if the 'periodStart' field has been set, false otherwise.
+      */
+    public boolean hasPeriodStart() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'periodStart' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearPeriodStart() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodEnd' field.
+      * @return The value.
+      */
+    public long getPeriodEnd() {
+      return periodEnd;
+    }
+
+
+    /**
+      * Sets the value of the 'periodEnd' field.
+      * @param value The value of 'periodEnd'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setPeriodEnd(long value) {
+      validate(fields()[3], value);
+      this.periodEnd = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodEnd' field has been set.
+      * @return True if the 'periodEnd' field has been set, false otherwise.
+      */
+    public boolean hasPeriodEnd() {
+      return fieldSetFlags()[3];
+    }
+
+
+    /**
+      * Clears the value of the 'periodEnd' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearPeriodEnd() {
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'count' field.
+      * @return The value.
+      */
+    public long getCount() {
+      return count;
+    }
+
+
+    /**
+      * Sets the value of the 'count' field.
+      * @param value The value of 'count'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setCount(long value) {
+      validate(fields()[4], value);
+      this.count = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'count' field has been set.
+      * @return True if the 'count' field has been set, false otherwise.
+      */
+    public boolean hasCount() {
+      return fieldSetFlags()[4];
+    }
+
+
+    /**
+      * Clears the value of the 'count' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearCount() {
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'mean' field.
+      * @return The value.
+      */
+    public double getMean() {
+      return mean;
+    }
+
+
+    /**
+      * Sets the value of the 'mean' field.
+      * @param value The value of 'mean'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setMean(double value) {
+      validate(fields()[5], value);
+      this.mean = value;
+      fieldSetFlags()[5] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'mean' field has been set.
+      * @return True if the 'mean' field has been set, false otherwise.
+      */
+    public boolean hasMean() {
+      return fieldSetFlags()[5];
+    }
+
+
+    /**
+      * Clears the value of the 'mean' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearMean() {
+      fieldSetFlags()[5] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'populationVariance' field.
+      * @return The value.
+      */
+    public double getPopulationVariance() {
+      return populationVariance;
+    }
+
+
+    /**
+      * Sets the value of the 'populationVariance' field.
+      * @param value The value of 'populationVariance'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setPopulationVariance(double value) {
+      validate(fields()[6], value);
+      this.populationVariance = value;
+      fieldSetFlags()[6] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'populationVariance' field has been set.
+      * @return True if the 'populationVariance' field has been set, false otherwise.
+      */
+    public boolean hasPopulationVariance() {
+      return fieldSetFlags()[6];
+    }
+
+
+    /**
+      * Clears the value of the 'populationVariance' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearPopulationVariance() {
+      fieldSetFlags()[6] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'min' field.
+      * @return The value.
+      */
+    public double getMin() {
+      return min;
+    }
+
+
+    /**
+      * Sets the value of the 'min' field.
+      * @param value The value of 'min'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setMin(double value) {
+      validate(fields()[7], value);
+      this.min = value;
+      fieldSetFlags()[7] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'min' field has been set.
+      * @return True if the 'min' field has been set, false otherwise.
+      */
+    public boolean hasMin() {
+      return fieldSetFlags()[7];
+    }
+
+
+    /**
+      * Clears the value of the 'min' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearMin() {
+      fieldSetFlags()[7] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'max' field.
+      * @return The value.
+      */
+    public double getMax() {
+      return max;
+    }
+
+
+    /**
+      * Sets the value of the 'max' field.
+      * @param value The value of 'max'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder setMax(double value) {
+      validate(fields()[8], value);
+      this.max = value;
+      fieldSetFlags()[8] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'max' field has been set.
+      * @return True if the 'max' field has been set, false otherwise.
+      */
+    public boolean hasMax() {
+      return fieldSetFlags()[8];
+    }
+
+
+    /**
+      * Clears the value of the 'max' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord.Builder clearMax() {
+      fieldSetFlags()[8] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public HourOfDayActivePowerRecord build() {
+      try {
+        HourOfDayActivePowerRecord record = new HourOfDayActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.hourOfDay = fieldSetFlags()[1] ? this.hourOfDay : (java.lang.Integer) defaultValue(fields()[1]);
+        record.periodStart = fieldSetFlags()[2] ? this.periodStart : (java.lang.Long) defaultValue(fields()[2]);
+        record.periodEnd = fieldSetFlags()[3] ? this.periodEnd : (java.lang.Long) defaultValue(fields()[3]);
+        record.count = fieldSetFlags()[4] ? this.count : (java.lang.Long) defaultValue(fields()[4]);
+        record.mean = fieldSetFlags()[5] ? this.mean : (java.lang.Double) defaultValue(fields()[5]);
+        record.populationVariance = fieldSetFlags()[6] ? this.populationVariance : (java.lang.Double) defaultValue(fields()[6]);
+        record.min = fieldSetFlags()[7] ? this.min : (java.lang.Double) defaultValue(fields()[7]);
+        record.max = fieldSetFlags()[8] ? this.max : (java.lang.Double) defaultValue(fields()[8]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<HourOfDayActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<HourOfDayActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<HourOfDayActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<HourOfDayActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeInt(this.hourOfDay);
+
+    out.writeLong(this.periodStart);
+
+    out.writeLong(this.periodEnd);
+
+    out.writeLong(this.count);
+
+    out.writeDouble(this.mean);
+
+    out.writeDouble(this.populationVariance);
+
+    out.writeDouble(this.min);
+
+    out.writeDouble(this.max);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.hourOfDay = in.readInt();
+
+      this.periodStart = in.readLong();
+
+      this.periodEnd = in.readLong();
+
+      this.count = in.readLong();
+
+      this.mean = in.readDouble();
+
+      this.populationVariance = in.readDouble();
+
+      this.min = in.readDouble();
+
+      this.max = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 9; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.hourOfDay = in.readInt();
+          break;
+
+        case 2:
+          this.periodStart = in.readLong();
+          break;
+
+        case 3:
+          this.periodEnd = in.readLong();
+          break;
+
+        case 4:
+          this.count = in.readLong();
+          break;
+
+        case 5:
+          this.mean = in.readDouble();
+          break;
+
+        case 6:
+          this.populationVariance = in.readDouble();
+          break;
+
+        case 7:
+          this.min = in.readDouble();
+          break;
+
+        case 8:
+          this.max = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/HourOfWeekActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/HourOfWeekActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..112e1f7bc1c180e658367fb42b997405eb31a62c
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/HourOfWeekActivePowerRecord.java
@@ -0,0 +1,1024 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class HourOfWeekActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = -2060891996492175489L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"HourOfWeekActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"dayOfWeek\",\"type\":\"int\"},{\"name\":\"hourOfDay\",\"type\":\"int\"},{\"name\":\"periodStart\",\"type\":\"long\"},{\"name\":\"periodEnd\",\"type\":\"long\"},{\"name\":\"count\",\"type\":\"long\"},{\"name\":\"mean\",\"type\":\"double\"},{\"name\":\"populationVariance\",\"type\":\"double\"},{\"name\":\"min\",\"type\":\"double\"},{\"name\":\"max\",\"type\":\"double\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<HourOfWeekActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<HourOfWeekActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<HourOfWeekActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<HourOfWeekActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<HourOfWeekActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<HourOfWeekActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<HourOfWeekActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<HourOfWeekActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this HourOfWeekActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a HourOfWeekActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a HourOfWeekActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static HourOfWeekActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  private java.lang.String identifier;
+  private int dayOfWeek;
+  private int hourOfDay;
+  private long periodStart;
+  private long periodEnd;
+  private long count;
+  private double mean;
+  private double populationVariance;
+  private double min;
+  private double max;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public HourOfWeekActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier The new value for identifier
+   * @param dayOfWeek The new value for dayOfWeek
+   * @param hourOfDay The new value for hourOfDay
+   * @param periodStart The new value for periodStart
+   * @param periodEnd The new value for periodEnd
+   * @param count The new value for count
+   * @param mean The new value for mean
+   * @param populationVariance The new value for populationVariance
+   * @param min The new value for min
+   * @param max The new value for max
+   */
+  public HourOfWeekActivePowerRecord(java.lang.String identifier, java.lang.Integer dayOfWeek, java.lang.Integer hourOfDay, java.lang.Long periodStart, java.lang.Long periodEnd, java.lang.Long count, java.lang.Double mean, java.lang.Double populationVariance, java.lang.Double min, java.lang.Double max) {
+    this.identifier = identifier;
+    this.dayOfWeek = dayOfWeek;
+    this.hourOfDay = hourOfDay;
+    this.periodStart = periodStart;
+    this.periodEnd = periodEnd;
+    this.count = count;
+    this.mean = mean;
+    this.populationVariance = populationVariance;
+    this.min = min;
+    this.max = max;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return dayOfWeek;
+    case 2: return hourOfDay;
+    case 3: return periodStart;
+    case 4: return periodEnd;
+    case 5: return count;
+    case 6: return mean;
+    case 7: return populationVariance;
+    case 8: return min;
+    case 9: return max;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: dayOfWeek = (java.lang.Integer)value$; break;
+    case 2: hourOfDay = (java.lang.Integer)value$; break;
+    case 3: periodStart = (java.lang.Long)value$; break;
+    case 4: periodEnd = (java.lang.Long)value$; break;
+    case 5: count = (java.lang.Long)value$; break;
+    case 6: mean = (java.lang.Double)value$; break;
+    case 7: populationVariance = (java.lang.Double)value$; break;
+    case 8: min = (java.lang.Double)value$; break;
+    case 9: max = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return The value of the 'identifier' field.
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'dayOfWeek' field.
+   * @return The value of the 'dayOfWeek' field.
+   */
+  public int getDayOfWeek() {
+    return dayOfWeek;
+  }
+
+
+  /**
+   * Sets the value of the 'dayOfWeek' field.
+   * @param value the value to set.
+   */
+  public void setDayOfWeek(int value) {
+    this.dayOfWeek = value;
+  }
+
+  /**
+   * Gets the value of the 'hourOfDay' field.
+   * @return The value of the 'hourOfDay' field.
+   */
+  public int getHourOfDay() {
+    return hourOfDay;
+  }
+
+
+  /**
+   * Sets the value of the 'hourOfDay' field.
+   * @param value the value to set.
+   */
+  public void setHourOfDay(int value) {
+    this.hourOfDay = value;
+  }
+
+  /**
+   * Gets the value of the 'periodStart' field.
+   * @return The value of the 'periodStart' field.
+   */
+  public long getPeriodStart() {
+    return periodStart;
+  }
+
+
+  /**
+   * Sets the value of the 'periodStart' field.
+   * @param value the value to set.
+   */
+  public void setPeriodStart(long value) {
+    this.periodStart = value;
+  }
+
+  /**
+   * Gets the value of the 'periodEnd' field.
+   * @return The value of the 'periodEnd' field.
+   */
+  public long getPeriodEnd() {
+    return periodEnd;
+  }
+
+
+  /**
+   * Sets the value of the 'periodEnd' field.
+   * @param value the value to set.
+   */
+  public void setPeriodEnd(long value) {
+    this.periodEnd = value;
+  }
+
+  /**
+   * Gets the value of the 'count' field.
+   * @return The value of the 'count' field.
+   */
+  public long getCount() {
+    return count;
+  }
+
+
+  /**
+   * Sets the value of the 'count' field.
+   * @param value the value to set.
+   */
+  public void setCount(long value) {
+    this.count = value;
+  }
+
+  /**
+   * Gets the value of the 'mean' field.
+   * @return The value of the 'mean' field.
+   */
+  public double getMean() {
+    return mean;
+  }
+
+
+  /**
+   * Sets the value of the 'mean' field.
+   * @param value the value to set.
+   */
+  public void setMean(double value) {
+    this.mean = value;
+  }
+
+  /**
+   * Gets the value of the 'populationVariance' field.
+   * @return The value of the 'populationVariance' field.
+   */
+  public double getPopulationVariance() {
+    return populationVariance;
+  }
+
+
+  /**
+   * Sets the value of the 'populationVariance' field.
+   * @param value the value to set.
+   */
+  public void setPopulationVariance(double value) {
+    this.populationVariance = value;
+  }
+
+  /**
+   * Gets the value of the 'min' field.
+   * @return The value of the 'min' field.
+   */
+  public double getMin() {
+    return min;
+  }
+
+
+  /**
+   * Sets the value of the 'min' field.
+   * @param value the value to set.
+   */
+  public void setMin(double value) {
+    this.min = value;
+  }
+
+  /**
+   * Gets the value of the 'max' field.
+   * @return The value of the 'max' field.
+   */
+  public double getMax() {
+    return max;
+  }
+
+
+  /**
+   * Sets the value of the 'max' field.
+   * @param value the value to set.
+   */
+  public void setMax(double value) {
+    this.max = value;
+  }
+
+  /**
+   * Creates a new HourOfWeekActivePowerRecord RecordBuilder.
+   * @return A new HourOfWeekActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new HourOfWeekActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new HourOfWeekActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new HourOfWeekActivePowerRecord RecordBuilder by copying an existing HourOfWeekActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new HourOfWeekActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for HourOfWeekActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<HourOfWeekActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<HourOfWeekActivePowerRecord> {
+
+    private java.lang.String identifier;
+    private int dayOfWeek;
+    private int hourOfDay;
+    private long periodStart;
+    private long periodEnd;
+    private long count;
+    private double mean;
+    private double populationVariance;
+    private double min;
+    private double max;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.dayOfWeek)) {
+        this.dayOfWeek = data().deepCopy(fields()[1].schema(), other.dayOfWeek);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.hourOfDay)) {
+        this.hourOfDay = data().deepCopy(fields()[2].schema(), other.hourOfDay);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+      if (isValidValue(fields()[3], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[3].schema(), other.periodStart);
+        fieldSetFlags()[3] = other.fieldSetFlags()[3];
+      }
+      if (isValidValue(fields()[4], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[4].schema(), other.periodEnd);
+        fieldSetFlags()[4] = other.fieldSetFlags()[4];
+      }
+      if (isValidValue(fields()[5], other.count)) {
+        this.count = data().deepCopy(fields()[5].schema(), other.count);
+        fieldSetFlags()[5] = other.fieldSetFlags()[5];
+      }
+      if (isValidValue(fields()[6], other.mean)) {
+        this.mean = data().deepCopy(fields()[6].schema(), other.mean);
+        fieldSetFlags()[6] = other.fieldSetFlags()[6];
+      }
+      if (isValidValue(fields()[7], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[7].schema(), other.populationVariance);
+        fieldSetFlags()[7] = other.fieldSetFlags()[7];
+      }
+      if (isValidValue(fields()[8], other.min)) {
+        this.min = data().deepCopy(fields()[8].schema(), other.min);
+        fieldSetFlags()[8] = other.fieldSetFlags()[8];
+      }
+      if (isValidValue(fields()[9], other.max)) {
+        this.max = data().deepCopy(fields()[9].schema(), other.max);
+        fieldSetFlags()[9] = other.fieldSetFlags()[9];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing HourOfWeekActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.dayOfWeek)) {
+        this.dayOfWeek = data().deepCopy(fields()[1].schema(), other.dayOfWeek);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.hourOfDay)) {
+        this.hourOfDay = data().deepCopy(fields()[2].schema(), other.hourOfDay);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[3].schema(), other.periodStart);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[4].schema(), other.periodEnd);
+        fieldSetFlags()[4] = true;
+      }
+      if (isValidValue(fields()[5], other.count)) {
+        this.count = data().deepCopy(fields()[5].schema(), other.count);
+        fieldSetFlags()[5] = true;
+      }
+      if (isValidValue(fields()[6], other.mean)) {
+        this.mean = data().deepCopy(fields()[6].schema(), other.mean);
+        fieldSetFlags()[6] = true;
+      }
+      if (isValidValue(fields()[7], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[7].schema(), other.populationVariance);
+        fieldSetFlags()[7] = true;
+      }
+      if (isValidValue(fields()[8], other.min)) {
+        this.min = data().deepCopy(fields()[8].schema(), other.min);
+        fieldSetFlags()[8] = true;
+      }
+      if (isValidValue(fields()[9], other.max)) {
+        this.max = data().deepCopy(fields()[9].schema(), other.max);
+        fieldSetFlags()[9] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'dayOfWeek' field.
+      * @return The value.
+      */
+    public int getDayOfWeek() {
+      return dayOfWeek;
+    }
+
+
+    /**
+      * Sets the value of the 'dayOfWeek' field.
+      * @param value The value of 'dayOfWeek'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setDayOfWeek(int value) {
+      validate(fields()[1], value);
+      this.dayOfWeek = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'dayOfWeek' field has been set.
+      * @return True if the 'dayOfWeek' field has been set, false otherwise.
+      */
+    public boolean hasDayOfWeek() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'dayOfWeek' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearDayOfWeek() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'hourOfDay' field.
+      * @return The value.
+      */
+    public int getHourOfDay() {
+      return hourOfDay;
+    }
+
+
+    /**
+      * Sets the value of the 'hourOfDay' field.
+      * @param value The value of 'hourOfDay'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setHourOfDay(int value) {
+      validate(fields()[2], value);
+      this.hourOfDay = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'hourOfDay' field has been set.
+      * @return True if the 'hourOfDay' field has been set, false otherwise.
+      */
+    public boolean hasHourOfDay() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'hourOfDay' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearHourOfDay() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodStart' field.
+      * @return The value.
+      */
+    public long getPeriodStart() {
+      return periodStart;
+    }
+
+
+    /**
+      * Sets the value of the 'periodStart' field.
+      * @param value The value of 'periodStart'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setPeriodStart(long value) {
+      validate(fields()[3], value);
+      this.periodStart = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodStart' field has been set.
+      * @return True if the 'periodStart' field has been set, false otherwise.
+      */
+    public boolean hasPeriodStart() {
+      return fieldSetFlags()[3];
+    }
+
+
+    /**
+      * Clears the value of the 'periodStart' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearPeriodStart() {
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodEnd' field.
+      * @return The value.
+      */
+    public long getPeriodEnd() {
+      return periodEnd;
+    }
+
+
+    /**
+      * Sets the value of the 'periodEnd' field.
+      * @param value The value of 'periodEnd'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setPeriodEnd(long value) {
+      validate(fields()[4], value);
+      this.periodEnd = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodEnd' field has been set.
+      * @return True if the 'periodEnd' field has been set, false otherwise.
+      */
+    public boolean hasPeriodEnd() {
+      return fieldSetFlags()[4];
+    }
+
+
+    /**
+      * Clears the value of the 'periodEnd' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearPeriodEnd() {
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'count' field.
+      * @return The value.
+      */
+    public long getCount() {
+      return count;
+    }
+
+
+    /**
+      * Sets the value of the 'count' field.
+      * @param value The value of 'count'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setCount(long value) {
+      validate(fields()[5], value);
+      this.count = value;
+      fieldSetFlags()[5] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'count' field has been set.
+      * @return True if the 'count' field has been set, false otherwise.
+      */
+    public boolean hasCount() {
+      return fieldSetFlags()[5];
+    }
+
+
+    /**
+      * Clears the value of the 'count' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearCount() {
+      fieldSetFlags()[5] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'mean' field.
+      * @return The value.
+      */
+    public double getMean() {
+      return mean;
+    }
+
+
+    /**
+      * Sets the value of the 'mean' field.
+      * @param value The value of 'mean'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setMean(double value) {
+      validate(fields()[6], value);
+      this.mean = value;
+      fieldSetFlags()[6] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'mean' field has been set.
+      * @return True if the 'mean' field has been set, false otherwise.
+      */
+    public boolean hasMean() {
+      return fieldSetFlags()[6];
+    }
+
+
+    /**
+      * Clears the value of the 'mean' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearMean() {
+      fieldSetFlags()[6] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'populationVariance' field.
+      * @return The value.
+      */
+    public double getPopulationVariance() {
+      return populationVariance;
+    }
+
+
+    /**
+      * Sets the value of the 'populationVariance' field.
+      * @param value The value of 'populationVariance'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setPopulationVariance(double value) {
+      validate(fields()[7], value);
+      this.populationVariance = value;
+      fieldSetFlags()[7] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'populationVariance' field has been set.
+      * @return True if the 'populationVariance' field has been set, false otherwise.
+      */
+    public boolean hasPopulationVariance() {
+      return fieldSetFlags()[7];
+    }
+
+
+    /**
+      * Clears the value of the 'populationVariance' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearPopulationVariance() {
+      fieldSetFlags()[7] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'min' field.
+      * @return The value.
+      */
+    public double getMin() {
+      return min;
+    }
+
+
+    /**
+      * Sets the value of the 'min' field.
+      * @param value The value of 'min'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setMin(double value) {
+      validate(fields()[8], value);
+      this.min = value;
+      fieldSetFlags()[8] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'min' field has been set.
+      * @return True if the 'min' field has been set, false otherwise.
+      */
+    public boolean hasMin() {
+      return fieldSetFlags()[8];
+    }
+
+
+    /**
+      * Clears the value of the 'min' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearMin() {
+      fieldSetFlags()[8] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'max' field.
+      * @return The value.
+      */
+    public double getMax() {
+      return max;
+    }
+
+
+    /**
+      * Sets the value of the 'max' field.
+      * @param value The value of 'max'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder setMax(double value) {
+      validate(fields()[9], value);
+      this.max = value;
+      fieldSetFlags()[9] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'max' field has been set.
+      * @return True if the 'max' field has been set, false otherwise.
+      */
+    public boolean hasMax() {
+      return fieldSetFlags()[9];
+    }
+
+
+    /**
+      * Clears the value of the 'max' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.HourOfWeekActivePowerRecord.Builder clearMax() {
+      fieldSetFlags()[9] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public HourOfWeekActivePowerRecord build() {
+      try {
+        HourOfWeekActivePowerRecord record = new HourOfWeekActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.dayOfWeek = fieldSetFlags()[1] ? this.dayOfWeek : (java.lang.Integer) defaultValue(fields()[1]);
+        record.hourOfDay = fieldSetFlags()[2] ? this.hourOfDay : (java.lang.Integer) defaultValue(fields()[2]);
+        record.periodStart = fieldSetFlags()[3] ? this.periodStart : (java.lang.Long) defaultValue(fields()[3]);
+        record.periodEnd = fieldSetFlags()[4] ? this.periodEnd : (java.lang.Long) defaultValue(fields()[4]);
+        record.count = fieldSetFlags()[5] ? this.count : (java.lang.Long) defaultValue(fields()[5]);
+        record.mean = fieldSetFlags()[6] ? this.mean : (java.lang.Double) defaultValue(fields()[6]);
+        record.populationVariance = fieldSetFlags()[7] ? this.populationVariance : (java.lang.Double) defaultValue(fields()[7]);
+        record.min = fieldSetFlags()[8] ? this.min : (java.lang.Double) defaultValue(fields()[8]);
+        record.max = fieldSetFlags()[9] ? this.max : (java.lang.Double) defaultValue(fields()[9]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<HourOfWeekActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<HourOfWeekActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<HourOfWeekActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<HourOfWeekActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeInt(this.dayOfWeek);
+
+    out.writeInt(this.hourOfDay);
+
+    out.writeLong(this.periodStart);
+
+    out.writeLong(this.periodEnd);
+
+    out.writeLong(this.count);
+
+    out.writeDouble(this.mean);
+
+    out.writeDouble(this.populationVariance);
+
+    out.writeDouble(this.min);
+
+    out.writeDouble(this.max);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.dayOfWeek = in.readInt();
+
+      this.hourOfDay = in.readInt();
+
+      this.periodStart = in.readLong();
+
+      this.periodEnd = in.readLong();
+
+      this.count = in.readLong();
+
+      this.mean = in.readDouble();
+
+      this.populationVariance = in.readDouble();
+
+      this.min = in.readDouble();
+
+      this.max = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 10; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.dayOfWeek = in.readInt();
+          break;
+
+        case 2:
+          this.hourOfDay = in.readInt();
+          break;
+
+        case 3:
+          this.periodStart = in.readLong();
+          break;
+
+        case 4:
+          this.periodEnd = in.readLong();
+          break;
+
+        case 5:
+          this.count = in.readLong();
+          break;
+
+        case 6:
+          this.mean = in.readDouble();
+          break;
+
+        case 7:
+          this.populationVariance = in.readDouble();
+          break;
+
+        case 8:
+          this.min = in.readDouble();
+          break;
+
+        case 9:
+          this.max = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/MonthOfYearActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/MonthOfYearActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c1cd52fee2fd703e0f98bfdc0bf08b069321952
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/MonthOfYearActivePowerRecord.java
@@ -0,0 +1,945 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class MonthOfYearActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = -6007754522109150657L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"MonthOfYearActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"monthOfYear\",\"type\":\"int\"},{\"name\":\"periodStart\",\"type\":\"long\"},{\"name\":\"periodEnd\",\"type\":\"long\"},{\"name\":\"count\",\"type\":\"long\"},{\"name\":\"mean\",\"type\":\"double\"},{\"name\":\"populationVariance\",\"type\":\"double\"},{\"name\":\"min\",\"type\":\"double\"},{\"name\":\"max\",\"type\":\"double\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<MonthOfYearActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<MonthOfYearActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<MonthOfYearActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<MonthOfYearActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<MonthOfYearActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<MonthOfYearActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<MonthOfYearActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<MonthOfYearActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this MonthOfYearActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a MonthOfYearActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a MonthOfYearActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static MonthOfYearActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  private java.lang.String identifier;
+  private int monthOfYear;
+  private long periodStart;
+  private long periodEnd;
+  private long count;
+  private double mean;
+  private double populationVariance;
+  private double min;
+  private double max;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public MonthOfYearActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier The new value for identifier
+   * @param monthOfYear The new value for monthOfYear
+   * @param periodStart The new value for periodStart
+   * @param periodEnd The new value for periodEnd
+   * @param count The new value for count
+   * @param mean The new value for mean
+   * @param populationVariance The new value for populationVariance
+   * @param min The new value for min
+   * @param max The new value for max
+   */
+  public MonthOfYearActivePowerRecord(java.lang.String identifier, java.lang.Integer monthOfYear, java.lang.Long periodStart, java.lang.Long periodEnd, java.lang.Long count, java.lang.Double mean, java.lang.Double populationVariance, java.lang.Double min, java.lang.Double max) {
+    this.identifier = identifier;
+    this.monthOfYear = monthOfYear;
+    this.periodStart = periodStart;
+    this.periodEnd = periodEnd;
+    this.count = count;
+    this.mean = mean;
+    this.populationVariance = populationVariance;
+    this.min = min;
+    this.max = max;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return monthOfYear;
+    case 2: return periodStart;
+    case 3: return periodEnd;
+    case 4: return count;
+    case 5: return mean;
+    case 6: return populationVariance;
+    case 7: return min;
+    case 8: return max;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: monthOfYear = (java.lang.Integer)value$; break;
+    case 2: periodStart = (java.lang.Long)value$; break;
+    case 3: periodEnd = (java.lang.Long)value$; break;
+    case 4: count = (java.lang.Long)value$; break;
+    case 5: mean = (java.lang.Double)value$; break;
+    case 6: populationVariance = (java.lang.Double)value$; break;
+    case 7: min = (java.lang.Double)value$; break;
+    case 8: max = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return The value of the 'identifier' field.
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'monthOfYear' field.
+   * @return The value of the 'monthOfYear' field.
+   */
+  public int getMonthOfYear() {
+    return monthOfYear;
+  }
+
+
+  /**
+   * Sets the value of the 'monthOfYear' field.
+   * @param value the value to set.
+   */
+  public void setMonthOfYear(int value) {
+    this.monthOfYear = value;
+  }
+
+  /**
+   * Gets the value of the 'periodStart' field.
+   * @return The value of the 'periodStart' field.
+   */
+  public long getPeriodStart() {
+    return periodStart;
+  }
+
+
+  /**
+   * Sets the value of the 'periodStart' field.
+   * @param value the value to set.
+   */
+  public void setPeriodStart(long value) {
+    this.periodStart = value;
+  }
+
+  /**
+   * Gets the value of the 'periodEnd' field.
+   * @return The value of the 'periodEnd' field.
+   */
+  public long getPeriodEnd() {
+    return periodEnd;
+  }
+
+
+  /**
+   * Sets the value of the 'periodEnd' field.
+   * @param value the value to set.
+   */
+  public void setPeriodEnd(long value) {
+    this.periodEnd = value;
+  }
+
+  /**
+   * Gets the value of the 'count' field.
+   * @return The value of the 'count' field.
+   */
+  public long getCount() {
+    return count;
+  }
+
+
+  /**
+   * Sets the value of the 'count' field.
+   * @param value the value to set.
+   */
+  public void setCount(long value) {
+    this.count = value;
+  }
+
+  /**
+   * Gets the value of the 'mean' field.
+   * @return The value of the 'mean' field.
+   */
+  public double getMean() {
+    return mean;
+  }
+
+
+  /**
+   * Sets the value of the 'mean' field.
+   * @param value the value to set.
+   */
+  public void setMean(double value) {
+    this.mean = value;
+  }
+
+  /**
+   * Gets the value of the 'populationVariance' field.
+   * @return The value of the 'populationVariance' field.
+   */
+  public double getPopulationVariance() {
+    return populationVariance;
+  }
+
+
+  /**
+   * Sets the value of the 'populationVariance' field.
+   * @param value the value to set.
+   */
+  public void setPopulationVariance(double value) {
+    this.populationVariance = value;
+  }
+
+  /**
+   * Gets the value of the 'min' field.
+   * @return The value of the 'min' field.
+   */
+  public double getMin() {
+    return min;
+  }
+
+
+  /**
+   * Sets the value of the 'min' field.
+   * @param value the value to set.
+   */
+  public void setMin(double value) {
+    this.min = value;
+  }
+
+  /**
+   * Gets the value of the 'max' field.
+   * @return The value of the 'max' field.
+   */
+  public double getMax() {
+    return max;
+  }
+
+
+  /**
+   * Sets the value of the 'max' field.
+   * @param value the value to set.
+   */
+  public void setMax(double value) {
+    this.max = value;
+  }
+
+  /**
+   * Creates a new MonthOfYearActivePowerRecord RecordBuilder.
+   * @return A new MonthOfYearActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new MonthOfYearActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new MonthOfYearActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new MonthOfYearActivePowerRecord RecordBuilder by copying an existing MonthOfYearActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new MonthOfYearActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for MonthOfYearActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<MonthOfYearActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<MonthOfYearActivePowerRecord> {
+
+    private java.lang.String identifier;
+    private int monthOfYear;
+    private long periodStart;
+    private long periodEnd;
+    private long count;
+    private double mean;
+    private double populationVariance;
+    private double min;
+    private double max;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.monthOfYear)) {
+        this.monthOfYear = data().deepCopy(fields()[1].schema(), other.monthOfYear);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = other.fieldSetFlags()[3];
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = other.fieldSetFlags()[4];
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = other.fieldSetFlags()[5];
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = other.fieldSetFlags()[6];
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = other.fieldSetFlags()[7];
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = other.fieldSetFlags()[8];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing MonthOfYearActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.monthOfYear)) {
+        this.monthOfYear = data().deepCopy(fields()[1].schema(), other.monthOfYear);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = true;
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = true;
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = true;
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = true;
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'monthOfYear' field.
+      * @return The value.
+      */
+    public int getMonthOfYear() {
+      return monthOfYear;
+    }
+
+
+    /**
+      * Sets the value of the 'monthOfYear' field.
+      * @param value The value of 'monthOfYear'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setMonthOfYear(int value) {
+      validate(fields()[1], value);
+      this.monthOfYear = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'monthOfYear' field has been set.
+      * @return True if the 'monthOfYear' field has been set, false otherwise.
+      */
+    public boolean hasMonthOfYear() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'monthOfYear' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearMonthOfYear() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodStart' field.
+      * @return The value.
+      */
+    public long getPeriodStart() {
+      return periodStart;
+    }
+
+
+    /**
+      * Sets the value of the 'periodStart' field.
+      * @param value The value of 'periodStart'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setPeriodStart(long value) {
+      validate(fields()[2], value);
+      this.periodStart = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodStart' field has been set.
+      * @return True if the 'periodStart' field has been set, false otherwise.
+      */
+    public boolean hasPeriodStart() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'periodStart' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearPeriodStart() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodEnd' field.
+      * @return The value.
+      */
+    public long getPeriodEnd() {
+      return periodEnd;
+    }
+
+
+    /**
+      * Sets the value of the 'periodEnd' field.
+      * @param value The value of 'periodEnd'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setPeriodEnd(long value) {
+      validate(fields()[3], value);
+      this.periodEnd = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodEnd' field has been set.
+      * @return True if the 'periodEnd' field has been set, false otherwise.
+      */
+    public boolean hasPeriodEnd() {
+      return fieldSetFlags()[3];
+    }
+
+
+    /**
+      * Clears the value of the 'periodEnd' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearPeriodEnd() {
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'count' field.
+      * @return The value.
+      */
+    public long getCount() {
+      return count;
+    }
+
+
+    /**
+      * Sets the value of the 'count' field.
+      * @param value The value of 'count'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setCount(long value) {
+      validate(fields()[4], value);
+      this.count = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'count' field has been set.
+      * @return True if the 'count' field has been set, false otherwise.
+      */
+    public boolean hasCount() {
+      return fieldSetFlags()[4];
+    }
+
+
+    /**
+      * Clears the value of the 'count' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearCount() {
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'mean' field.
+      * @return The value.
+      */
+    public double getMean() {
+      return mean;
+    }
+
+
+    /**
+      * Sets the value of the 'mean' field.
+      * @param value The value of 'mean'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setMean(double value) {
+      validate(fields()[5], value);
+      this.mean = value;
+      fieldSetFlags()[5] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'mean' field has been set.
+      * @return True if the 'mean' field has been set, false otherwise.
+      */
+    public boolean hasMean() {
+      return fieldSetFlags()[5];
+    }
+
+
+    /**
+      * Clears the value of the 'mean' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearMean() {
+      fieldSetFlags()[5] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'populationVariance' field.
+      * @return The value.
+      */
+    public double getPopulationVariance() {
+      return populationVariance;
+    }
+
+
+    /**
+      * Sets the value of the 'populationVariance' field.
+      * @param value The value of 'populationVariance'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setPopulationVariance(double value) {
+      validate(fields()[6], value);
+      this.populationVariance = value;
+      fieldSetFlags()[6] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'populationVariance' field has been set.
+      * @return True if the 'populationVariance' field has been set, false otherwise.
+      */
+    public boolean hasPopulationVariance() {
+      return fieldSetFlags()[6];
+    }
+
+
+    /**
+      * Clears the value of the 'populationVariance' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearPopulationVariance() {
+      fieldSetFlags()[6] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'min' field.
+      * @return The value.
+      */
+    public double getMin() {
+      return min;
+    }
+
+
+    /**
+      * Sets the value of the 'min' field.
+      * @param value The value of 'min'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setMin(double value) {
+      validate(fields()[7], value);
+      this.min = value;
+      fieldSetFlags()[7] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'min' field has been set.
+      * @return True if the 'min' field has been set, false otherwise.
+      */
+    public boolean hasMin() {
+      return fieldSetFlags()[7];
+    }
+
+
+    /**
+      * Clears the value of the 'min' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearMin() {
+      fieldSetFlags()[7] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'max' field.
+      * @return The value.
+      */
+    public double getMax() {
+      return max;
+    }
+
+
+    /**
+      * Sets the value of the 'max' field.
+      * @param value The value of 'max'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder setMax(double value) {
+      validate(fields()[8], value);
+      this.max = value;
+      fieldSetFlags()[8] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'max' field has been set.
+      * @return True if the 'max' field has been set, false otherwise.
+      */
+    public boolean hasMax() {
+      return fieldSetFlags()[8];
+    }
+
+
+    /**
+      * Clears the value of the 'max' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.MonthOfYearActivePowerRecord.Builder clearMax() {
+      fieldSetFlags()[8] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public MonthOfYearActivePowerRecord build() {
+      try {
+        MonthOfYearActivePowerRecord record = new MonthOfYearActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.monthOfYear = fieldSetFlags()[1] ? this.monthOfYear : (java.lang.Integer) defaultValue(fields()[1]);
+        record.periodStart = fieldSetFlags()[2] ? this.periodStart : (java.lang.Long) defaultValue(fields()[2]);
+        record.periodEnd = fieldSetFlags()[3] ? this.periodEnd : (java.lang.Long) defaultValue(fields()[3]);
+        record.count = fieldSetFlags()[4] ? this.count : (java.lang.Long) defaultValue(fields()[4]);
+        record.mean = fieldSetFlags()[5] ? this.mean : (java.lang.Double) defaultValue(fields()[5]);
+        record.populationVariance = fieldSetFlags()[6] ? this.populationVariance : (java.lang.Double) defaultValue(fields()[6]);
+        record.min = fieldSetFlags()[7] ? this.min : (java.lang.Double) defaultValue(fields()[7]);
+        record.max = fieldSetFlags()[8] ? this.max : (java.lang.Double) defaultValue(fields()[8]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<MonthOfYearActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<MonthOfYearActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<MonthOfYearActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<MonthOfYearActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeInt(this.monthOfYear);
+
+    out.writeLong(this.periodStart);
+
+    out.writeLong(this.periodEnd);
+
+    out.writeLong(this.count);
+
+    out.writeDouble(this.mean);
+
+    out.writeDouble(this.populationVariance);
+
+    out.writeDouble(this.min);
+
+    out.writeDouble(this.max);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.monthOfYear = in.readInt();
+
+      this.periodStart = in.readLong();
+
+      this.periodEnd = in.readLong();
+
+      this.count = in.readLong();
+
+      this.mean = in.readDouble();
+
+      this.populationVariance = in.readDouble();
+
+      this.min = in.readDouble();
+
+      this.max = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 9; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.monthOfYear = in.readInt();
+          break;
+
+        case 2:
+          this.periodStart = in.readLong();
+          break;
+
+        case 3:
+          this.periodEnd = in.readLong();
+          break;
+
+        case 4:
+          this.count = in.readLong();
+          break;
+
+        case 5:
+          this.mean = in.readDouble();
+          break;
+
+        case 6:
+          this.populationVariance = in.readDouble();
+          break;
+
+        case 7:
+          this.min = in.readDouble();
+          break;
+
+        case 8:
+          this.max = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/YearActivePowerRecord.java b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/YearActivePowerRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..0471c825551cc048e5e553309ddf2751b6e7ba3d
--- /dev/null
+++ b/theodolite-benchmarks/commons/src-gen/main/java/rocks/theodolite/benchmarks/commons/model/records/YearActivePowerRecord.java
@@ -0,0 +1,945 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package rocks.theodolite.benchmarks.commons.model.records;
+
+import org.apache.avro.generic.GenericArray;
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.util.Utf8;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@org.apache.avro.specific.AvroGenerated
+public class YearActivePowerRecord extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  private static final long serialVersionUID = 1269303032337461873L;
+
+
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"YearActivePowerRecord\",\"namespace\":\"rocks.theodolite.benchmarks.commons.model.records\",\"fields\":[{\"name\":\"identifier\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"year\",\"type\":\"int\"},{\"name\":\"periodStart\",\"type\":\"long\"},{\"name\":\"periodEnd\",\"type\":\"long\"},{\"name\":\"count\",\"type\":\"long\"},{\"name\":\"mean\",\"type\":\"double\"},{\"name\":\"populationVariance\",\"type\":\"double\"},{\"name\":\"min\",\"type\":\"double\"},{\"name\":\"max\",\"type\":\"double\"}]}");
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+  private static final SpecificData MODEL$ = new SpecificData();
+
+  private static final BinaryMessageEncoder<YearActivePowerRecord> ENCODER =
+      new BinaryMessageEncoder<YearActivePowerRecord>(MODEL$, SCHEMA$);
+
+  private static final BinaryMessageDecoder<YearActivePowerRecord> DECODER =
+      new BinaryMessageDecoder<YearActivePowerRecord>(MODEL$, SCHEMA$);
+
+  /**
+   * Return the BinaryMessageEncoder instance used by this class.
+   * @return the message encoder used by this class
+   */
+  public static BinaryMessageEncoder<YearActivePowerRecord> getEncoder() {
+    return ENCODER;
+  }
+
+  /**
+   * Return the BinaryMessageDecoder instance used by this class.
+   * @return the message decoder used by this class
+   */
+  public static BinaryMessageDecoder<YearActivePowerRecord> getDecoder() {
+    return DECODER;
+  }
+
+  /**
+   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+   * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+   * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore
+   */
+  public static BinaryMessageDecoder<YearActivePowerRecord> createDecoder(SchemaStore resolver) {
+    return new BinaryMessageDecoder<YearActivePowerRecord>(MODEL$, SCHEMA$, resolver);
+  }
+
+  /**
+   * Serializes this YearActivePowerRecord to a ByteBuffer.
+   * @return a buffer holding the serialized data for this instance
+   * @throws java.io.IOException if this instance could not be serialized
+   */
+  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+    return ENCODER.encode(this);
+  }
+
+  /**
+   * Deserializes a YearActivePowerRecord from a ByteBuffer.
+   * @param b a byte buffer holding serialized data for an instance of this class
+   * @return a YearActivePowerRecord instance decoded from the given buffer
+   * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class
+   */
+  public static YearActivePowerRecord fromByteBuffer(
+      java.nio.ByteBuffer b) throws java.io.IOException {
+    return DECODER.decode(b);
+  }
+
+  private java.lang.String identifier;
+  private int year;
+  private long periodStart;
+  private long periodEnd;
+  private long count;
+  private double mean;
+  private double populationVariance;
+  private double min;
+  private double max;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public YearActivePowerRecord() {}
+
+  /**
+   * All-args constructor.
+   * @param identifier The new value for identifier
+   * @param year The new value for year
+   * @param periodStart The new value for periodStart
+   * @param periodEnd The new value for periodEnd
+   * @param count The new value for count
+   * @param mean The new value for mean
+   * @param populationVariance The new value for populationVariance
+   * @param min The new value for min
+   * @param max The new value for max
+   */
+  public YearActivePowerRecord(java.lang.String identifier, java.lang.Integer year, java.lang.Long periodStart, java.lang.Long periodEnd, java.lang.Long count, java.lang.Double mean, java.lang.Double populationVariance, java.lang.Double min, java.lang.Double max) {
+    this.identifier = identifier;
+    this.year = year;
+    this.periodStart = periodStart;
+    this.periodEnd = periodEnd;
+    this.count = count;
+    this.mean = mean;
+    this.populationVariance = populationVariance;
+    this.min = min;
+    this.max = max;
+  }
+
+  public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return identifier;
+    case 1: return year;
+    case 2: return periodStart;
+    case 3: return periodEnd;
+    case 4: return count;
+    case 5: return mean;
+    case 6: return populationVariance;
+    case 7: return min;
+    case 8: return max;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: identifier = value$ != null ? value$.toString() : null; break;
+    case 1: year = (java.lang.Integer)value$; break;
+    case 2: periodStart = (java.lang.Long)value$; break;
+    case 3: periodEnd = (java.lang.Long)value$; break;
+    case 4: count = (java.lang.Long)value$; break;
+    case 5: mean = (java.lang.Double)value$; break;
+    case 6: populationVariance = (java.lang.Double)value$; break;
+    case 7: min = (java.lang.Double)value$; break;
+    case 8: max = (java.lang.Double)value$; break;
+    default: throw new IndexOutOfBoundsException("Invalid index: " + field$);
+    }
+  }
+
+  /**
+   * Gets the value of the 'identifier' field.
+   * @return The value of the 'identifier' field.
+   */
+  public java.lang.String getIdentifier() {
+    return identifier;
+  }
+
+
+  /**
+   * Sets the value of the 'identifier' field.
+   * @param value the value to set.
+   */
+  public void setIdentifier(java.lang.String value) {
+    this.identifier = value;
+  }
+
+  /**
+   * Gets the value of the 'year' field.
+   * @return The value of the 'year' field.
+   */
+  public int getYear() {
+    return year;
+  }
+
+
+  /**
+   * Sets the value of the 'year' field.
+   * @param value the value to set.
+   */
+  public void setYear(int value) {
+    this.year = value;
+  }
+
+  /**
+   * Gets the value of the 'periodStart' field.
+   * @return The value of the 'periodStart' field.
+   */
+  public long getPeriodStart() {
+    return periodStart;
+  }
+
+
+  /**
+   * Sets the value of the 'periodStart' field.
+   * @param value the value to set.
+   */
+  public void setPeriodStart(long value) {
+    this.periodStart = value;
+  }
+
+  /**
+   * Gets the value of the 'periodEnd' field.
+   * @return The value of the 'periodEnd' field.
+   */
+  public long getPeriodEnd() {
+    return periodEnd;
+  }
+
+
+  /**
+   * Sets the value of the 'periodEnd' field.
+   * @param value the value to set.
+   */
+  public void setPeriodEnd(long value) {
+    this.periodEnd = value;
+  }
+
+  /**
+   * Gets the value of the 'count' field.
+   * @return The value of the 'count' field.
+   */
+  public long getCount() {
+    return count;
+  }
+
+
+  /**
+   * Sets the value of the 'count' field.
+   * @param value the value to set.
+   */
+  public void setCount(long value) {
+    this.count = value;
+  }
+
+  /**
+   * Gets the value of the 'mean' field.
+   * @return The value of the 'mean' field.
+   */
+  public double getMean() {
+    return mean;
+  }
+
+
+  /**
+   * Sets the value of the 'mean' field.
+   * @param value the value to set.
+   */
+  public void setMean(double value) {
+    this.mean = value;
+  }
+
+  /**
+   * Gets the value of the 'populationVariance' field.
+   * @return The value of the 'populationVariance' field.
+   */
+  public double getPopulationVariance() {
+    return populationVariance;
+  }
+
+
+  /**
+   * Sets the value of the 'populationVariance' field.
+   * @param value the value to set.
+   */
+  public void setPopulationVariance(double value) {
+    this.populationVariance = value;
+  }
+
+  /**
+   * Gets the value of the 'min' field.
+   * @return The value of the 'min' field.
+   */
+  public double getMin() {
+    return min;
+  }
+
+
+  /**
+   * Sets the value of the 'min' field.
+   * @param value the value to set.
+   */
+  public void setMin(double value) {
+    this.min = value;
+  }
+
+  /**
+   * Gets the value of the 'max' field.
+   * @return The value of the 'max' field.
+   */
+  public double getMax() {
+    return max;
+  }
+
+
+  /**
+   * Sets the value of the 'max' field.
+   * @param value the value to set.
+   */
+  public void setMax(double value) {
+    this.max = value;
+  }
+
+  /**
+   * Creates a new YearActivePowerRecord RecordBuilder.
+   * @return A new YearActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder newBuilder() {
+    return new rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder();
+  }
+
+  /**
+   * Creates a new YearActivePowerRecord RecordBuilder by copying an existing Builder.
+   * @param other The existing builder to copy.
+   * @return A new YearActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * Creates a new YearActivePowerRecord RecordBuilder by copying an existing YearActivePowerRecord instance.
+   * @param other The existing instance to copy.
+   * @return A new YearActivePowerRecord RecordBuilder
+   */
+  public static rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder newBuilder(rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord other) {
+    if (other == null) {
+      return new rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder();
+    } else {
+      return new rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder(other);
+    }
+  }
+
+  /**
+   * RecordBuilder for YearActivePowerRecord instances.
+   */
+  @org.apache.avro.specific.AvroGenerated
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<YearActivePowerRecord>
+    implements org.apache.avro.data.RecordBuilder<YearActivePowerRecord> {
+
+    private java.lang.String identifier;
+    private int year;
+    private long periodStart;
+    private long periodEnd;
+    private long count;
+    private double mean;
+    private double populationVariance;
+    private double min;
+    private double max;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(SCHEMA$, MODEL$);
+    }
+
+    /**
+     * Creates a Builder by copying an existing Builder.
+     * @param other The existing Builder to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = other.fieldSetFlags()[0];
+      }
+      if (isValidValue(fields()[1], other.year)) {
+        this.year = data().deepCopy(fields()[1].schema(), other.year);
+        fieldSetFlags()[1] = other.fieldSetFlags()[1];
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = other.fieldSetFlags()[2];
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = other.fieldSetFlags()[3];
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = other.fieldSetFlags()[4];
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = other.fieldSetFlags()[5];
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = other.fieldSetFlags()[6];
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = other.fieldSetFlags()[7];
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = other.fieldSetFlags()[8];
+      }
+    }
+
+    /**
+     * Creates a Builder by copying an existing YearActivePowerRecord instance
+     * @param other The existing instance to copy.
+     */
+    private Builder(rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord other) {
+      super(SCHEMA$, MODEL$);
+      if (isValidValue(fields()[0], other.identifier)) {
+        this.identifier = data().deepCopy(fields()[0].schema(), other.identifier);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.year)) {
+        this.year = data().deepCopy(fields()[1].schema(), other.year);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.periodStart)) {
+        this.periodStart = data().deepCopy(fields()[2].schema(), other.periodStart);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.periodEnd)) {
+        this.periodEnd = data().deepCopy(fields()[3].schema(), other.periodEnd);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.count)) {
+        this.count = data().deepCopy(fields()[4].schema(), other.count);
+        fieldSetFlags()[4] = true;
+      }
+      if (isValidValue(fields()[5], other.mean)) {
+        this.mean = data().deepCopy(fields()[5].schema(), other.mean);
+        fieldSetFlags()[5] = true;
+      }
+      if (isValidValue(fields()[6], other.populationVariance)) {
+        this.populationVariance = data().deepCopy(fields()[6].schema(), other.populationVariance);
+        fieldSetFlags()[6] = true;
+      }
+      if (isValidValue(fields()[7], other.min)) {
+        this.min = data().deepCopy(fields()[7].schema(), other.min);
+        fieldSetFlags()[7] = true;
+      }
+      if (isValidValue(fields()[8], other.max)) {
+        this.max = data().deepCopy(fields()[8].schema(), other.max);
+        fieldSetFlags()[8] = true;
+      }
+    }
+
+    /**
+      * Gets the value of the 'identifier' field.
+      * @return The value.
+      */
+    public java.lang.String getIdentifier() {
+      return identifier;
+    }
+
+
+    /**
+      * Sets the value of the 'identifier' field.
+      * @param value The value of 'identifier'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setIdentifier(java.lang.String value) {
+      validate(fields()[0], value);
+      this.identifier = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'identifier' field has been set.
+      * @return True if the 'identifier' field has been set, false otherwise.
+      */
+    public boolean hasIdentifier() {
+      return fieldSetFlags()[0];
+    }
+
+
+    /**
+      * Clears the value of the 'identifier' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearIdentifier() {
+      identifier = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'year' field.
+      * @return The value.
+      */
+    public int getYear() {
+      return year;
+    }
+
+
+    /**
+      * Sets the value of the 'year' field.
+      * @param value The value of 'year'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setYear(int value) {
+      validate(fields()[1], value);
+      this.year = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'year' field has been set.
+      * @return True if the 'year' field has been set, false otherwise.
+      */
+    public boolean hasYear() {
+      return fieldSetFlags()[1];
+    }
+
+
+    /**
+      * Clears the value of the 'year' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearYear() {
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodStart' field.
+      * @return The value.
+      */
+    public long getPeriodStart() {
+      return periodStart;
+    }
+
+
+    /**
+      * Sets the value of the 'periodStart' field.
+      * @param value The value of 'periodStart'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setPeriodStart(long value) {
+      validate(fields()[2], value);
+      this.periodStart = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodStart' field has been set.
+      * @return True if the 'periodStart' field has been set, false otherwise.
+      */
+    public boolean hasPeriodStart() {
+      return fieldSetFlags()[2];
+    }
+
+
+    /**
+      * Clears the value of the 'periodStart' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearPeriodStart() {
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'periodEnd' field.
+      * @return The value.
+      */
+    public long getPeriodEnd() {
+      return periodEnd;
+    }
+
+
+    /**
+      * Sets the value of the 'periodEnd' field.
+      * @param value The value of 'periodEnd'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setPeriodEnd(long value) {
+      validate(fields()[3], value);
+      this.periodEnd = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'periodEnd' field has been set.
+      * @return True if the 'periodEnd' field has been set, false otherwise.
+      */
+    public boolean hasPeriodEnd() {
+      return fieldSetFlags()[3];
+    }
+
+
+    /**
+      * Clears the value of the 'periodEnd' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearPeriodEnd() {
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'count' field.
+      * @return The value.
+      */
+    public long getCount() {
+      return count;
+    }
+
+
+    /**
+      * Sets the value of the 'count' field.
+      * @param value The value of 'count'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setCount(long value) {
+      validate(fields()[4], value);
+      this.count = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'count' field has been set.
+      * @return True if the 'count' field has been set, false otherwise.
+      */
+    public boolean hasCount() {
+      return fieldSetFlags()[4];
+    }
+
+
+    /**
+      * Clears the value of the 'count' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearCount() {
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'mean' field.
+      * @return The value.
+      */
+    public double getMean() {
+      return mean;
+    }
+
+
+    /**
+      * Sets the value of the 'mean' field.
+      * @param value The value of 'mean'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setMean(double value) {
+      validate(fields()[5], value);
+      this.mean = value;
+      fieldSetFlags()[5] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'mean' field has been set.
+      * @return True if the 'mean' field has been set, false otherwise.
+      */
+    public boolean hasMean() {
+      return fieldSetFlags()[5];
+    }
+
+
+    /**
+      * Clears the value of the 'mean' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearMean() {
+      fieldSetFlags()[5] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'populationVariance' field.
+      * @return The value.
+      */
+    public double getPopulationVariance() {
+      return populationVariance;
+    }
+
+
+    /**
+      * Sets the value of the 'populationVariance' field.
+      * @param value The value of 'populationVariance'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setPopulationVariance(double value) {
+      validate(fields()[6], value);
+      this.populationVariance = value;
+      fieldSetFlags()[6] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'populationVariance' field has been set.
+      * @return True if the 'populationVariance' field has been set, false otherwise.
+      */
+    public boolean hasPopulationVariance() {
+      return fieldSetFlags()[6];
+    }
+
+
+    /**
+      * Clears the value of the 'populationVariance' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearPopulationVariance() {
+      fieldSetFlags()[6] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'min' field.
+      * @return The value.
+      */
+    public double getMin() {
+      return min;
+    }
+
+
+    /**
+      * Sets the value of the 'min' field.
+      * @param value The value of 'min'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setMin(double value) {
+      validate(fields()[7], value);
+      this.min = value;
+      fieldSetFlags()[7] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'min' field has been set.
+      * @return True if the 'min' field has been set, false otherwise.
+      */
+    public boolean hasMin() {
+      return fieldSetFlags()[7];
+    }
+
+
+    /**
+      * Clears the value of the 'min' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearMin() {
+      fieldSetFlags()[7] = false;
+      return this;
+    }
+
+    /**
+      * Gets the value of the 'max' field.
+      * @return The value.
+      */
+    public double getMax() {
+      return max;
+    }
+
+
+    /**
+      * Sets the value of the 'max' field.
+      * @param value The value of 'max'.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder setMax(double value) {
+      validate(fields()[8], value);
+      this.max = value;
+      fieldSetFlags()[8] = true;
+      return this;
+    }
+
+    /**
+      * Checks whether the 'max' field has been set.
+      * @return True if the 'max' field has been set, false otherwise.
+      */
+    public boolean hasMax() {
+      return fieldSetFlags()[8];
+    }
+
+
+    /**
+      * Clears the value of the 'max' field.
+      * @return This builder.
+      */
+    public rocks.theodolite.benchmarks.commons.model.records.YearActivePowerRecord.Builder clearMax() {
+      fieldSetFlags()[8] = false;
+      return this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public YearActivePowerRecord build() {
+      try {
+        YearActivePowerRecord record = new YearActivePowerRecord();
+        record.identifier = fieldSetFlags()[0] ? this.identifier : (java.lang.String) defaultValue(fields()[0]);
+        record.year = fieldSetFlags()[1] ? this.year : (java.lang.Integer) defaultValue(fields()[1]);
+        record.periodStart = fieldSetFlags()[2] ? this.periodStart : (java.lang.Long) defaultValue(fields()[2]);
+        record.periodEnd = fieldSetFlags()[3] ? this.periodEnd : (java.lang.Long) defaultValue(fields()[3]);
+        record.count = fieldSetFlags()[4] ? this.count : (java.lang.Long) defaultValue(fields()[4]);
+        record.mean = fieldSetFlags()[5] ? this.mean : (java.lang.Double) defaultValue(fields()[5]);
+        record.populationVariance = fieldSetFlags()[6] ? this.populationVariance : (java.lang.Double) defaultValue(fields()[6]);
+        record.min = fieldSetFlags()[7] ? this.min : (java.lang.Double) defaultValue(fields()[7]);
+        record.max = fieldSetFlags()[8] ? this.max : (java.lang.Double) defaultValue(fields()[8]);
+        return record;
+      } catch (org.apache.avro.AvroMissingFieldException e) {
+        throw e;
+      } catch (java.lang.Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumWriter<YearActivePowerRecord>
+    WRITER$ = (org.apache.avro.io.DatumWriter<YearActivePowerRecord>)MODEL$.createDatumWriter(SCHEMA$);
+
+  @Override public void writeExternal(java.io.ObjectOutput out)
+    throws java.io.IOException {
+    WRITER$.write(this, SpecificData.getEncoder(out));
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final org.apache.avro.io.DatumReader<YearActivePowerRecord>
+    READER$ = (org.apache.avro.io.DatumReader<YearActivePowerRecord>)MODEL$.createDatumReader(SCHEMA$);
+
+  @Override public void readExternal(java.io.ObjectInput in)
+    throws java.io.IOException {
+    READER$.read(this, SpecificData.getDecoder(in));
+  }
+
+  @Override protected boolean hasCustomCoders() { return true; }
+
+  @Override public void customEncode(org.apache.avro.io.Encoder out)
+    throws java.io.IOException
+  {
+    out.writeString(this.identifier);
+
+    out.writeInt(this.year);
+
+    out.writeLong(this.periodStart);
+
+    out.writeLong(this.periodEnd);
+
+    out.writeLong(this.count);
+
+    out.writeDouble(this.mean);
+
+    out.writeDouble(this.populationVariance);
+
+    out.writeDouble(this.min);
+
+    out.writeDouble(this.max);
+
+  }
+
+  @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in)
+    throws java.io.IOException
+  {
+    org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff();
+    if (fieldOrder == null) {
+      this.identifier = in.readString();
+
+      this.year = in.readInt();
+
+      this.periodStart = in.readLong();
+
+      this.periodEnd = in.readLong();
+
+      this.count = in.readLong();
+
+      this.mean = in.readDouble();
+
+      this.populationVariance = in.readDouble();
+
+      this.min = in.readDouble();
+
+      this.max = in.readDouble();
+
+    } else {
+      for (int i = 0; i < 9; i++) {
+        switch (fieldOrder[i].pos()) {
+        case 0:
+          this.identifier = in.readString();
+          break;
+
+        case 1:
+          this.year = in.readInt();
+          break;
+
+        case 2:
+          this.periodStart = in.readLong();
+          break;
+
+        case 3:
+          this.periodEnd = in.readLong();
+          break;
+
+        case 4:
+          this.count = in.readLong();
+          break;
+
+        case 5:
+          this.mean = in.readDouble();
+          break;
+
+        case 6:
+          this.populationVariance = in.readDouble();
+          break;
+
+        case 7:
+          this.min = in.readDouble();
+          break;
+
+        case 8:
+          this.max = in.readDouble();
+          break;
+
+        default:
+          throw new java.io.IOException("Corrupt ResolvingDecoder.");
+        }
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/theodolite-benchmarks/commons/src/main/avro/ActivePower.avdl b/theodolite-benchmarks/commons/src/main/avro/ActivePower.avdl
new file mode 100644
index 0000000000000000000000000000000000000000..6ee82d6becc6393617d569de27d0b162f892e192
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/avro/ActivePower.avdl
@@ -0,0 +1,19 @@
+@namespace("rocks.theodolite.benchmarks.commons.model.records")
+protocol ActivePower {
+
+  record ActivePowerRecord {
+    /**
+     *
+     */
+    string identifier;
+    /**
+     *
+     */
+    long timestamp;
+    /**
+     *
+     */
+    double valueInW;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/avro/AggregatedActivePower.avdl b/theodolite-benchmarks/commons/src/main/avro/AggregatedActivePower.avdl
new file mode 100644
index 0000000000000000000000000000000000000000..571f30f3247cae7c829aaa7742a37f8f3c89cfed
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/avro/AggregatedActivePower.avdl
@@ -0,0 +1,27 @@
+@namespace("rocks.theodolite.benchmarks.commons.model.records")
+protocol AggregatedActivePower {
+
+  record AggregatedActivePowerRecord {
+    /**
+     *
+     */
+    string identifier;
+    /**
+     * 
+     */
+    long timestamp;
+    /**
+     * 
+     */
+    long count;
+    /**
+     * 
+     */
+    double sumInW;
+    /**
+     * 
+     */
+    double averageInW;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/avro/StatsActivePower.avdl b/theodolite-benchmarks/commons/src/main/avro/StatsActivePower.avdl
new file mode 100644
index 0000000000000000000000000000000000000000..9f4c6360661a6b40f267a17ae8205b8178044895
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/avro/StatsActivePower.avdl
@@ -0,0 +1,65 @@
+@namespace("rocks.theodolite.benchmarks.commons.model.records")
+protocol StatsActivePower {
+
+  record HourOfDayActivePowerRecord {
+    string identifier;
+    int hourOfDay;
+    long periodStart;
+    long periodEnd;
+    long count;
+    double mean;
+    double populationVariance;
+    double min;
+    double max;
+  }
+  
+  record DayOfWeekActivePowerRecord {
+    string identifier;
+    int dayOfWeek;
+    long periodStart;
+    long periodEnd;
+    long count;
+    double mean;
+    double populationVariance;
+    double min;
+    double max;
+  }
+
+  record HourOfWeekActivePowerRecord {
+    string identifier;
+    int dayOfWeek;
+    int hourOfDay;
+    long periodStart;
+    long periodEnd;
+    long count;
+    double mean;
+    double populationVariance;
+    double min;
+    double max;
+  }
+  
+  record MonthOfYearActivePowerRecord {
+    string identifier;
+    int monthOfYear;
+    long periodStart;
+    long periodEnd;
+    long count;
+    double mean;
+    double populationVariance;
+    double min;
+    double max;
+  }
+
+  record YearActivePowerRecord {
+    string identifier;
+    int year;
+    long periodStart;
+    long periodEnd;
+    long count;
+    double mean;
+    double populationVariance;
+    double min;
+    double max;
+  }
+
+}
\ No newline at end of file
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/commons/configuration/NameResolvingEnvironmentConfiguration.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/commons/configuration/NameResolvingEnvironmentConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb29d078d2fb5125103188247f1673a1da766536
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/commons/configuration/NameResolvingEnvironmentConfiguration.java
@@ -0,0 +1,34 @@
+package rocks.theodolite.benchmarks.commons.commons.configuration;
+
+import java.util.Locale;
+import org.apache.commons.configuration2.EnvironmentConfiguration;
+
+/**
+ * {@link EnvironmentConfiguration} that automatically translates Java property file style variables
+ * ({@code my.variable.name}) to environment style variables ({@code MY__VARIABLE_NAME}).
+ */
+public class NameResolvingEnvironmentConfiguration extends EnvironmentConfiguration {
+
+  @Override
+  protected Object getPropertyInternal(final String key) {
+    final Object value = super.getPropertyInternal(key);
+    if (value == null) {
+      return super.getPropertyInternal(formatKeyAsEnvVariable(key));
+    }
+    return value;
+  }
+
+  @Override
+  protected boolean containsKeyInternal(final String key) {
+    final boolean value = super.containsKeyInternal(key);
+    if (!value) {
+      return super.containsKeyInternal(formatKeyAsEnvVariable(key));
+    }
+    return value;
+  }
+
+  public static String formatKeyAsEnvVariable(final String key) {
+    return key.toUpperCase(Locale.ROOT).replace('.', '_');
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/commons/configuration/ServiceConfigurations.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/commons/configuration/ServiceConfigurations.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ad0703697aa02f641c9b86f7384bfd9b9e1956c
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/commons/configuration/ServiceConfigurations.java
@@ -0,0 +1,120 @@
+package rocks.theodolite.benchmarks.commons.commons.configuration;
+
+import com.google.common.io.Resources;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.apache.commons.configuration2.CompositeConfiguration;
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for creating {@link Configuration}s.
+ */
+public final class ServiceConfigurations {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceConfigurations.class);
+
+  private static final String DEFAULT_PROPERTIES_LOCATION = "META-INF/application.properties";
+  private static final String USER_PROPERTIES_LOCATION = "config/application.properties";
+
+  private ServiceConfigurations() {}
+
+  /**
+   * Create a {@link Configuration} as it typically used by microservices. More precisely, this
+   * means when trying to access value with a particular key, this configuration first looks for
+   * this key in the current environment variables, then in a properties file located in
+   * {@code config/application.properties}, and finally for a properties file in the classpath at
+   * {@code META-INF/application.properties}.
+   *
+   * @see NameResolvingEnvironmentConfiguration for details regarding the environemnt variable
+   *      lookup.
+   */
+  public static Configuration createWithDefaults() {
+    return builder()
+        .withEnvironmentVariables()
+        .withUserConfigurationFile(USER_PROPERTIES_LOCATION)
+        .withDefaultConfigurationFile(DEFAULT_PROPERTIES_LOCATION)
+        .build();
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /**
+   * Builder class for a {@link Configuration} for a microservice.
+   */
+  public static class Builder {
+
+    private final CompositeConfiguration configuration = new CompositeConfiguration();
+
+    private Builder() {}
+
+    public Builder withEnvironmentVariables() {
+      this.configuration.addConfiguration(new NameResolvingEnvironmentConfiguration());
+      return this;
+    }
+
+    /**
+     * Add a properties file from the user's file system to the {@link Configuration}.
+     */
+    public Builder withUserConfigurationFile(final String userPropertiesLocation) {
+      final Path path = Paths.get(userPropertiesLocation);
+      LOGGER.info("Looking for user configuration at {}", userPropertiesLocation);
+      if (Files.exists(path)) {
+        LOGGER.info("Found user configuration at {}", userPropertiesLocation);
+        try {
+          this.configuration.addConfiguration(configurations().properties(path.toFile()));
+        } catch (final ConfigurationException e) {
+          throw new IllegalArgumentException(
+              "Cannot load configuration from file '" + userPropertiesLocation + "'", e);
+        }
+      } else {
+        LOGGER.info("No user configuration found at {}", userPropertiesLocation);
+      }
+      return this;
+    }
+
+    /**
+     * Add a properties file from the class path to the {@link Configuration}.
+     */
+    public Builder withDefaultConfigurationFile(final String defaultPropertiesLocation) {
+      if (resourceExists(defaultPropertiesLocation)) {
+        try {
+          this.configuration
+              .addConfiguration(configurations().properties(defaultPropertiesLocation));
+        } catch (final ConfigurationException e) {
+          throw new IllegalArgumentException(
+              "Cannot load configuration from ressource '" + defaultPropertiesLocation + "'", e);
+        }
+      }
+      return this;
+    }
+
+    public Configuration build() {
+      return this.configuration;
+    }
+
+  }
+
+  /**
+   * Shortcut for long class name.
+   */
+  private static org.apache.commons.configuration2.builder.fluent.Configurations configurations() {
+    // TODO Refactor when Configurations class is removed
+    return new org.apache.commons.configuration2.builder.fluent.Configurations();
+  }
+
+  private static boolean resourceExists(final String resourceName) {
+    try {
+      Resources.getResource(resourceName);
+    } catch (final IllegalArgumentException e) {
+      return false;
+    }
+    return true;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/configuration/events/Event.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/configuration/events/Event.java
new file mode 100644
index 0000000000000000000000000000000000000000..895b3401c5d59abb6863caa246414e9ead69d773
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/configuration/events/Event.java
@@ -0,0 +1,13 @@
+package rocks.theodolite.benchmarks.commons.configuration.events;
+
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
+
+/**
+ * Events that could occur when modifying a {@link SensorRegistry}. Currently only a general change
+ * event and a status posting event are supported.
+ */
+public enum Event {
+
+  SENSOR_REGISTRY_CHANGED, SENSOR_REGISTRY_STATUS;
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/configuration/events/EventSerde.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/configuration/events/EventSerde.java
new file mode 100644
index 0000000000000000000000000000000000000000..50a3faad61d6c6179efe983b0c172e66e0d28367
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/configuration/events/EventSerde.java
@@ -0,0 +1,81 @@
+package rocks.theodolite.benchmarks.commons.configuration.events;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+import org.apache.kafka.common.serialization.ByteBufferDeserializer;
+import org.apache.kafka.common.serialization.ByteBufferSerializer;
+import org.apache.kafka.common.serialization.Deserializer;
+import org.apache.kafka.common.serialization.Serde;
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.common.serialization.Serializer;
+
+/**
+ * Provides factory methods for creating Kafka serializers and deserializers for {@link Event}s.
+ */
+public final class EventSerde {
+
+  private EventSerde() {}
+
+  public static Serde<Event> serde() {
+    return Serdes.serdeFrom(new EventSerializer(), new EventDeserializer());
+  }
+
+  public static Serializer<Event> serializer() {
+    return new EventSerializer();
+  }
+
+  public static Deserializer<Event> deserializer() {
+    return new EventDeserializer();
+  }
+
+  private static class EventSerializer implements Serializer<Event> {
+
+    private static final int INT_SIZE = 4;
+
+    private final ByteBufferSerializer byteBufferSerializer = new ByteBufferSerializer();
+
+    @Override
+    public void configure(final Map<String, ?> configs, final boolean isKey) {
+      this.byteBufferSerializer.configure(configs, isKey);
+    }
+
+    @Override
+    public byte[] serialize(final String topic, final Event event) {
+      return this.byteBufferSerializer.serialize(topic,
+          ByteBuffer.allocate(INT_SIZE).putInt(event.ordinal()));
+    }
+
+    @Override
+    public void close() {
+      this.byteBufferSerializer.close();
+    }
+
+  }
+
+  private static class EventDeserializer implements Deserializer<Event> {
+
+    private final ByteBufferDeserializer byteBufferDeserializer = new ByteBufferDeserializer();
+
+    @Override
+    public void configure(final Map<String, ?> configs, final boolean isKey) {
+      this.byteBufferDeserializer.configure(configs, isKey);
+    }
+
+    @Override
+    public Event deserialize(final String topic, final byte[] data) {
+      final int ordinal = this.byteBufferDeserializer.deserialize(topic, data).getInt();
+      for (final Event event : Event.values()) {
+        if (ordinal == event.ordinal()) {
+          return event;
+        }
+      }
+      throw new IllegalArgumentException("Deserialized data is not a valid event.");
+    }
+
+    @Override
+    public void close() {
+      this.byteBufferDeserializer.close();
+    }
+
+  }
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/avro/SchemaRegistryAvroSerdeFactory.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/avro/SchemaRegistryAvroSerdeFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f3d5721efd90000b9265b593be5656b989c4f44
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/avro/SchemaRegistryAvroSerdeFactory.java
@@ -0,0 +1,39 @@
+package rocks.theodolite.benchmarks.commons.kafka.avro;
+
+import io.confluent.kafka.serializers.AbstractKafkaAvroSerDeConfig;
+import io.confluent.kafka.streams.serdes.avro.SpecificAvroSerde;
+import java.util.Collections;
+import java.util.Map;
+import org.apache.avro.specific.SpecificRecord;
+import org.apache.kafka.common.serialization.Serde;
+
+/**
+ * Factory methods to create {@link Serde}s for Avro records using the Confluent Schema Registry.
+ */
+public final class SchemaRegistryAvroSerdeFactory {
+
+  private static final String SCHEMA_REGISTRY_URL_KEY =
+      AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG;
+
+  private final Map<String, String> serdeConfig;
+
+  public SchemaRegistryAvroSerdeFactory(final String schemaRegistryUrl) {
+    this.serdeConfig = Collections.singletonMap(SCHEMA_REGISTRY_URL_KEY, schemaRegistryUrl);
+
+  }
+
+  public <T extends SpecificRecord> Serde<T> forKeys() {
+    return this.build(true);
+  }
+
+  public <T extends SpecificRecord> Serde<T> forValues() {
+    return this.build(false);
+  }
+
+  private <T extends SpecificRecord> Serde<T> build(final boolean isKey) {
+    final Serde<T> avroSerde = new SpecificAvroSerde<>();
+    avroSerde.configure(this.serdeConfig, isKey);
+    return avroSerde;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferConstants.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..b29c05359d04ebf2552da7a3c3a6b915ede1cd35
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferConstants.java
@@ -0,0 +1,18 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+import java.nio.charset.Charset;
+
+/**
+ * Shared constants between {@link WriteBuffer} and {@link ReadBuffer}.
+ */
+public final class BufferConstants {
+
+  public static final Charset CHARSET = Charset.forName("UTF-8");
+
+  public static final byte BOOLEAN_FALSE = 0;
+
+  public static final byte BOOLEAN_TRUE = 1;
+
+  private BufferConstants() {}
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferDeserializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferDeserializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..88fba611be5600d3a5557b34d5244e523dcbb017
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferDeserializer.java
@@ -0,0 +1,13 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+/**
+ * Deserializer to deserialize a {@link ReadBuffer} to an object.
+ *
+ * @param <T> the type of the deserialized object
+ */
+@FunctionalInterface
+public interface BufferDeserializer<T> {
+
+  T deserialize(ReadBuffer buffer);
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferSerde.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferSerde.java
new file mode 100644
index 0000000000000000000000000000000000000000..e14f03e2b36e5551911536f2dff20f70e8efe08a
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferSerde.java
@@ -0,0 +1,11 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+/**
+ * Combine {@link BufferSerializer} and {@link BufferDeserializer} into one type. This allows
+ * implementing a serde in one class.
+ *
+ * @param <T> Type of the serializer and deserializer.
+ */
+public interface BufferSerde<T> extends BufferSerializer<T>, BufferDeserializer<T> {
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferSerializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c7353a64a39839f183ad4153f369e3d33bcfe5b
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/BufferSerializer.java
@@ -0,0 +1,13 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+/**
+ * Serializer to serialize an object to a {@link WriteBuffer}.
+ *
+ * @param <T> the type of the serialized object
+ */
+@FunctionalInterface
+public interface BufferSerializer<T> {
+
+  void serialize(WriteBuffer buffer, T data);
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/ReadBuffer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/ReadBuffer.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf0e7af93c31b20e7136d4f6b1c870691cd4801d
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/ReadBuffer.java
@@ -0,0 +1,67 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A buffer that is constructed from a byte array and data can be sequentially read to different
+ * kinds of data types. It is the counterpart to {@link WriteBuffer}.
+ */
+public class ReadBuffer {
+
+  private final ByteBuffer buffer;
+
+  /**
+   * Create this buffer by a byte array.
+   */
+  public ReadBuffer(final byte[] bytes) {
+    this.buffer = ByteBuffer.wrap(bytes);
+  }
+
+  public byte getByte() {
+    return this.buffer.get();
+  }
+
+  /**
+   * Get a byte array.
+   */
+  public byte[] getBytes() {
+    final int bytesLength = this.buffer.getInt();
+    final byte[] bytes = new byte[bytesLength];
+    this.buffer.get(bytes);
+    return bytes;
+  }
+
+  public boolean getBoolean() { // NOPMD
+    return this.getByte() == BufferConstants.BOOLEAN_TRUE;
+  }
+
+  public short getShort() { // NOPMD
+    return this.buffer.getShort();
+  }
+
+  public int getInt() {
+    return this.buffer.getInt();
+  }
+
+  public long getLong() {
+    return this.buffer.getLong();
+  }
+
+  public float getFloat() {
+    return this.buffer.getFloat();
+  }
+
+  public double getDouble() {
+    return this.buffer.getDouble();
+  }
+
+  public int getChar() {
+    return this.buffer.getChar();
+  }
+
+  public String getString() {
+    final byte[] bytes = this.getBytes();
+    return new String(bytes, BufferConstants.CHARSET);
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleDeserializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleDeserializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3d2b6756c417f62c85bfd5a269d0d47d36daa7c
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleDeserializer.java
@@ -0,0 +1,38 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+import java.util.Map;
+import org.apache.kafka.common.serialization.Deserializer;
+
+/**
+ * Kafka {@link Deserializer} to be configured with a {@link BufferDeserializer} for simpler usage.
+ *
+ * @param <T> the type of the deserialized object
+ */
+public class SimpleDeserializer<T> implements Deserializer<T> {
+
+  private final BufferDeserializer<T> deserializer;
+
+  public SimpleDeserializer(final BufferDeserializer<T> deserializer) {
+    this.deserializer = deserializer;
+  }
+
+  @Override
+  public void configure(final Map<String, ?> configs, final boolean isKey) {
+    // Do nothing
+  }
+
+  @Override
+  public T deserialize(final String topic, final byte[] bytes) {
+    if (bytes == null) {
+      return null;
+    }
+    final ReadBuffer buffer = new ReadBuffer(bytes);
+    return this.deserializer.deserialize(buffer);
+  }
+
+  @Override
+  public void close() {
+    // Do nothing
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleSerdes.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleSerdes.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae1c0530f8283122451b7e20d32f56300cdf6ef7
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleSerdes.java
@@ -0,0 +1,24 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+import org.apache.kafka.common.serialization.Serde;
+import org.apache.kafka.common.serialization.Serdes;
+
+/**
+ * Factory class to create <i>Simple Serdes</i>. These are serdes created from a
+ * {@link BufferSerializer} and a {@link BufferDeserializer}.
+ */
+public final class SimpleSerdes {
+
+  private SimpleSerdes() {}
+
+  public static <T> Serde<T> create(final BufferSerde<T> serde) {
+    return Serdes.serdeFrom(new SimpleSerializer<>(serde), new SimpleDeserializer<>(serde));
+  }
+
+  public static <T> Serde<T> create(final BufferSerializer<T> serializer,
+      final BufferDeserializer<T> deserializer) {
+    return Serdes.serdeFrom(new SimpleSerializer<>(serializer),
+        new SimpleDeserializer<>(deserializer));
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleSerializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ed3d91f74a3ad6bc3a0ff8f52d91e53a741e65d
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/SimpleSerializer.java
@@ -0,0 +1,39 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+import java.util.Map;
+import org.apache.kafka.common.serialization.Serializer;
+
+/**
+ * Kafka {@link Serializer} to be configured with a {@link BufferSerializer} for simpler usage.
+ *
+ * @param <T> the type of the serialized objects
+ */
+public class SimpleSerializer<T> implements Serializer<T> {
+
+  private final BufferSerializer<T> serializer;
+
+  public SimpleSerializer(final BufferSerializer<T> serializer) {
+    this.serializer = serializer;
+  }
+
+  @Override
+  public void configure(final Map<String, ?> configs, final boolean isKey) {
+    // Do nothing
+  }
+
+  @Override
+  public byte[] serialize(final String topic, final T data) {
+    if (data == null) {
+      return null;
+    }
+    final WriteBuffer buffer = new WriteBuffer();
+    this.serializer.serialize(buffer, data);
+    return buffer.getBytes();
+  }
+
+  @Override
+  public void close() {
+    // Do nothing
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/WriteBuffer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/WriteBuffer.java
new file mode 100644
index 0000000000000000000000000000000000000000..144b125f031250c09900360898f98f871643f036
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/kafka/simpleserdes/WriteBuffer.java
@@ -0,0 +1,69 @@
+package rocks.theodolite.benchmarks.commons.kafka.simpleserdes;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A buffer to which different kinds of data types can be written and its content can be returned as
+ * bytes. Its counterpart is a {@link ReadBuffer} which allows to read the data in the order it is
+ * written.
+ */
+public class WriteBuffer {
+
+  private static final int BYTE_BUFFER_CAPACITY = 65_536; // Is only virtual memory
+
+  private final ByteBuffer buffer = ByteBuffer.allocateDirect(BYTE_BUFFER_CAPACITY);
+
+  public void putByte(final byte value) {
+    this.buffer.put(value);
+  }
+
+  public void putBytes(final byte[] value) {
+    this.buffer.putInt(value.length);
+    this.buffer.put(value);
+  }
+
+  public void putBoolean(final boolean value) {
+    this.putByte(
+        value ? BufferConstants.BOOLEAN_TRUE : BufferConstants.BOOLEAN_FALSE);
+  }
+
+  public void putShort(final short value) { // NOPMD
+    this.buffer.putShort(value);
+  }
+
+  public void putInt(final int value) {
+    this.buffer.putInt(value);
+  }
+
+  public void putLong(final long value) {
+    this.buffer.putLong(value);
+  }
+
+  public void putFloat(final float value) {
+    this.buffer.putFloat(value);
+  }
+
+  public void putDouble(final double value) {
+    this.buffer.putDouble(value);
+  }
+
+  public void putChar(final char value) {
+    this.buffer.putChar(value);
+  }
+
+  public void putString(final String value) {
+    final byte[] bytes = value.getBytes(BufferConstants.CHARSET);
+    this.putBytes(bytes);
+  }
+
+  /**
+   * Get the content of this buffer as bytes.
+   */
+  public byte[] getBytes() {
+    this.buffer.flip();
+    final byte[] bytes = new byte[this.buffer.remaining()];
+    this.buffer.get(bytes, 0, bytes.length);
+    return bytes;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/AbstractSensor.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/AbstractSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..3dad538bb9ddb41959511ee41591d069450b7f69
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/AbstractSensor.java
@@ -0,0 +1,35 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.Optional;
+
+abstract class AbstractSensor implements Sensor {
+
+  private final AggregatedSensor parent;
+
+  private final String identifier;
+
+  private final String name;
+
+  protected AbstractSensor(final AggregatedSensor parent, final String identifier,
+      final String name) {
+    this.parent = parent;
+    this.identifier = identifier;
+    this.name = name;
+  }
+
+  @Override
+  public Optional<AggregatedSensor> getParent() {
+    return Optional.ofNullable(this.parent);
+  }
+
+  @Override
+  public String getIdentifier() {
+    return this.identifier;
+  }
+
+  @Override
+  public String getName() {
+    return this.name;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/AggregatedSensor.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/AggregatedSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa8717ded4643f2350174e4c26dd10ffe608d2ac
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/AggregatedSensor.java
@@ -0,0 +1,56 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * Representing an aggregated sensor in the {@link SensorRegistry}, i.e. one that may have child
+ * sensors.
+ */
+public interface AggregatedSensor extends Sensor {
+
+  Collection<Sensor> getChildren();
+
+  /**
+   * Returns all {@link MachineSensor}s that are children (including grandchildren etc.) of this
+   * aggregated sensor. In other words, it returns all leaves located below this aggregated sensor
+   * in the corresponding {@link SensorRegistry}.
+   */
+  default Collection<MachineSensor> getAllChildren() {
+    final List<MachineSensor> allChildren = new ArrayList<>();
+    final Queue<Sensor> untraversedSensors = new LinkedList<>(this.getChildren());
+    while (!untraversedSensors.isEmpty()) {
+      final Sensor sensor = untraversedSensors.poll();
+      if (sensor instanceof MachineSensor) {
+        allChildren.add((MachineSensor) sensor);
+      } else if (sensor instanceof AggregatedSensor) {
+        untraversedSensors.addAll(((AggregatedSensor) sensor).getChildren());
+      }
+    }
+    return allChildren;
+  }
+
+  /**
+   * Flattens this {@link AggregatedSensor} and all of its children to a collection of
+   * {@link Sensor}s.
+   *
+   * @return A collection containing this {@link AggregatedSensor} and all of its children.
+   */
+  default Collection<Sensor> flatten() {
+    final List<Sensor> accumulator = new ArrayList<>();
+    final Queue<Sensor> untraversedSensors = new LinkedList<>();
+    untraversedSensors.add(this);
+    while (!untraversedSensors.isEmpty()) {
+      final Sensor sensor = untraversedSensors.poll();
+      accumulator.add(sensor);
+      if (sensor instanceof AggregatedSensor) {
+        untraversedSensors.addAll(((AggregatedSensor) sensor).getChildren());
+      }
+    }
+    return accumulator;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ImmutableSensorRegistry.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ImmutableSensorRegistry.java
new file mode 100644
index 0000000000000000000000000000000000000000..bac00a0c0c4086c1e3847619e5603f020ca78e8a
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ImmutableSensorRegistry.java
@@ -0,0 +1,145 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.AggregatedSensorSerializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.MachineSensorSerializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.SensorRegistryDeserializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.SensorRegistrySerializer;
+
+/**
+ * Implementation of a {@link SensorRegistry} that is immutable.
+ */
+public final class ImmutableSensorRegistry implements SensorRegistry {
+
+  private static final Gson GSON = new GsonBuilder()
+      .registerTypeAdapter(ImmutableSensorRegistry.class, new SensorRegistrySerializer())
+      .registerTypeAdapter(ImmutableSensorRegistry.ImmutableAggregatatedSensor.class,
+          new AggregatedSensorSerializer())
+      .registerTypeAdapter(MachineSensorImpl.class, new MachineSensorSerializer())
+      .registerTypeAdapter(SensorRegistry.class, new SensorRegistryDeserializer()).create();
+
+  private final ImmutableMap<String, MachineSensor> machineSensors;
+  private final AggregatedSensor topLevelSensor;
+
+  private ImmutableSensorRegistry(final SensorRegistry sensorRegistry) {
+    final ImmutableMap.Builder<String, MachineSensor> mapBuilder = ImmutableMap.builder();
+    this.topLevelSensor =
+        new ImmutableAggregatatedSensor(null, sensorRegistry.getTopLevelSensor(), mapBuilder);
+    this.machineSensors = mapBuilder.build();
+  }
+
+  @Override
+  public Optional<MachineSensor> getSensorForIdentifier(final String identifier) {
+    return Optional.ofNullable(this.machineSensors.get(identifier));
+  }
+
+  @Override
+  public AggregatedSensor getTopLevelSensor() {
+    return this.topLevelSensor;
+  }
+
+  @Override
+  public Collection<MachineSensor> getMachineSensors() {
+    return this.machineSensors.values();
+  }
+
+  @Override
+  public String toJson() {
+    // Necessary method. Deletion would cause SensorRegistry.toJson() to fail.
+    return GSON.toJson(this);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(this.topLevelSensor);
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof SensorRegistry) {
+      final SensorRegistry other = (SensorRegistry) obj;
+      return Objects.equals(this.getTopLevelSensor(), other.getTopLevelSensor());
+    }
+    return false;
+  }
+
+  public static ImmutableSensorRegistry copyOf(final SensorRegistry sensorRegistry) {
+    return new ImmutableSensorRegistry(sensorRegistry);
+  }
+
+  public static SensorRegistry fromJson(final String json) {
+    return GSON.fromJson(json, SensorRegistry.class);
+  }
+
+  private static final class ImmutableAggregatatedSensor extends AbstractSensor
+      implements AggregatedSensor {
+
+    private final ImmutableList<Sensor> children;
+
+    private ImmutableAggregatatedSensor(final AggregatedSensor newParent,
+        final AggregatedSensor sensorToCopy,
+        final ImmutableMap.Builder<String, MachineSensor> sensorRegistryMapBuilder) {
+      super(newParent, sensorToCopy.getIdentifier(), sensorToCopy.getName());
+      final Builder<Sensor> childrenBuilder = ImmutableList.builder();
+      for (final Sensor child : sensorToCopy.getChildren()) {
+        if (child instanceof MachineSensor) {
+          final MachineSensor newChild =
+              new MachineSensorImpl(this, child.getIdentifier(), child.getName());
+          childrenBuilder.add(newChild);
+          sensorRegistryMapBuilder.put(newChild.getIdentifier(), newChild);
+        } else if (child instanceof AggregatedSensor) {
+          final AggregatedSensor newChild = new ImmutableAggregatatedSensor(this,
+              (AggregatedSensor) child, sensorRegistryMapBuilder);
+          childrenBuilder.add(newChild);
+        } else {
+          throw new IllegalStateException(
+              "Sensor " + child + " is neither of type '"
+                  + MachineSensor.class.getSimpleName() + "' nor "
+                  + AggregatedSensor.class.getSimpleName() + "' and thus not supported.");
+        }
+      }
+      this.children = childrenBuilder.build();
+    }
+
+    @Override
+    public Collection<Sensor> getChildren() {
+      return this.children;
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(this.getIdentifier(), this.children);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+      if (obj == this) {
+        return true;
+      }
+      if (obj instanceof AggregatedSensor) {
+        final AggregatedSensor other = (AggregatedSensor) obj;
+        return Objects.equals(this.getIdentifier(), other.getIdentifier())
+            && Objects.equals(this.children, other.getChildren());
+      }
+      return false;
+    }
+
+    @Override
+    public String toString() {
+      return this.getName() + '[' + this.getIdentifier() + "] (" + this.children.size()
+          + " children)";
+    }
+
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MachineSensor.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MachineSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..cdb4b535bffd807acb92fbfd057f5986b4840ba8
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MachineSensor.java
@@ -0,0 +1,25 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Representing a real sensor in the {@link SensorRegistry}, i.e. one that is not aggregated.
+ */
+public interface MachineSensor extends Sensor {
+
+  /**
+   * Get a list of parent, grandparent etc. sensors.
+   */
+  default List<AggregatedSensor> getParents() {
+    Optional<AggregatedSensor> parent = this.getParent();
+    final List<AggregatedSensor> parents = new ArrayList<>();
+    while (parent.isPresent()) {
+      parents.add(parent.get());
+      parent = parent.get().getParent();
+    }
+    return parents;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MachineSensorImpl.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MachineSensorImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..191664bfdee31874003d7420ef7f81560c4fe29b
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MachineSensorImpl.java
@@ -0,0 +1,34 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.Objects;
+
+class MachineSensorImpl extends AbstractSensor implements MachineSensor {
+
+  protected MachineSensorImpl(final AggregatedSensor parent, final String identifier,
+      final String name) {
+    super(parent, identifier, name);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(this.getIdentifier());
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof MachineSensor) {
+      final MachineSensor other = (MachineSensor) obj;
+      return Objects.equals(this.getIdentifier(), other.getIdentifier());
+    }
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return this.getName() + '[' + this.getIdentifier() + ']';
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableAggregatedSensor.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableAggregatedSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0b5e42c83998622294adcb38dab50fd591d286d
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableAggregatedSensor.java
@@ -0,0 +1,96 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A {@link MutableAggregatedSensor} which can child sensors be added to.
+ */
+public class MutableAggregatedSensor extends AbstractSensor implements AggregatedSensor {
+
+  private final List<Sensor> children = new ArrayList<>();
+  private final MutableSensorRegistry sensorRegistry;
+
+  protected MutableAggregatedSensor(final MutableSensorRegistry registry, final String identifier,
+      final String name) {
+    super(null, identifier, name);
+    this.sensorRegistry = registry;
+  }
+
+  protected MutableAggregatedSensor(final MutableAggregatedSensor parent, final String identifier,
+      final String name) {
+    super(parent, identifier, name);
+    this.sensorRegistry = parent.sensorRegistry;
+  }
+
+  @Override
+  public Collection<Sensor> getChildren() {
+    return this.children;
+  }
+
+  /**
+   * Create a new {@link MutableAggregatedSensor} as child of this sensor.
+   */
+  public MutableAggregatedSensor addChildAggregatedSensor(final String identifier) {
+    return this.addChildAggregatedSensor(identifier, "");
+  }
+
+  /**
+   * Create a new {@link MutableAggregatedSensor} as child of this sensor.
+   */
+  public MutableAggregatedSensor addChildAggregatedSensor(final String identifier,
+      final String name) {
+    final MutableAggregatedSensor aggregatedSensor =
+        new MutableAggregatedSensor(this, identifier, name);
+    this.children.add(aggregatedSensor);
+    return aggregatedSensor;
+  }
+
+  /**
+   * Create a new {@link MachineSensor} as child of this sensor.
+   */
+  public MachineSensor addChildMachineSensor(final String identifier) {
+    return this.addChildMachineSensor(identifier, "");
+  }
+
+  /**
+   * Create a new {@link MachineSensor} as child of this sensor.
+   */
+  public MachineSensor addChildMachineSensor(final String identifier, final String name) {
+    final MachineSensorImpl machineSensor = new MachineSensorImpl(this, identifier, name);
+    final boolean registerResult = this.sensorRegistry.register(machineSensor);
+    if (!registerResult) {
+      throw new IllegalArgumentException(
+          "Sensor width identifier " + identifier + " is already registered.");
+    }
+    this.children.add(machineSensor);
+    return machineSensor;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(this.getIdentifier(), this.children);
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof AggregatedSensor) {
+      final AggregatedSensor other = (AggregatedSensor) obj;
+      return Objects.equals(this.getIdentifier(), other.getIdentifier())
+          && Objects.equals(this.children, other.getChildren());
+    }
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return this.getName() + '[' + this.getIdentifier() + "] (" + this.children.size()
+        + " children)";
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableSensorRegistry.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableSensorRegistry.java
new file mode 100644
index 0000000000000000000000000000000000000000..53a0418e6c2a8efe6139fd2150de218b4f8c6966
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableSensorRegistry.java
@@ -0,0 +1,84 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.AggregatedSensorSerializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.MachineSensorSerializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.SensorRegistrySerializer;
+
+/**
+ * A {@link SensorRegistry} to which sensors can be added.
+ */
+public class MutableSensorRegistry implements SensorRegistry {
+
+  private static final Gson GSON = new GsonBuilder()
+      .registerTypeAdapter(MutableSensorRegistry.class, new SensorRegistrySerializer())
+      .registerTypeAdapter(MutableAggregatedSensor.class, new AggregatedSensorSerializer())
+      .registerTypeAdapter(MachineSensorImpl.class, new MachineSensorSerializer()).create();
+
+  // TODO HashMap for efficient access to machine sensors
+  private final Map<String, MachineSensorImpl> machineSensors = new HashMap<>();
+
+  // TODO maybe access to root
+  private final MutableAggregatedSensor topLevelSensor;
+
+  public MutableSensorRegistry(final String topLevelSensorIdentifier) {
+    this(topLevelSensorIdentifier, "");
+  }
+
+  public MutableSensorRegistry(final String topLevelSensorIdentifier,
+      final String topLevelSensorName) {
+    this.topLevelSensor =
+        new MutableAggregatedSensor(this, topLevelSensorIdentifier, topLevelSensorName);
+  }
+
+  @Override
+  public Optional<MachineSensor> getSensorForIdentifier(final String identifier) {
+    return Optional.ofNullable(this.machineSensors.get(identifier));
+  }
+
+  @Override
+  public MutableAggregatedSensor getTopLevelSensor() {
+    return this.topLevelSensor;
+  }
+
+  @Override
+  public Collection<MachineSensor> getMachineSensors() {
+    return Collections.unmodifiableCollection(this.machineSensors.values());
+  }
+
+  protected boolean register(final MachineSensorImpl machineSensor) {
+    final Object oldValue =
+        this.machineSensors.putIfAbsent(machineSensor.getIdentifier(), machineSensor);
+    return oldValue == null;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(this.topLevelSensor);
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof SensorRegistry) {
+      final SensorRegistry other = (SensorRegistry) obj;
+      return Objects.equals(this.getTopLevelSensor(), other.getTopLevelSensor());
+    }
+    return false;
+  }
+
+  @Override
+  public String toJson() {
+    return GSON.toJson(this);
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/Sensor.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/Sensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b22cc81d3912d8094ae67475ce261ce958d3d236
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/Sensor.java
@@ -0,0 +1,16 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.Optional;
+
+/**
+ * Class representing a sensor in the {@link SensorRegistry}.
+ */
+public interface Sensor {
+
+  Optional<AggregatedSensor> getParent();
+
+  String getIdentifier();
+
+  String getName();
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/SensorRegistry.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/SensorRegistry.java
new file mode 100644
index 0000000000000000000000000000000000000000..e079f5c12e4a3ddfe9f680860444c239ae51aa6b
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/SensorRegistry.java
@@ -0,0 +1,45 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Hierarchical data structure (i.e. a tree) for organizing sensors. A {@link SensorRegistry} has
+ * one top-level sensor which can have multiple child sensors. These sensors can either be real
+ * {@link MachineSensor}s or {@link AggregatedSensor}s, having child sensors.
+ */
+public interface SensorRegistry {
+
+  Optional<MachineSensor> getSensorForIdentifier(final String identifier);
+
+  AggregatedSensor getTopLevelSensor();
+
+  Collection<MachineSensor> getMachineSensors();
+
+  /**
+   * Flattens the hierarchy to a collection of all contained {@link Sensor}s.
+   *
+   * @return A collection of all {@link Sensor}s contained in the hierarchy.
+   */
+  default Collection<Sensor> flatten() {
+    return this.getTopLevelSensor().flatten();
+  }
+
+  /**
+   * Converts this sensor registry into a json string.
+   *
+   * <p>
+   * Per default a copy of this sensor registry is created to ensure that proper (de)serializers
+   * exist. If subclasses have appropriate serdes, they should override this method.
+   * </p>
+   */
+  default String toJson() {
+    final ImmutableSensorRegistry immutableSensorRegistry = ImmutableSensorRegistry.copyOf(this);
+    return immutableSensorRegistry.toJson();
+  }
+
+  static SensorRegistry fromJson(final String json) {
+    return ImmutableSensorRegistry.fromJson(json);
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/AggregatedSensorSerializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/AggregatedSensorSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..64156fbc10af5a64a02107840d3586cafc30f6e8
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/AggregatedSensorSerializer.java
@@ -0,0 +1,25 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+
+/**
+ * {@link JsonSerializer} for {@link AggregatedSensor}s.
+ */
+public final class AggregatedSensorSerializer implements JsonSerializer<AggregatedSensor> {
+
+  @Override
+  public JsonElement serialize(final AggregatedSensor sensor, final Type type,
+      final JsonSerializationContext context) {
+    final JsonObject jsonSensorObject = new JsonObject();
+    jsonSensorObject.addProperty("identifier", sensor.getIdentifier());
+    jsonSensorObject.addProperty("name", sensor.getName());
+    jsonSensorObject.add("children", context.serialize(sensor.getChildren()));
+    return jsonSensorObject;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/MachineSensorSerializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/MachineSensorSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..4301552e922801d402f456b51a5607d9e1351294
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/MachineSensorSerializer.java
@@ -0,0 +1,24 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MachineSensor;
+
+/**
+ * {@link JsonSerializer} for {@link MachineSensor}s.
+ */
+public final class MachineSensorSerializer implements JsonSerializer<MachineSensor> {
+
+  @Override
+  public JsonElement serialize(final MachineSensor sensor, final Type type,
+      final JsonSerializationContext context) {
+    final JsonObject jsonSensorObject = new JsonObject();
+    jsonSensorObject.addProperty("identifier", sensor.getIdentifier());
+    jsonSensorObject.addProperty("name", sensor.getName());
+    return jsonSensorObject;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistryDeserializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistryDeserializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0a3a30524ae4d6c3b78d584c5eb574644fcbb08
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistryDeserializer.java
@@ -0,0 +1,120 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.lang.reflect.Type;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.ImmutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableAggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
+
+/**
+ * {@link JsonDeserializer} for {@link AggregatedSensor}s.
+ */
+public final class SensorRegistryDeserializer implements JsonDeserializer<SensorRegistry> {
+
+  private static final String IDENTIFIER_KEY = "identifier";
+
+  private static final String NAME_KEY = "name";
+
+  private static final String CHILDREN_KEY = "children";
+
+  @Override
+  public SensorRegistry deserialize(final JsonElement jsonElement, final Type type,
+      final JsonDeserializationContext context) {
+    final MutableSensorRegistry sensorRegistry = this.transformTopLevelSensor(jsonElement);
+
+    return ImmutableSensorRegistry.copyOf(sensorRegistry);
+  }
+
+  private MutableSensorRegistry transformTopLevelSensor(final JsonElement jsonElement) {
+    final SensorParseResult parseResult = this.parseSensor(jsonElement); //
+    if (parseResult == null) {
+      // create empty registry
+      return new MutableSensorRegistry("", "");
+    } else {
+      // create registry from result
+      final MutableSensorRegistry sensorRegistry =
+          new MutableSensorRegistry(parseResult.identifier, parseResult.name);
+      if (parseResult.children != null) {
+        for (final JsonElement childJsonElement : parseResult.children) {
+          this.addSensor(childJsonElement, sensorRegistry.getTopLevelSensor());
+        }
+      }
+      return sensorRegistry;
+    }
+  }
+
+  private void addSensor(final JsonElement jsonElement,
+      final MutableAggregatedSensor parentSensor) {
+    final SensorParseResult parseResult = this.parseSensor(jsonElement);
+    if (parseResult != null) {
+      // create child sensor from result
+      if (parseResult.children == null) {
+        // create MachineSensor
+        parentSensor.addChildMachineSensor(parseResult.identifier, parseResult.name);
+      } else {
+        // create Aggregated Sensor
+        final MutableAggregatedSensor sensor =
+            parentSensor.addChildAggregatedSensor(parseResult.identifier, parseResult.name);
+        for (final JsonElement childJsonElement : parseResult.children) {
+          this.addSensor(childJsonElement, sensor);
+        }
+      }
+    }
+  }
+
+  // returns null if invalid JsonElement
+  private SensorParseResult parseSensor(final JsonElement jsonElement) {
+    if (jsonElement.isJsonObject()) {
+      final JsonObject jsonObject = jsonElement.getAsJsonObject();
+      if (jsonObject.has(IDENTIFIER_KEY)) {
+        final JsonElement identifierJsonElement = jsonObject.get(IDENTIFIER_KEY);
+        final JsonElement nameJsonElement = jsonObject.get(NAME_KEY);
+        if (identifierJsonElement.isJsonPrimitive() && nameJsonElement.isJsonPrimitive()) {
+          final JsonPrimitive identifierJsonPrimitive = identifierJsonElement.getAsJsonPrimitive();
+          final JsonPrimitive nameJsonPrimitive = nameJsonElement.getAsJsonPrimitive();
+          if (identifierJsonPrimitive.isString()) {
+            final String identifierString = identifierJsonPrimitive.getAsString();
+            final String nameString = nameJsonPrimitive.getAsString();
+            final JsonArray childrenJsonArray = this.parseChildren(jsonObject);
+            return new SensorParseResult(identifierString, nameString, childrenJsonArray);
+          }
+        }
+      }
+    }
+    return null;
+    // TODO throw exception
+  }
+
+  // returns null if JsonObject does not have children or children is not an array
+  private JsonArray parseChildren(final JsonObject parentJsonObject) {
+    if (parentJsonObject.has(CHILDREN_KEY)) {
+      final JsonElement childrenJsonElement = parentJsonObject.get(CHILDREN_KEY);
+      if (childrenJsonElement.isJsonArray()) {
+        return childrenJsonElement.getAsJsonArray();
+      }
+    }
+    return null;
+    // TODO throw exception
+  }
+
+  private static class SensorParseResult {
+    private final String identifier;
+    private final String name;
+    private final JsonArray children;
+
+    private SensorParseResult(final String identifier, final String name,
+        final JsonArray children) {
+      this.identifier = identifier;
+      this.children = children;
+      this.name = name;
+    }
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistrySerializer.java b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistrySerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a3581164a3e17c7e681b4c78f3d71a5a398ee92
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/main/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistrySerializer.java
@@ -0,0 +1,20 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
+
+/**
+ * {@link JsonSerializer} for {@link SensorRegistry}s.
+ */
+public final class SensorRegistrySerializer implements JsonSerializer<SensorRegistry> {
+
+  @Override
+  public JsonElement serialize(final SensorRegistry sensorRegistry, final Type type,
+      final JsonSerializationContext context) {
+    return context.serialize(sensorRegistry.getTopLevelSensor());
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/common/configuration/NameResolvingEnvironmentConfigurationTest.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/common/configuration/NameResolvingEnvironmentConfigurationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7bc8d0f66b1aea0b367756bd383af6d6ea6c0f9
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/common/configuration/NameResolvingEnvironmentConfigurationTest.java
@@ -0,0 +1,88 @@
+package rocks.theodolite.benchmarks.commons.common.configuration;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import org.apache.commons.configuration2.Configuration;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.EnvironmentVariables;
+import rocks.theodolite.benchmarks.commons.commons.configuration.NameResolvingEnvironmentConfiguration;
+
+public class NameResolvingEnvironmentConfigurationTest {
+
+  private static final String PROPERTY_FILES_KEY = "my.env.var";
+  private static final String ENV_VAR_KEY = "MY_ENV_VAR";
+  private static final String STRING_VALUE = "value";
+  private static final String STRING_VALUE_2 = "value2";
+  private static final int INT_VALUE = 7;
+
+  @Rule
+  public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
+
+  @Test
+  public void testHelperLibrary() {
+    this.environmentVariables.clear("name");
+    this.environmentVariables.set("name", STRING_VALUE);
+    assertEquals("value", System.getenv("name"));
+  }
+
+  @Test
+  public void testGetUsingEnvVarFormat() {
+    this.environmentVariables.clear(ENV_VAR_KEY);
+    this.environmentVariables.set(ENV_VAR_KEY, STRING_VALUE);
+    final Configuration config = new NameResolvingEnvironmentConfiguration();
+    final String result = config.getString(ENV_VAR_KEY);
+    assertEquals(STRING_VALUE, result);
+  }
+
+  @Test
+  public void testGetUsingPropertiesFormat() {
+    this.environmentVariables.clear(ENV_VAR_KEY);
+    this.environmentVariables.set(ENV_VAR_KEY, STRING_VALUE);
+    final Configuration config = new NameResolvingEnvironmentConfiguration();
+    final String result = config.getString(PROPERTY_FILES_KEY);
+    assertEquals(STRING_VALUE, result);
+  }
+
+  @Test
+  public void testGetOfNumber() {
+    this.environmentVariables.clear(ENV_VAR_KEY);
+    this.environmentVariables.set(ENV_VAR_KEY, String.valueOf(INT_VALUE));
+    final Configuration config = new NameResolvingEnvironmentConfiguration();
+    final int result = config.getInt(PROPERTY_FILES_KEY);
+    assertEquals(INT_VALUE, result);
+  }
+
+  @Test
+  public void testGetOfBothExisting() {
+    this.environmentVariables.clear(ENV_VAR_KEY, PROPERTY_FILES_KEY);
+    this.environmentVariables.set(ENV_VAR_KEY, STRING_VALUE);
+    this.environmentVariables.set(PROPERTY_FILES_KEY, STRING_VALUE_2);
+    final Configuration config = new NameResolvingEnvironmentConfiguration();
+    final String result = config.getString(PROPERTY_FILES_KEY);
+    assertEquals(STRING_VALUE_2, result);
+  }
+
+  @Test
+  public void testGetNonExistingUsingEnvVarFormat() {
+    this.environmentVariables.clear(ENV_VAR_KEY);
+    final Configuration config = new NameResolvingEnvironmentConfiguration();
+    final String result = config.getString(ENV_VAR_KEY);
+    assertNull(result);
+  }
+
+  @Test
+  public void testGetNonExistingUsingPropertiesFormat() {
+    this.environmentVariables.clear(ENV_VAR_KEY);
+    final Configuration config = new NameResolvingEnvironmentConfiguration();
+    final String result = config.getString(PROPERTY_FILES_KEY);
+    assertNull(result);
+  }
+
+  @Test
+  public void testFormatKeyAsEnvVariable() {
+    assertEquals(ENV_VAR_KEY,
+        NameResolvingEnvironmentConfiguration.formatKeyAsEnvVariable(PROPERTY_FILES_KEY));
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ExampleSensors.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ExampleSensors.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d1b4d65a46202561de0aee701895d57cba4ee12
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ExampleSensors.java
@@ -0,0 +1,36 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public final class ExampleSensors {
+
+  private static final SensorRegistry REGISTRY;
+
+  static {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    final MutableAggregatedSensor comcent = topLevel.addChildAggregatedSensor("comcent");
+    final MutableAggregatedSensor server1 = comcent.addChildAggregatedSensor("comcent.server1");
+    final MachineSensor server1pw1 = server1.addChildMachineSensor("comcent.server1.pw1");
+    final MachineSensor server1pw2 = server1.addChildMachineSensor("comcent.server1.pw2");
+    final MachineSensor server1pw3 = server1.addChildMachineSensor("comcent.server1.pw3");
+    final MutableAggregatedSensor server2 = comcent.addChildAggregatedSensor("comcent.server2");
+    final MachineSensor server2pw1 = server2.addChildMachineSensor("comcent.server2.pw1");
+    final MachineSensor server2pw2 = server2.addChildMachineSensor("comcent.server2.pw2");
+
+    REGISTRY = ImmutableSensorRegistry.copyOf(sensorRegistry);
+  }
+
+  private ExampleSensors() {}
+
+  public static List<String> machineSensorNames() {
+    return REGISTRY.getMachineSensors().stream().map(s -> s.getIdentifier())
+        .collect(Collectors.toList());
+  }
+
+  public static SensorRegistry registry() {
+    return REGISTRY;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ImmutableSensorRegistryTest.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ImmutableSensorRegistryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2be6ce4d5920f6c2640e0701a4f6afbc0cfa544f
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/ImmutableSensorRegistryTest.java
@@ -0,0 +1,106 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class ImmutableSensorRegistryTest {
+
+  @Test
+  public void testEquals() {
+    final ImmutableSensorRegistry sensorRegistry1 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    final ImmutableSensorRegistry sensorRegistry2 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.equals(sensorRegistry2));
+    assertTrue(sensorRegistry2.equals(sensorRegistry1));
+  }
+
+  @Test
+  public void testEqualsWithDifferentNames() {
+    final ImmutableSensorRegistry sensorRegistry1 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    final ImmutableSensorRegistry sensorRegistry2 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistryWithDifferentNames());
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.equals(sensorRegistry2));
+    assertTrue(sensorRegistry2.equals(sensorRegistry1));
+  }
+
+  @Test
+  public void testNotEquals() {
+    final ImmutableSensorRegistry sensorRegistry1 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    final ImmutableSensorRegistry sensorRegistry2 =
+        ImmutableSensorRegistry.copyOf(this.getOtherSensorRegistry());
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertFalse(sensorRegistry1.equals(sensorRegistry2));
+    assertFalse(sensorRegistry2.equals(sensorRegistry1));
+  }
+
+  @Test
+  public void testEqualHashCodes() {
+    final ImmutableSensorRegistry sensorRegistry1 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    final ImmutableSensorRegistry sensorRegistry2 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.hashCode() == sensorRegistry2.hashCode());
+  }
+
+  @Test
+  public void testEqualHashCodesWithDifferentNames() {
+    final ImmutableSensorRegistry sensorRegistry1 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    final ImmutableSensorRegistry sensorRegistry2 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistryWithDifferentNames());
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.hashCode() == sensorRegistry2.hashCode());
+  }
+
+  @Test
+  public void testNotEqualHashCodes() {
+    final ImmutableSensorRegistry sensorRegistry1 =
+        ImmutableSensorRegistry.copyOf(this.getSensorRegistry());
+    final ImmutableSensorRegistry sensorRegistry2 =
+        ImmutableSensorRegistry.copyOf(this.getOtherSensorRegistry());
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertFalse(sensorRegistry1.hashCode() == sensorRegistry2.hashCode());
+  }
+
+  private MutableSensorRegistry getSensorRegistry() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1");
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-2", "Child 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-1", "Grandchild 1");
+    aggregatedSensor.addChildMachineSensor("grandchild-2", "Grandchild 2");
+    return sensorRegistry;
+  }
+
+  private MutableSensorRegistry getSensorRegistryWithDifferentNames() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1 Alternative");
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-2", "Child 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-1", "Grandchild 1");
+    aggregatedSensor.addChildMachineSensor("grandchild-2", "Grandchild 2 Alternative");
+    return sensorRegistry;
+  }
+
+  private MutableSensorRegistry getOtherSensorRegistry() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1");
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-2", "Child 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-1", "Grandchild 1");
+    aggregatedSensor.addChildMachineSensor("grandchild-2", "Grandchild 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-3", "Grandchild 3");
+    return sensorRegistry;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MaschineSensorImplExposer.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MaschineSensorImplExposer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f397d8ad7c2676e7f98be8d0fdb1743347509960
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MaschineSensorImplExposer.java
@@ -0,0 +1,13 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+/**
+ * Helper class to allow tests in other packages access {@link MachineSensorImpl} class objects.
+ */
+public final class MaschineSensorImplExposer {
+
+  public static final Class<? extends MachineSensor> MACHINE_SENSOR_IMPL_CLASS =
+      MachineSensorImpl.class;
+
+  private MaschineSensorImplExposer() {}
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableSensorRegistryTest.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableSensorRegistryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d49c65c69209c574de35ac4509cf32c04c89459
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/MutableSensorRegistryTest.java
@@ -0,0 +1,102 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import java.util.Optional;
+import org.junit.Test;
+
+public class MutableSensorRegistryTest {
+
+  @Test
+  public void parentOfTopLevelShouldBeNotPresent() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root");
+    final Optional<AggregatedSensor> parent = sensorRegistry.getTopLevelSensor().getParent();
+    assertFalse(parent.isPresent());
+  }
+
+  @Test
+  public void testEquals() {
+    final MutableSensorRegistry sensorRegistry1 = this.getSensorRegistry();
+    final MutableSensorRegistry sensorRegistry2 = this.getSensorRegistry();
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.equals(sensorRegistry2));
+    assertTrue(sensorRegistry2.equals(sensorRegistry1));
+  }
+
+  @Test
+  public void testEqualsWithDifferentNames() {
+    final MutableSensorRegistry sensorRegistry1 = this.getSensorRegistry();
+    final MutableSensorRegistry sensorRegistry2 = this.getSensorRegistryWithDifferentNames();
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.equals(sensorRegistry2));
+    assertTrue(sensorRegistry2.equals(sensorRegistry1));
+  }
+
+  @Test
+  public void testNotEquals() {
+    final MutableSensorRegistry sensorRegistry1 = this.getSensorRegistry();
+    final MutableSensorRegistry sensorRegistry2 = this.getOtherSensorRegistry();
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertFalse(sensorRegistry1.equals(sensorRegistry2));
+    assertFalse(sensorRegistry2.equals(sensorRegistry1));
+  }
+
+  @Test
+  public void testEqualHashCodes() {
+    final MutableSensorRegistry sensorRegistry1 = this.getSensorRegistry();
+    final MutableSensorRegistry sensorRegistry2 = this.getSensorRegistry();
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.hashCode() == sensorRegistry2.hashCode());
+  }
+
+  @Test
+  public void testEqualHashCodesWithDifferentNames() {
+    final MutableSensorRegistry sensorRegistry1 = this.getSensorRegistry();
+    final MutableSensorRegistry sensorRegistry2 = this.getSensorRegistryWithDifferentNames();
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertTrue(sensorRegistry1.hashCode() == sensorRegistry2.hashCode());
+  }
+
+  @Test
+  public void testNotEqualHashCodes() {
+    final MutableSensorRegistry sensorRegistry1 = this.getSensorRegistry();
+    final MutableSensorRegistry sensorRegistry2 = this.getOtherSensorRegistry();
+    assertFalse(sensorRegistry1 == sensorRegistry2);
+    assertFalse(sensorRegistry1.hashCode() == sensorRegistry2.hashCode());
+  }
+
+  private MutableSensorRegistry getSensorRegistry() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1");
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-2", "Child 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-1", "Grandchild 1");
+    aggregatedSensor.addChildMachineSensor("grandchild-2", "Grandchild 2");
+    return sensorRegistry;
+  }
+
+  private MutableSensorRegistry getSensorRegistryWithDifferentNames() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1 Alternative");
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-2", "Child 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-1", "Grandchild 1");
+    aggregatedSensor.addChildMachineSensor("grandchild-2", "Grandchild 2 Alternative");
+    return sensorRegistry;
+  }
+
+  private MutableSensorRegistry getOtherSensorRegistry() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1");
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-2", "Child 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-1", "Grandchild 1");
+    aggregatedSensor.addChildMachineSensor("grandchild-2", "Grandchild 2");
+    aggregatedSensor.addChildMachineSensor("grandchild-3", "Grandchild 3");
+    return sensorRegistry;
+  }
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistryDeserializerTest.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistryDeserializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9821eb90a916e42fdff8750d5c0d7c3cfd265a8
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistryDeserializerTest.java
@@ -0,0 +1,174 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MachineSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.Sensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.SensorRegistryDeserializer;
+
+public class SensorRegistryDeserializerTest {
+
+	private Gson gson;
+
+	@Before
+	public void setUp() throws Exception {
+		this.gson = new GsonBuilder().registerTypeAdapter(SensorRegistry.class, new SensorRegistryDeserializer()).create();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		this.gson = null;
+	}
+
+	@Test
+	public void testEmptyRegistry() {
+		final String json = "";
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		assertNull(registry);
+	}
+
+	@Test
+	public void testRegistryOfWrongType() {
+		final String json = "[{\"identifier\": \"my-id\", \"name\": \"My Name\"}]";
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		assertEquals(registry.getTopLevelSensor().getIdentifier(), "");
+		assertTrue(registry.getTopLevelSensor().getChildren().isEmpty());
+	}
+
+	@Test
+	public void testRegistryWithMissingIdentifier() {
+		final String json = "{\"children\": []}";
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		assertEquals(registry.getTopLevelSensor().getIdentifier(), "");
+		assertTrue(registry.getTopLevelSensor().getChildren().isEmpty());
+	}
+
+	@Test
+	public void testRegistryWithMissingChildren() {
+		final String json = "{\"identifier\": \"my-root-id\", \"name\": \"My Name\"}";
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		assertEquals(registry.getTopLevelSensor().getIdentifier(), "my-root-id");
+		assertTrue(registry.getTopLevelSensor().getChildren().isEmpty());
+	}
+
+	@Test
+	public void testRegistryWithZeroChildren() {
+		final String json = "{\"identifier\": \"my-root-id\", \"name\": \"My Name\", \"children\": []}";
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		assertEquals(registry.getTopLevelSensor().getIdentifier(), "my-root-id");
+		assertTrue(registry.getTopLevelSensor().getChildren().isEmpty());
+	}
+
+	@Test
+	public void testRegistryWithOneGenerationChildren() {
+		final String json = "{\"identifier\": \"my-root-id\", \"name\": \"My Name\", \"children\": [{\"identifier\": \"child-id-1\", \"name\": \"Child 1\"}, {\"identifier\": \"child-id-2\", \"name\": \"Child 2\"}, {\"identifier\": \"child-id-3\", \"name\": \"Child 3\"}]}";
+		final List<String> childIdentifiers = ImmutableList.of("child-id-1", "child-id-2", "child-id-3"); // List.of() in Java <= 9
+
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		final AggregatedSensor topLevelSensor = registry.getTopLevelSensor();
+		assertEquals(topLevelSensor.getIdentifier(), "my-root-id");
+		final List<Sensor> childSensors = Lists.newArrayList(topLevelSensor.getChildren());
+		assertEquals(childSensors.size(), 3);
+		for (final Sensor sensor : childSensors) {
+			assertTrue(childIdentifiers.contains(sensor.getIdentifier()));
+			assertTrue(sensor instanceof MachineSensor);
+		}
+		for (final String childIdentifier : childIdentifiers) {
+			assertTrue(registry.getSensorForIdentifier(childIdentifier).isPresent());
+		}
+	}
+
+	@Test
+	public void testRegistryWithCorruptedChild() {
+		final String json = "{\"identifier\": \"my-root-id\", \"name\": \"My Name\", \"children\": [{\"identifier\": \"child-id-1\", \"name\": \"Child 1\"}, {\"no-identifier\": \"child-id-2\", \"name\": \"Child 2\"}]}";
+		final List<String> childIdentifiers = ImmutableList.of("child-id-1"); // List.of() in Java <= 9
+
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		final AggregatedSensor topLevelSensor = registry.getTopLevelSensor();
+		assertEquals(topLevelSensor.getIdentifier(), "my-root-id");
+		final List<Sensor> childSensors = Lists.newArrayList(topLevelSensor.getChildren());
+		assertEquals(childSensors.size(), 1);
+		for (final Sensor sensor : childSensors) {
+			assertTrue(childIdentifiers.contains(sensor.getIdentifier()));
+			assertTrue(sensor instanceof MachineSensor);
+		}
+		for (final String childIdentifier : childIdentifiers) {
+			assertTrue(registry.getSensorForIdentifier(childIdentifier).isPresent());
+		}
+	}
+
+	@Test
+	public void testRegistryWithArrayAsChild() {
+		final String json = "{\"identifier\": \"my-root-id\", \"name\": \"My Name\", \"children\": [{\"identifier\": \"child-id-1\", \"name\": \"Child 1\"}, [{\"identifier\": \"child-id-2\", \"name\": \"Child 2\"}]]}";
+		final List<String> childIdentifiers = ImmutableList.of("child-id-1"); // List.of() in Java <= 9
+
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		final AggregatedSensor topLevelSensor = registry.getTopLevelSensor();
+		assertEquals(topLevelSensor.getIdentifier(), "my-root-id");
+		final List<Sensor> childSensors = Lists.newArrayList(topLevelSensor.getChildren());
+		assertEquals(childSensors.size(), 1);
+		for (final Sensor sensor : childSensors) {
+			assertTrue(childIdentifiers.contains(sensor.getIdentifier()));
+			assertTrue(sensor instanceof MachineSensor);
+		}
+		for (final String childIdentifier : childIdentifiers) {
+			assertTrue(registry.getSensorForIdentifier(childIdentifier).isPresent());
+		}
+	}
+
+	@Test
+	public void testRegistryWithTwoGenerationChildren() {
+		final String json = "{\"identifier\": \"my-root-id\", \"name\": \"My Name\", \"children\": [{\"identifier\": \"child-id-1\", \"name\": \"Child 1\", \"children\": [{\"identifier\": \"child-id-1-1\", \"name\": \"Child 1a\"}, {\"identifier\": \"child-id-1-2\", \"name\": \"Child 1b\"}, {\"identifier\": \"child-id-1-3\", \"name\": \"Child 1c\"}]}, {\"identifier\": \"child-id-2\", \"name\": \"Child 2\"}]}";
+		final List<String> childIdentifiers = ImmutableList.of("child-id-1", "child-id-2"); // List.of() in Java <= 9
+		final List<String> grandChildIdentifiers = ImmutableList.of("child-id-1-1", "child-id-1-2", "child-id-1-3"); // List.of() in Java <= 9
+		final List<String> machineSensorIdentifiers = ImmutableList.of("child-id-2", "child-id-1-1", "child-id-1-2", // List.of() in Java <= 9
+				"child-id-1-3");
+
+		final SensorRegistry registry = this.gson.fromJson(json, SensorRegistry.class);
+		final AggregatedSensor topLevelSensor = registry.getTopLevelSensor();
+		assertEquals(topLevelSensor.getIdentifier(), "my-root-id");
+		final List<Sensor> childSensors = Lists.newArrayList(topLevelSensor.getChildren());
+		assertEquals(childSensors.size(), 2);
+		for (final Sensor sensor : childSensors) {
+			assertTrue(childIdentifiers.contains(sensor.getIdentifier()));
+			if (sensor.getIdentifier().equals("child-id-2")) {
+				assertTrue(sensor instanceof MachineSensor);
+			} else if (sensor.getIdentifier().equals("child-id-1")) {
+				assertTrue(sensor instanceof AggregatedSensor);
+				if (sensor instanceof AggregatedSensor) {
+					final AggregatedSensor aggregatedSensor = (AggregatedSensor) sensor;
+					final List<Sensor> grandChildSensors = Lists.newArrayList(aggregatedSensor.getChildren());
+					assertEquals(grandChildSensors.size(), 3);
+					for (final Sensor grandChildSensor : grandChildSensors) {
+						assertTrue(grandChildIdentifiers.contains(grandChildSensor.getIdentifier()));
+						assertTrue(grandChildSensor instanceof MachineSensor);
+					}
+				} else {
+					fail(); // Should never happen because of asserTrue check before
+				}
+			} else {
+				fail("Sensor is neither of type MachineSensor nor AggregatedSensor");
+			}
+		}
+		for (final String identifier : machineSensorIdentifiers) {
+			assertTrue(registry.getSensorForIdentifier(identifier).isPresent());
+		}
+	}
+
+}
diff --git a/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistrySerializerTest.java b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistrySerializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2413b571c3445df71480f76cb2b0cf251ad6009
--- /dev/null
+++ b/theodolite-benchmarks/commons/src/test/java/rocks/theodolite/benchmarks/commons/model/sensorregistry/serialization/SensorRegistrySerializerTest.java
@@ -0,0 +1,74 @@
+package rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization;
+
+import static org.junit.Assert.assertEquals;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MaschineSensorImplExposer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableAggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.AggregatedSensorSerializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.MachineSensorSerializer;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.serialization.SensorRegistrySerializer;
+
+public class SensorRegistrySerializerTest {
+
+  private Gson gson;
+
+  @Before
+  public void setUp() throws Exception {
+    this.gson = new GsonBuilder()
+        .registerTypeAdapter(MutableSensorRegistry.class, new SensorRegistrySerializer())
+        .registerTypeAdapter(MutableAggregatedSensor.class, new AggregatedSensorSerializer())
+        .registerTypeAdapter(MaschineSensorImplExposer.MACHINE_SENSOR_IMPL_CLASS,
+            new MachineSensorSerializer())
+        .create();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    this.gson = null;
+  }
+
+  @Test
+  public void testEmptySensorRegistry() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+
+    final String json = this.gson.toJson(sensorRegistry);
+    System.out.println(json);
+    assertEquals(json, "{\"identifier\":\"root\",\"name\":\"Root\",\"children\":[]}");
+  }
+
+  @Test
+  public void testEmptySensorRegistryWithChildren() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    topLevel.addChildMachineSensor("child-1", "Child 1");
+    topLevel.addChildMachineSensor("child-2");
+
+    final String json = this.gson.toJson(sensorRegistry);
+    System.out.println(json);
+    assertEquals(json,
+        "{\"identifier\":\"root\",\"name\":\"Root\",\"children\":[{\"identifier\":\"child-1\",\"name\":\"Child 1\"},{\"identifier\":\"child-2\",\"name\":\"\"}]}");
+  }
+
+  @Test
+  public void testEmptySensorRegistryWithGrandChildren() {
+    final MutableSensorRegistry sensorRegistry = new MutableSensorRegistry("root", "Root");
+    final MutableAggregatedSensor topLevel = sensorRegistry.getTopLevelSensor();
+    final MutableAggregatedSensor aggregatedSensor =
+        topLevel.addChildAggregatedSensor("child-1", "Child 1");
+    aggregatedSensor.addChildMachineSensor("child-1-1", "Child 1a");
+    aggregatedSensor.addChildMachineSensor("child-1-2", "Child 1b");
+    topLevel.addChildMachineSensor("child-2", "Child 2");
+
+    final String json = this.gson.toJson(sensorRegistry);
+    System.out.println(json);
+    assertEquals(json,
+        "{\"identifier\":\"root\",\"name\":\"Root\",\"children\":[{\"identifier\":\"child-1\",\"name\":\"Child 1\",\"children\":[{\"identifier\":\"child-1-1\",\"name\":\"Child 1a\"},{\"identifier\":\"child-1-2\",\"name\":\"Child 1b\"}]},{\"identifier\":\"child-2\",\"name\":\"Child 2\"}]}");
+  }
+
+}
diff --git a/theodolite-benchmarks/definitions/uc1-beam-flink/uc1-beam-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-beam-flink/uc1-beam-flink-benchmark-operator.yaml
index 2e110abfc13e1537792da381de2260fb3adbd606..17266b969b3abfc7a14b4578ba1855f06b830086 100644
--- a/theodolite-benchmarks/definitions/uc1-beam-flink/uc1-beam-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc1-beam-flink/uc1-beam-flink-benchmark-operator.yaml
@@ -49,6 +49,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml
index 46030c67b135c97fcefe99482bd511f0c8138a0e..d3ee8f5242c4740aedf9862dc7be091a920582d1 100644
--- a/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml
@@ -12,12 +12,12 @@ spec:
           - "beam-samza-service.yaml"
           - "service-monitor.yaml"
     afterActions:
-      - selector: # delete zookeeper nodes to reset zookeeper
-          pod:
-            matchLabels:
-              app: "zookeeper-client"
-          container: "zookeeper-client"
-        exec:
+      - exec:
+          selector: # delete zookeeper nodes to reset zookeeper
+            pod:
+              matchLabels:
+                app: "zookeeper-client"
+            container: "zookeeper-client"
           command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc1-application-1"]
           timeoutSeconds: 60
   loadGenerator:
@@ -44,6 +44,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml
index 20953c2d1e64895417f4f5339a0f3820d78735ac..ac89e714018a6d9d68d3459a3b7245475176fd6a 100644
--- a/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml
@@ -49,6 +49,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc1-hazelcastjet/uc1-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-hazelcastjet/uc1-benchmark-operator.yaml
index ca8994c40350ed55e2a6b927c370b3d11a6d4bfa..ad42faedd39e07d52ebb7655d644ea92a7b9e04a 100644
--- a/theodolite-benchmarks/definitions/uc1-hazelcastjet/uc1-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc1-hazelcastjet/uc1-benchmark-operator.yaml
@@ -34,6 +34,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml
index c340547c703c03a2e91738d4f53537938da97e0e..80352e27dee3c80ae38c558825736bbc17c97283 100644
--- a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml
@@ -36,6 +36,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc2-beam-flink/uc2-beam-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-beam-flink/uc2-beam-flink-benchmark-operator.yaml
index ffe613b401301e00cb1d368ec44609210d299df1..f172b33cec4327b7bc5193ee6fea43f5313dee8d 100644
--- a/theodolite-benchmarks/definitions/uc2-beam-flink/uc2-beam-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc2-beam-flink/uc2-beam-flink-benchmark-operator.yaml
@@ -49,6 +49,15 @@ spec:
           resource: "uc2-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml
index 46b61aaeaead664d6ed723278384c1bdf8b99ed1..619e87b608f2342324b49ecaf17aad4071570b03 100644
--- a/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml
@@ -12,12 +12,12 @@ spec:
           - "beam-samza-service.yaml"
           - "service-monitor.yaml"
     afterActions:
-      - selector: # delete zookeeper nodes to reset zookeeper
-          pod:
-            matchLabels:
-              app: "zookeeper-client"
-          container: "zookeeper-client"
-        exec:
+      - exec:
+          selector: # delete zookeeper nodes to reset zookeeper
+            pod:
+              matchLabels:
+                app: "zookeeper-client"
+            container: "zookeeper-client"
           command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc2-application-1"]
           timeoutSeconds: 60
   loadGenerator:
@@ -44,6 +44,15 @@ spec:
           resource: "uc2-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml
index 3020bb317c8b500562f1edcf2dc770f1288a8788..b45f9d4baa37ab9495adbc82f7f2cd9196d8413d 100644
--- a/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml
@@ -49,6 +49,15 @@ spec:
           resource: "uc2-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc2-hazelcastjet/uc2-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-hazelcastjet/uc2-benchmark-operator.yaml
index 436bcc790c50c86e96b3b1853b198a0f6da1aec9..0c1408df5d1bd2f5efee8d28567bfe58db32fca8 100644
--- a/theodolite-benchmarks/definitions/uc2-hazelcastjet/uc2-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc2-hazelcastjet/uc2-benchmark-operator.yaml
@@ -34,6 +34,15 @@ spec:
           resource: "uc2-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml
index b9f2b14e369b3c8e241be62c04bd480f38d847dc..3e9ffd9a20932b99a0d1903c412b417c19a710d3 100644
--- a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml
@@ -36,6 +36,15 @@ spec:
           resource: "uc2-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc3-beam-flink/uc3-beam-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-beam-flink/uc3-beam-flink-benchmark-operator.yaml
index 4449252c0de5aa81c3069b65c19325256bab57e9..af899991712bcb51abc204b84a3a48de9d687b25 100644
--- a/theodolite-benchmarks/definitions/uc3-beam-flink/uc3-beam-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc3-beam-flink/uc3-beam-flink-benchmark-operator.yaml
@@ -49,6 +49,15 @@ spec:
           resource: "uc3-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml
index 36d812d4ca1fd226c7edcd96472b5aefff26bfda..2dd5fcdf32bfc9de143a8a39c7550db912108200 100644
--- a/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml
@@ -12,12 +12,12 @@ spec:
           - "beam-samza-service.yaml"
           - "service-monitor.yaml"
     afterActions:
-      - selector: # delete zookeeper nodes to reset zookeeper
-          pod:
-            matchLabels:
-              app: "zookeeper-client"
-          container: "zookeeper-client"
-        exec:
+      - exec:
+          selector: # delete zookeeper nodes to reset zookeeper
+            pod:
+              matchLabels:
+                app: "zookeeper-client"
+            container: "zookeeper-client"
           command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc3-application-1"]
           timeoutSeconds: 60
   loadGenerator:
@@ -44,6 +44,15 @@ spec:
           resource: "uc3-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml
index 0b6e2490f3b58e5c843f2719b24378b46406c6a9..8cdc00a559cc94fe9e9bcf95dd722662880be07e 100644
--- a/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml
@@ -49,6 +49,15 @@ spec:
           resource: "uc3-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc3-hazelcastjet/uc3-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-hazelcastjet/uc3-benchmark-operator.yaml
index 3d9f755dc741458b0c8a27fe5ef450b09478b8cb..5c50ce87cee65e90dbf393ae0f7dcdf8fdf72a26 100644
--- a/theodolite-benchmarks/definitions/uc3-hazelcastjet/uc3-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc3-hazelcastjet/uc3-benchmark-operator.yaml
@@ -34,6 +34,15 @@ spec:
           resource: "uc3-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml
index 1db619303fe1bb108205654c2245b8032b723c15..e34f8707e9a461c7df4fc9361fd95763fcadf784 100644
--- a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml
@@ -36,6 +36,15 @@ spec:
           resource: "uc3-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc4-beam-flink/uc4-beam-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-beam-flink/uc4-beam-flink-benchmark-operator.yaml
index 738b1c837469a9272bf27d4df08d6e5242b1a4c2..3d6e07f4e3049a19f2fbb44ccff5f077d87d2322 100644
--- a/theodolite-benchmarks/definitions/uc4-beam-flink/uc4-beam-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc4-beam-flink/uc4-beam-flink-benchmark-operator.yaml
@@ -50,6 +50,15 @@ spec:
           properties:
             loadGenMaxRecords: "150000"
             numSensors: "4.0"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml
index 12690cec23761a38c948b0cb8757550ded54acef..8835db1d3ff6287d4c9cfb04021881deb65acb39 100644
--- a/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml
@@ -12,12 +12,12 @@ spec:
           - "beam-samza-service.yaml"
           - "service-monitor.yaml"
     afterActions:
-      - selector: # delete zookeeper nodes to reset zookeeper
-          pod:
-            matchLabels:
-              app: "zookeeper-client"
-          container: "zookeeper-client"
-        exec:
+      - exec:
+          selector: # delete zookeeper nodes to reset zookeeper
+            pod:
+              matchLabels:
+                app: "zookeeper-client"
+            container: "zookeeper-client"
           command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc4-application-1"]
           timeoutSeconds: 60
   loadGenerator:
@@ -45,6 +45,15 @@ spec:
           properties:
             loadGenMaxRecords: "150000"
             numSensors: "4.0"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml
index 28ae937e964127ded0e34d637ab307fa08db8ec3..2e4011d44d63ce6767e30f5519a41b36fd8b9bc5 100644
--- a/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml
@@ -50,6 +50,15 @@ spec:
           properties:
             loadGenMaxRecords: "150000"
             numSensors: "4.0"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc4-hazelcastjet/uc4-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-hazelcastjet/uc4-benchmark-operator.yaml
index f0151969ccb2ff34558c4a56c78f17db9fd3678e..06c22a1cf69ec4fb747fc10f27e4c08718d6a8c1 100644
--- a/theodolite-benchmarks/definitions/uc4-hazelcastjet/uc4-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc4-hazelcastjet/uc4-benchmark-operator.yaml
@@ -35,6 +35,15 @@ spec:
           properties:
             loadGenMaxRecords: "150000"
             numSensors: "4.0"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml
index 9ce6daa2dc14e8beecba1c43381defea6bba0d37..257c6814dd4ebbec727c0223161ce6649c4d4b42 100644
--- a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml
+++ b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml
@@ -37,6 +37,15 @@ spec:
           properties:
             loadGenMaxRecords: "150000"
             numSensors: "4.0"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 2000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite-benchmarks/docker-test/uc4-hazelcastjet/docker-compose.yml b/theodolite-benchmarks/docker-test/uc4-hazelcastjet/docker-compose.yml
index 9a254f5228677322ed98afcd73349cf7a50d80bc..ca6f3c85fe670e53bafd6a56e568cad9166ae501 100644
--- a/theodolite-benchmarks/docker-test/uc4-hazelcastjet/docker-compose.yml
+++ b/theodolite-benchmarks/docker-test/uc4-hazelcastjet/docker-compose.yml
@@ -38,7 +38,7 @@ services:
       SCHEMA_REGISTRY_HOST_NAME: schema-registry
       SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka:9092
   benchmark:
-    image: ghcr.io/cau-se/theodolite-uc1-hazelcastjet:${THEODOLITE_TAG:-latest}
+    image: ghcr.io/cau-se/theodolite-uc4-hazelcastjet:${THEODOLITE_TAG:-latest}
     depends_on:
       - schema-registry
       - kafka
diff --git a/theodolite-benchmarks/docker-test/uc4-hazelcastjet/test.sh b/theodolite-benchmarks/docker-test/uc4-hazelcastjet/test.sh
index d9bb6ccf241935c39df63ea5e2f0fce02476e976..a141feee36c7a58e75baf5462ee06e3bc1f4c882 100755
--- a/theodolite-benchmarks/docker-test/uc4-hazelcastjet/test.sh
+++ b/theodolite-benchmarks/docker-test/uc4-hazelcastjet/test.sh
@@ -2,7 +2,7 @@
 
 until docker-compose exec -T kcat kcat -L -b kafka:9092 -t output -J | jq -r '.topics[0].partitions | length' | grep "\b3\b"; do sleep 5s; done
 
-docker-compose exec -T kcat kcat -C -b kafka:9092 -t output -s key=s -s value=avro -r http://schema-registry:8081 -f '%k:%s\n' -c 600 |
+docker-compose exec -T kcat kcat -C -b kafka:9092 -t output -s key=s -s value=avro -r http://schema-registry:8081 -f '%k:%s\n' -c 1200 |
     tee /dev/stderr |
     awk -F ':' '!/^%/ {print $1}' |
     sort |
diff --git a/theodolite-benchmarks/http-bridge/build.gradle b/theodolite-benchmarks/http-bridge/build.gradle
index fa98d9fdd602174a945df95321f5e32b8c64052f..7714f9947b1361badb8a17d3eb6f063b1dc39aab 100644
--- a/theodolite-benchmarks/http-bridge/build.gradle
+++ b/theodolite-benchmarks/http-bridge/build.gradle
@@ -17,8 +17,7 @@ repositories {
 }
 
 dependencies {
-  implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+  implementation project(':commons')
   implementation project(':load-generator-commons')
   
   implementation 'io.javalin:javalin:4.3.0'
diff --git a/theodolite-benchmarks/http-bridge/src/main/java/rocks/theodolite/benchmarks/httpbridge/EnvVarHttpBridgeFactory.java b/theodolite-benchmarks/http-bridge/src/main/java/rocks/theodolite/benchmarks/httpbridge/EnvVarHttpBridgeFactory.java
index d3c172ac87221ab03f0171883df26802bf5a3aa9..2d49f05eea8aee1a3ed72d63868fbd6a50a92f48 100644
--- a/theodolite-benchmarks/http-bridge/src/main/java/rocks/theodolite/benchmarks/httpbridge/EnvVarHttpBridgeFactory.java
+++ b/theodolite-benchmarks/http-bridge/src/main/java/rocks/theodolite/benchmarks/httpbridge/EnvVarHttpBridgeFactory.java
@@ -3,9 +3,9 @@ package rocks.theodolite.benchmarks.httpbridge;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.loadgenerator.ConfigurationKeys;
 import rocks.theodolite.benchmarks.loadgenerator.TitanKafkaSenderFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 class EnvVarHttpBridgeFactory {
 
diff --git a/theodolite-benchmarks/kstreams-commons/build.gradle b/theodolite-benchmarks/kstreams-commons/build.gradle
index 167a75327b251af20b1142fe42c82b3bbedfe62b..e443e3af19d8b51e230d6f57a865aef9a4d90e30 100644
--- a/theodolite-benchmarks/kstreams-commons/build.gradle
+++ b/theodolite-benchmarks/kstreams-commons/build.gradle
@@ -14,9 +14,8 @@ repositories {
 
 dependencies {
   // These dependencies are used internally, and not exposed to consumers on their own compile classpath.
+  implementation project(':commons')
   // implementation 'org.slf4j:slf4j-simple:1.7.25'
-  implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
   implementation 'org.apache.kafka:kafka-streams:3.1.0'
 
   // Use JUnit test framework
diff --git a/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/GenericSerde.java b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/GenericSerde.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fa269385e522d42f9c3af3a6f4102468380bc35
--- /dev/null
+++ b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/GenericSerde.java
@@ -0,0 +1,64 @@
+package rocks.theodolite.benchmarks.commons.kstreams;
+
+import java.util.Map;
+import java.util.function.Function;
+import org.apache.kafka.common.serialization.Deserializer;
+import org.apache.kafka.common.serialization.Serde;
+import org.apache.kafka.common.serialization.Serializer;
+
+/**
+ * Factory methods to create generic {@link Serde}s.
+ */
+public final class GenericSerde {
+
+  private GenericSerde() {}
+
+  /**
+   * Create a {@link Serde} using a serialize and a deserialize function.
+   *
+   * @param serializer function to convert a record into a byte array
+   * @param deserializer function to create a record from a byte array
+   */
+  public static <T> Serde<T> from(final Function<T, byte[]> serializer,
+      final Function<byte[], T> deserializer) {
+    return org.apache.kafka.common.serialization.Serdes.serdeFrom(new Serializer<T>() {
+
+      @Override
+      public void configure(final Map<String, ?> configs, final boolean isKey) {
+        // Do nothing
+      }
+
+      @Override
+      public byte[] serialize(final String topic, final T data) {
+        return serializer.apply(data);
+      }
+
+      @Override
+      public void close() {
+        // Do nothing
+      }
+    }, new Deserializer<T>() {
+
+      @Override
+      public void configure(final Map<String, ?> configs, final boolean isKey) {
+        // Do nothing
+      }
+
+      @Override
+      public T deserialize(final String topic, final byte[] data) {
+        if (data == null) {
+          return null;
+        }
+        return deserializer.apply(data);
+      }
+
+      @Override
+      public void close() {
+        // Do nothing
+      }
+
+    });
+
+  }
+
+}
diff --git a/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/KafkaStreamsBuilder.java b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/KafkaStreamsBuilder.java
index 06e8591eebc538fcfaed2db394625d8a6dd8b033..5a2716c6ebcb2a857946908b500554d3de883174 100644
--- a/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/KafkaStreamsBuilder.java
+++ b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/KafkaStreamsBuilder.java
@@ -7,7 +7,6 @@ import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.Topology;
-import titan.ccp.common.kafka.streams.PropertiesBuilder;
 
 /**
  * Builder for the Kafka Streams configuration.
diff --git a/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/PropertiesBuilder.java b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/PropertiesBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..78dda383a25b155c7ab1de91df9ddd6f320fbecc
--- /dev/null
+++ b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/PropertiesBuilder.java
@@ -0,0 +1,50 @@
+package rocks.theodolite.benchmarks.commons.kstreams;
+
+import java.util.Properties;
+import java.util.function.Predicate;
+
+
+/**
+ * Interface for a helper class for constructing and logging Kafka Stream {@link Properties}.
+ */
+public interface PropertiesBuilder {
+
+  /**
+   * Set the provided configuration key to the provided value.
+   */
+  <T> PropertiesBuilder set(String configKey, T value);
+
+  /**
+   * Set the provided configuration key to the provided value if a given condition is evaluated to
+   * true.
+   */
+  <T> PropertiesBuilder set(String configKey, T value, Predicate<T> condition);
+
+  /**
+   * Build a {@link Properties} object with the option being set before.
+   */
+  Properties build();
+
+  /**
+   * Interface representing an Kafka Stream {@link Properties} builder without the application id
+   * yet being set.
+   */
+  interface WithoutApplicationId {
+
+    /**
+     * Continue building Kafka Stream properties by specifying an application id. From now on, all
+     * configuration properties can be set directly.
+     */
+    PropertiesBuilder applicationId(String applicationId);
+
+  }
+
+  /**
+   * Start building Kafka Stream properties by specifying a bootstrap server. Next, an application
+   * id has to be specified.
+   */
+  static PropertiesBuilder.WithoutApplicationId bootstrapServers(final String bootstrapServers) {
+    return PropertiesBuilderImpl.bootstrapServers(bootstrapServers);
+  }
+
+}
diff --git a/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/PropertiesBuilderImpl.java b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/PropertiesBuilderImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..34459b8ea3d4c7d842e38c06cf12d7f0ffb9f14c
--- /dev/null
+++ b/theodolite-benchmarks/kstreams-commons/src/main/java/rocks/theodolite/benchmarks/commons/kstreams/PropertiesBuilderImpl.java
@@ -0,0 +1,52 @@
+package rocks.theodolite.benchmarks.commons.kstreams;
+
+import java.util.Objects;
+import java.util.Properties;
+import java.util.function.Predicate;
+import org.apache.kafka.streams.StreamsConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default implementation for {@link PropertiesBuilder} and
+ * {@link PropertiesBuilder.WithoutApplicationId}.
+ */
+class PropertiesBuilderImpl implements PropertiesBuilder, PropertiesBuilder.WithoutApplicationId {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesBuilderImpl.class);
+
+  private final Properties properties = new Properties();
+
+  @Override
+  public <T> PropertiesBuilderImpl set(final String configKey, final T value) {
+    this.properties.put(configKey, value);
+    LOGGER.info("Set Kafka Streams configuration parameter '{}' to '{}'.", configKey, value);
+    return this;
+  }
+
+  @Override
+  public <T> PropertiesBuilderImpl set(final String configKey, final T value,
+      final Predicate<T> condition) {
+    if (condition.test(value)) {
+      this.set(configKey, value);
+    }
+    return this;
+  }
+
+  @Override
+  public Properties build() {
+    return this.properties;
+  }
+
+  @Override
+  public PropertiesBuilderImpl applicationId(final String applicationId) {
+    Objects.requireNonNull(applicationId, "Kafka Streams application ID cannot be null.");
+    return this.set(StreamsConfig.APPLICATION_ID_CONFIG, applicationId);
+  }
+
+  protected static PropertiesBuilderImpl bootstrapServers(final String bootsrapservers) {
+    Objects.requireNonNull(bootsrapservers, "Kafka bootstrap servers cannot be null.");
+    return new PropertiesBuilderImpl().set(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, bootsrapservers);
+  }
+
+}
diff --git a/theodolite-benchmarks/load-generator-commons/build.gradle b/theodolite-benchmarks/load-generator-commons/build.gradle
index 62542eeabc1cccb35fa9f71d1929b72956a56999..082fb8eb9f1df15fb7b054588bb9728940eb442f 100644
--- a/theodolite-benchmarks/load-generator-commons/build.gradle
+++ b/theodolite-benchmarks/load-generator-commons/build.gradle
@@ -18,8 +18,7 @@ dependencies {
   implementation 'org.slf4j:slf4j-simple:1.7.25'
   implementation 'com.google.guava:guava:30.1-jre'
   implementation 'com.google.code.gson:gson:2.8.2'
-  implementation('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  implementation('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
+  implementation project(':commons')
   implementation 'org.apache.kafka:kafka-streams:2.6.0' // TODO required?
   implementation platform('com.google.cloud:libraries-bom:24.2.0')
   implementation 'com.google.protobuf:protobuf-java-util'
diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/EnvVarLoadGeneratorFactory.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/EnvVarLoadGeneratorFactory.java
index ae9a6d4220ceaec091a0a2fb49fb82f16fdbb42e..5d5f3c0c64b4d8a0efc4f4c7c332986ea4b9560d 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/EnvVarLoadGeneratorFactory.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/EnvVarLoadGeneratorFactory.java
@@ -7,7 +7,7 @@ import java.util.Properties;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 class EnvVarLoadGeneratorFactory {
 
diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KafkaRecordSender.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KafkaRecordSender.java
index 56b1946ad78d888fe6e5140fdc373bb2cd3a4ed4..0593e850112bf20d0e02f0a6f2aa884b9ce4406e 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KafkaRecordSender.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KafkaRecordSender.java
@@ -8,7 +8,7 @@ import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.clients.producer.ProducerRecord;
 import org.apache.kafka.common.serialization.Serializer;
 import org.apache.kafka.common.serialization.StringSerializer;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
 
 /**
  * Sends records to Kafka.
diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanKafkaSenderFactory.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanKafkaSenderFactory.java
index ee7d416513439a5d0ba7bad7bcdb09e1baf5e4c7..02a46952d9f21bfda5dc7ebea24fc1c7779e77bb 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanKafkaSenderFactory.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanKafkaSenderFactory.java
@@ -1,7 +1,7 @@
 package rocks.theodolite.benchmarks.loadgenerator;
 
 import java.util.Properties;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * A factory for creating {@link KafkaRecordSender}s that sends Titan {@link ActivePowerRecord}s.
diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanPubSubSenderFactory.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanPubSubSenderFactory.java
index 569d98fb9dcd235d12a0c415fdae495eeb6abdd4..c355033343854004e0aa4dff066da6abdebd7f8b 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanPubSubSenderFactory.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanPubSubSenderFactory.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.loadgenerator;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * A factory for creating {@link PubSubRecordSender}s that sends Titan {@link ActivePowerRecord}s.
diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGenerator.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGenerator.java
index 34b17db4220e60e1fd273b1acf0a0c1543a0742b..41ee632fccb836f0264251142e01386019746674 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGenerator.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGenerator.java
@@ -1,7 +1,7 @@
 package rocks.theodolite.benchmarks.loadgenerator;
 
 import java.time.Clock;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * A factory for creating {@link RecordGenerator}s that creates Titan {@link ActivePowerRecord}s.
diff --git a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/HttpRecordSenderTest.java b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/HttpRecordSenderTest.java
index 731dda6c74fd3cd6d74771f95896c2260ce6df29..74e10711643398c7d0eb79a80a8ba3ff033cb4a7 100644
--- a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/HttpRecordSenderTest.java
+++ b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/HttpRecordSenderTest.java
@@ -14,7 +14,7 @@ import java.net.URI;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 public class HttpRecordSenderTest {
 
diff --git a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGeneratorTest.java b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGeneratorTest.java
index eb7c7f2a403dfb7138bdfd8e0855930001a4488b..7ef2ae41935120a0619f76379ee321bc83c9ba4c 100644
--- a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGeneratorTest.java
+++ b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/TitanRecordGeneratorTest.java
@@ -7,7 +7,7 @@ import java.time.ZoneId;
 import java.time.ZoneOffset;
 import org.junit.Assert;
 import org.junit.Test;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 public class TitanRecordGeneratorTest {
 
diff --git a/theodolite-benchmarks/settings.gradle b/theodolite-benchmarks/settings.gradle
index 0040989a8b3b02487c2d7328726b7caadb90f32f..1979f5f335444084b5421dcdba3228594a7b907e 100644
--- a/theodolite-benchmarks/settings.gradle
+++ b/theodolite-benchmarks/settings.gradle
@@ -1,5 +1,14 @@
+pluginManagement {
+    repositories {
+        gradlePluginPortal()
+        mavenCentral()
+    }
+}
 rootProject.name = 'theodolite-benchmarks'
 
+
+
+include 'commons'
 include 'load-generator-commons'
 include 'kstreams-commons'
 include 'flink-commons'
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/ConverterAdapter.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/ConverterAdapter.java
index 08834a47223e8b4209da79c4cdcbb6a60e027418..b32d0cb8213b57cbad7f97f97409992e90d03abd 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/ConverterAdapter.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/ConverterAdapter.java
@@ -2,8 +2,8 @@ package rocks.theodolite.benchmarks.uc1.beam;
 
 import org.apache.beam.sdk.transforms.SimpleFunction;
 import org.apache.beam.sdk.values.TypeDescriptor;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.RecordConverter;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * {@link SimpleFunction} which wraps a {@link RecordConverter} to be used with Beam.
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/GenericSink.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/GenericSink.java
index 04eae799837b2e5278842d248d135e479f84086b..e42b7dea8ce346af11e5379e258970949a9def45 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/GenericSink.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/GenericSink.java
@@ -4,8 +4,8 @@ import org.apache.beam.sdk.transforms.MapElements;
 import org.apache.beam.sdk.transforms.PTransform;
 import org.apache.beam.sdk.transforms.ParDo;
 import org.apache.beam.sdk.values.PCollection;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseAdapter;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * A {@link PTransform} for a generic {@link DatabaseAdapter}.
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/PipelineFactory.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/PipelineFactory.java
index d95d9b3343835f8348af15c3d00c34ef807d4501..74271aca04e28ab213ef396d61e12adc30517035 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/PipelineFactory.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/PipelineFactory.java
@@ -9,8 +9,8 @@ import org.apache.beam.sdk.transforms.Values;
 import org.apache.commons.configuration2.Configuration;
 import rocks.theodolite.benchmarks.commons.beam.AbstractPipelineFactory;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaActivePowerTimestampReader;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.beam.firestore.FirestoreOptionsExpander;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * {@link AbstractPipelineFactory} for UC1.
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkFactory.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkFactory.java
index d4854293b0c26804f0204e58c09a45f13dbf171f..73b95bb2257c80a1523b76c1e6b136319e6537cf 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkFactory.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkFactory.java
@@ -3,7 +3,7 @@ package rocks.theodolite.benchmarks.uc1.beam;
 import org.apache.beam.sdk.transforms.PTransform;
 import org.apache.beam.sdk.values.PCollection;
 import org.apache.commons.configuration2.Configuration;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Interface for a class that creates sinks (i.e., {@link PTransform}s that map and store
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkType.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkType.java
index da836815e09631e2ebc071badc02618171e0792a..60eaabfddbbc7738c33f1c2b563703710e3f0a0e 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkType.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/SinkType.java
@@ -4,9 +4,9 @@ import java.util.stream.Stream;
 import org.apache.beam.sdk.transforms.PTransform;
 import org.apache.beam.sdk.values.PCollection;
 import org.apache.commons.configuration2.Configuration;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.beam.firestore.FirestoreSink;
 import rocks.theodolite.benchmarks.uc1.commons.logger.LogWriterFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Supported Sink types, i.e., {@link PTransform} for converting and storing
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/DocumentMapper.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/DocumentMapper.java
index 1abf847250779150bb48b45c162afaeac1130044..6d23c929688bbbcda1586fb41a454605f48e2ef7 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/DocumentMapper.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/DocumentMapper.java
@@ -4,7 +4,7 @@ import com.google.firestore.v1.Document;
 import com.google.firestore.v1.Value;
 import java.io.IOException;
 import org.apache.beam.sdk.transforms.SimpleFunction;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 final class DocumentMapper extends SimpleFunction<ActivePowerRecord, Document> {
 
diff --git a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/FirestoreSink.java b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/FirestoreSink.java
index dfe3f240b9727d0fa5027ea5f29cd67def3323ba..100bb6205bd91d2562f9141332943610ba3b5e3e 100644
--- a/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/FirestoreSink.java
+++ b/theodolite-benchmarks/uc1-beam/src/main/java/rocks/theodolite/benchmarks/uc1/beam/firestore/FirestoreSink.java
@@ -7,7 +7,7 @@ import org.apache.beam.sdk.transforms.MapElements;
 import org.apache.beam.sdk.transforms.PTransform;
 import org.apache.beam.sdk.values.PCollection;
 import org.apache.commons.configuration2.Configuration;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * A {@link PTransform} mapping {@link ActivePowerRecord}s to {@link Document}s, followed by storing
diff --git a/theodolite-benchmarks/uc1-commons/build.gradle b/theodolite-benchmarks/uc1-commons/build.gradle
index 0f7d31d1f557ecd214b3a57227851d0f70b61084..7f742b99d8555f8be8f0ac4861ba257b1913afef 100644
--- a/theodolite-benchmarks/uc1-commons/build.gradle
+++ b/theodolite-benchmarks/uc1-commons/build.gradle
@@ -13,11 +13,7 @@ repositories {
 }
 
 dependencies {
-  // Make this implementation once this is a local subproject.
-  // Currently, Flink needs its own version of these dependencies.
-  compileOnly('org.industrial-devops:titan-ccp-common:0.1.0-SNAPSHOT') { changing = true }
-  compileOnly('org.industrial-devops:titan-ccp-common-kafka:0.1.0-SNAPSHOT') { changing = true }
-
+  implementation project(':commons')
   implementation 'com.google.code.gson:gson:2.8.9'
 
   testImplementation 'junit:junit:4.12'
diff --git a/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/DatabaseAdapter.java b/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/DatabaseAdapter.java
index a1cb1ade0dc76b168cf9ee54f64d5ac88d6b3a98..99e59a6e6fcbef8e49fe04d7ecaf9ed929e9b13e 100644
--- a/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/DatabaseAdapter.java
+++ b/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/DatabaseAdapter.java
@@ -1,7 +1,7 @@
 package rocks.theodolite.benchmarks.uc1.commons;
 
 import java.util.Objects;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * A database adapter consisting of a {@link RecordConverter} and a {@link DatabaseWriter}.
diff --git a/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/RecordConverter.java b/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/RecordConverter.java
index 105f19e0e920e3516f7277cd7804dae210a7d0b1..a728e9d6b676a273c3847b89b2091e8928aba114 100644
--- a/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/RecordConverter.java
+++ b/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/RecordConverter.java
@@ -1,6 +1,6 @@
 package rocks.theodolite.benchmarks.uc1.commons;
 
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Converts an {@link ActivePowerRecord} to the type required by a database.
diff --git a/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/logger/JsonConverter.java b/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/logger/JsonConverter.java
index f9974affb7bf57fc63e9bfe8ba92fd056da9a97b..a59f02687c1c6a0455f43e5a34c421c85e6972cd 100644
--- a/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/logger/JsonConverter.java
+++ b/theodolite-benchmarks/uc1-commons/src/main/java/rocks/theodolite/benchmarks/uc1/commons/logger/JsonConverter.java
@@ -2,8 +2,8 @@ package rocks.theodolite.benchmarks.uc1.commons.logger;
 
 import com.google.gson.Gson;
 import java.io.Serializable;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.RecordConverter;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * {@link RecordConverter} that converts {@link ActivePowerRecord}s to JSON strings.
diff --git a/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/ConverterAdapter.java b/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/ConverterAdapter.java
index 064b8afbb03dc16262ca7fcf90a0fdd8af4419a9..8380cdc09caa35814f3203bdf6dc1746875fdf9b 100644
--- a/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/ConverterAdapter.java
+++ b/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/ConverterAdapter.java
@@ -1,8 +1,8 @@
 package rocks.theodolite.benchmarks.uc1.flink;
 
 import org.apache.flink.api.common.functions.MapFunction;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.RecordConverter;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * {@link MapFunction} which wraps a {@link RecordConverter} to be used with Flink.
diff --git a/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/HistoryServiceFlinkJob.java b/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/HistoryServiceFlinkJob.java
index a5e833b0bbb7cd8a153e5fa7c51c1a548ef63083..9d3412c7f7a318b471902f9f2f38e714bf1034ec 100644
--- a/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/HistoryServiceFlinkJob.java
+++ b/theodolite-benchmarks/uc1-flink/src/main/java/rocks/theodolite/benchmarks/uc1/flink/HistoryServiceFlinkJob.java
@@ -5,9 +5,9 @@ import org.apache.flink.streaming.api.datastream.DataStream;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
 import rocks.theodolite.benchmarks.commons.flink.AbstractFlinkService;
 import rocks.theodolite.benchmarks.commons.flink.KafkaConnectorFactory;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseAdapter;
 import rocks.theodolite.benchmarks.uc1.commons.logger.LogWriterFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * The History microservice implemented as a Flink job.
@@ -24,7 +24,7 @@ public final class HistoryServiceFlinkJob extends AbstractFlinkService {
 
   @Override
   protected void configureSerializers() {
-  // No serializers needed here
+    // No serializers needed here
   }
 
 
diff --git a/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1HazelcastJetFactory.java b/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1HazelcastJetFactory.java
index 4a5c5dead14e606847dc5e2ac3c95414d9f611b3..93aaa1a7e844634bb4fdf283d5b9f41a0d6c0b7f 100644
--- a/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1HazelcastJetFactory.java
+++ b/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1HazelcastJetFactory.java
@@ -134,8 +134,8 @@ public class Uc1HazelcastJetFactory {
    * @return The Uc1HazelcastJetBuilder factory with set kafkaPropertiesForPipeline.
    */
   public Uc1HazelcastJetFactory setPropertiesFromEnv(final String bootstrapServersDefault, // NOPMD
-                                                     final String schemaRegistryUrlDefault,
-                                                     final String jobName) {
+      final String schemaRegistryUrlDefault,
+      final String jobName) {
     // Use KafkaPropertiesBuilder to build a properties object used for kafka
     final KafkaPropertiesBuilder propsBuilder = new KafkaPropertiesBuilder();
     final Properties kafkaProps =
diff --git a/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineBuilder.java b/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineBuilder.java
index c02ea1e7ea7fb3f27bdbf818248678011a93f6a2..e6107682ef3aff91d45bcd7a65675b5a6323975e 100644
--- a/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineBuilder.java
+++ b/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineBuilder.java
@@ -1,18 +1,18 @@
 package rocks.theodolite.benchmarks.uc1.hazelcastjet;
 
-import static com.hazelcast.jet.pipeline.SinkBuilder.sinkBuilder;
-
 import com.hazelcast.jet.kafka.KafkaSources;
 import com.hazelcast.jet.pipeline.Pipeline;
 import com.hazelcast.jet.pipeline.Sink;
+import com.hazelcast.jet.pipeline.SinkBuilder;
 import com.hazelcast.jet.pipeline.StreamSource;
 import com.hazelcast.jet.pipeline.StreamStage;
 import java.util.Map.Entry;
 import java.util.Properties;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseAdapter;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseWriter;
 import rocks.theodolite.benchmarks.uc1.commons.logger.LogWriterFactory;
-import titan.ccp.model.records.ActivePowerRecord;
+
 
 /**
  * Builder to build a HazelcastJet Pipeline for UC1 which can be used for stream processing using
@@ -45,7 +45,7 @@ public class Uc1PipelineBuilder {
     // Do not refactor this to just use the call
     // (There is a problem with static calls in functions in hazelcastjet)
     final DatabaseWriter<String> writer = this.databaseAdapter.getDatabaseWriter();
-    final Sink<String> sink = sinkBuilder(
+    final Sink<String> sink = SinkBuilder.sinkBuilder(
         "Sink into database", x -> writer)
         .<String>receiveFn(DatabaseWriter::write)
         .build();
diff --git a/theodolite-benchmarks/uc1-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc1/hazelcast/Uc1PipelineTest.java b/theodolite-benchmarks/uc1-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc1/hazelcast/Uc1PipelineTest.java
index 525327ddbcdcddb6cf1bfe4e2d6be62d3384fc0c..8ffde0487ab88c260655f51eac3d2701f31a7ab0 100644
--- a/theodolite-benchmarks/uc1-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc1/hazelcast/Uc1PipelineTest.java
+++ b/theodolite-benchmarks/uc1-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc1/hazelcast/Uc1PipelineTest.java
@@ -1,5 +1,7 @@
 package rocks.theodolite.benchmarks.uc1.hazelcast;
 
+import static com.hazelcast.jet.pipeline.SinkBuilder.sinkBuilder;
+import static com.hazelcast.logging.Logger.getLogger;
 import com.hazelcast.jet.Jet;
 import com.hazelcast.jet.JetInstance;
 import com.hazelcast.jet.config.JetConfig;
@@ -12,24 +14,21 @@ import com.hazelcast.jet.pipeline.test.AssertionCompletedException;
 import com.hazelcast.jet.pipeline.test.Assertions;
 import com.hazelcast.jet.pipeline.test.TestSources;
 import com.hazelcast.jet.test.SerialTest;
+import com.hazelcast.logging.ILogger;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.CompletionException;
-import com.hazelcast.logging.ILogger;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.slf4j.Logger;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseAdapter;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseWriter;
 import rocks.theodolite.benchmarks.uc1.commons.logger.LogWriterFactory;
 import rocks.theodolite.benchmarks.uc1.hazelcastjet.Uc1PipelineBuilder;
-import titan.ccp.model.records.ActivePowerRecord;
-
-import static com.hazelcast.jet.pipeline.SinkBuilder.sinkBuilder;
-import static com.hazelcast.logging.Logger.getLogger;
 
 /**
  * Test methods for the Hazelcast Jet Implementation of UC1.
@@ -44,7 +43,7 @@ public class Uc1PipelineTest extends JetTestSupport {
   // Standart Logger
   private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Uc1PipelineTest.class);
   // HazelcastJet Logger
-  private static final ILogger logger =  getLogger(Uc1PipelineTest.class);
+  private static final ILogger logger = getLogger(Uc1PipelineTest.class);
 
   private final DatabaseAdapter<String> databaseAdapter = LogWriterFactory.forJson();
 
@@ -55,7 +54,7 @@ public class Uc1PipelineTest extends JetTestSupport {
   @Before
   public void buildUc1Pipeline() {
 
-    this.logger.info("Hazelcast Logger");
+    Uc1PipelineTest.logger.info("Hazelcast Logger");
     LOGGER.info("Standard Logger");
 
 
@@ -67,9 +66,9 @@ public class Uc1PipelineTest extends JetTestSupport {
     // Create mock jet instance with configuration
     final String testClusterName = randomName();
     final JetConfig testJetConfig = new JetConfig();
-//    testJetConfig.setProperty( "hazelcast.logging.type", "slf4j" );
+    // testJetConfig.setProperty( "hazelcast.logging.type", "slf4j" );
     testJetConfig.getHazelcastConfig().setClusterName(testClusterName);
-    this.testInstance = createJetMember(testJetConfig);
+    this.testInstance = this.createJetMember(testJetConfig);
 
 
     // Create a test source
@@ -92,17 +91,17 @@ public class Uc1PipelineTest extends JetTestSupport {
     final DatabaseWriter<String> adapter = this.databaseAdapter.getDatabaseWriter();
     final Sink<String> sink = sinkBuilder(
         "database-sink", x -> adapter)
-        .<String>receiveFn(DatabaseWriter::write)
-        .build();
+            .<String>receiveFn(DatabaseWriter::write)
+            .build();
 
-//    Map Stage, can be used instead of sink
-//    StreamStage<String> log = uc1Topology.map(s -> {
-//        LOGGER.info(s);
-//        return s;
-//    });
-//    log.writeTo(sink);
+    // Map Stage, can be used instead of sink
+    // StreamStage<String> log = uc1Topology.map(s -> {
+    // LOGGER.info(s);
+    // return s;
+    // });
+    // log.writeTo(sink);
 
-    //apply sink
+    // apply sink
     this.uc1Topology.writeTo(sink);
   }
 
@@ -121,8 +120,8 @@ public class Uc1PipelineTest extends JetTestSupport {
     // Assertion
     this.uc1Topology.apply(Assertions.assertCollectedEventually(assertTimeoutSeconds,
         collection -> {
-      //print the newest Record
-//      LOGGER.info(collection.get(collection.size()-1));
+          // print the newest Record
+          // LOGGER.info(collection.get(collection.size()-1));
 
           // Run pipeline until 5th item
           Assert.assertTrue("Not enough data arrived in the end",
diff --git a/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/HistoryService.java b/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/HistoryService.java
index 0a2a1bec7c3515f903905efeb07e717a46e329ea..dd792ac8a814514338d6fb27b4f67f4b6f033105 100644
--- a/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/HistoryService.java
+++ b/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/HistoryService.java
@@ -3,7 +3,7 @@ package rocks.theodolite.benchmarks.uc1.kstreams;
 import java.util.concurrent.CompletableFuture;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.KafkaStreams;
-import titan.ccp.common.configuration.ServiceConfigurations;
+import rocks.theodolite.benchmarks.commons.commons.configuration.ServiceConfigurations;
 
 /**
  * A microservice that manages the history and, therefore, stores and aggregates incoming
diff --git a/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/TopologyBuilder.java b/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/TopologyBuilder.java
index 944e449c4693dc7c234844c97567d7f9f048cf3b..efbf774066773cd6a17d830cf07b629231fe06ef 100644
--- a/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/TopologyBuilder.java
+++ b/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/TopologyBuilder.java
@@ -5,10 +5,10 @@ import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.Topology;
 import org.apache.kafka.streams.kstream.Consumed;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc1.commons.DatabaseAdapter;
 import rocks.theodolite.benchmarks.uc1.commons.logger.LogWriterFactory;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Builds Kafka Stream Topology for the History microservice.
diff --git a/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/Uc1KafkaStreamsBuilder.java b/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/Uc1KafkaStreamsBuilder.java
index a1e9c4d78d0f340273fb3db944ba96913c8d0b13..05d6a5845a9eb79998d7c4fc1940357559d0936d 100644
--- a/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/Uc1KafkaStreamsBuilder.java
+++ b/theodolite-benchmarks/uc1-kstreams/src/main/java/rocks/theodolite/benchmarks/uc1/kstreams/Uc1KafkaStreamsBuilder.java
@@ -4,8 +4,8 @@ import java.util.Objects;
 import java.util.Properties;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.Topology;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
 import rocks.theodolite.benchmarks.commons.kstreams.KafkaStreamsBuilder;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
 
 /**
  * Builder for the Kafka Streams configuration.
diff --git a/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/PipelineFactory.java b/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/PipelineFactory.java
index 375b2a6cba5256e0644b6beaf26d41e010089250..decbcae1c4b524f9f39295ecd49275a3c1b09951 100644
--- a/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/PipelineFactory.java
+++ b/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/PipelineFactory.java
@@ -22,7 +22,7 @@ import rocks.theodolite.benchmarks.commons.beam.AbstractPipelineFactory;
 import rocks.theodolite.benchmarks.commons.beam.ConfigurationKeys;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaActivePowerTimestampReader;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaWriterTransformation;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * {@link AbstractPipelineFactory} for UC2.
diff --git a/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/StatsAggregation.java b/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/StatsAggregation.java
index a8956ee4b55c1e545e2c25ce38e2911b7c961337..cf320bf18b37f25b787c1baea1109892f2aa83fa 100644
--- a/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/StatsAggregation.java
+++ b/theodolite-benchmarks/uc2-beam/src/main/java/rocks/theodolite/benchmarks/uc2/beam/StatsAggregation.java
@@ -6,7 +6,7 @@ import java.io.Serializable;
 import org.apache.beam.sdk.coders.AvroCoder;
 import org.apache.beam.sdk.coders.DefaultCoder;
 import org.apache.beam.sdk.transforms.Combine.CombineFn;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Aggregation Class for ActivePowerRecords. Creates a StatsAccumulator based on the ValueInW.
diff --git a/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/HistoryServiceFlinkJob.java b/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/HistoryServiceFlinkJob.java
index 1109fb7bb431811dde4c448b445990599bc6d626..ea7716dbc10f61f03a6c5705c9d17e2d3a12745d 100644
--- a/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/HistoryServiceFlinkJob.java
+++ b/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/HistoryServiceFlinkJob.java
@@ -1,10 +1,13 @@
 package rocks.theodolite.benchmarks.uc2.flink;
 
 import com.google.common.math.Stats;
+import org.apache.flink.api.common.functions.AggregateFunction;
 import org.apache.flink.api.common.typeinfo.Types;
 import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
 import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
 import org.apache.flink.streaming.api.windowing.time.Time;
+import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
 import org.apache.kafka.common.serialization.Serdes;
@@ -61,7 +64,9 @@ public final class HistoryServiceFlinkJob extends AbstractFlinkService {
         // .rebalance()
         .keyBy(ActivePowerRecord::getIdentifier)
         .window(TumblingEventTimeWindows.of(windowDuration))
-        .aggregate(new StatsAggregateFunction(), new StatsProcessWindowFunction())
+        .aggregate(
+            (AggregateFunction<ActivePowerRecord, Stats, Stats>) new StatsAggregateFunction(),
+            (ProcessWindowFunction<Stats, Tuple2<String, Stats>, String, TimeWindow>) new StatsProcessWindowFunction())
         .map(t -> {
           final String key = t.f0;
           final String value = t.f1.toString();
diff --git a/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/StatsAggregateFunction.java b/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/StatsAggregateFunction.java
index b2a9e5f538c9e92ba777dbcd61caaa3199ebb383..ca5c9b2aee2285f5e8415d853fd9fe09f2d51b49 100644
--- a/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/StatsAggregateFunction.java
+++ b/theodolite-benchmarks/uc2-flink/src/main/java/rocks/theodolite/benchmarks/uc2/flink/StatsAggregateFunction.java
@@ -3,8 +3,8 @@ package rocks.theodolite.benchmarks.uc2.flink;
 import com.google.common.math.Stats;
 import com.google.common.math.StatsAccumulator;
 import org.apache.flink.api.common.functions.AggregateFunction;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc2.flink.util.StatsFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Statistical aggregation of {@link ActivePowerRecord}s using {@link Stats}.
diff --git a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/HistoryService.java b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/HistoryService.java
index f382978b714fdfdff6c190339c2ed23a2e037069..7737959bde97ce8332c87fc88b0aa9fd90bf8250 100644
--- a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/HistoryService.java
+++ b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/HistoryService.java
@@ -57,8 +57,8 @@ public class HistoryService {
    */
   private void createHazelcastJetApplication() throws Exception { // NOPMD
     new Uc2HazelcastJetFactory()
-        .setReadPropertiesFromEnv(KAFKA_BOOTSTRAP_DEFAULT, SCHEMA_REGISTRY_URL_DEFAULT,JOB_NAME)
-        .setWritePropertiesFromEnv(KAFKA_BOOTSTRAP_DEFAULT,SCHEMA_REGISTRY_URL_DEFAULT)
+        .setReadPropertiesFromEnv(KAFKA_BOOTSTRAP_DEFAULT, SCHEMA_REGISTRY_URL_DEFAULT, JOB_NAME)
+        .setWritePropertiesFromEnv(KAFKA_BOOTSTRAP_DEFAULT, SCHEMA_REGISTRY_URL_DEFAULT)
         .setKafkaInputTopicFromEnv(KAFKA_INPUT_TOPIC_DEFAULT)
         .setKafkaOutputTopicFromEnv(KAFKA_OUTPUT_TOPIC_DEFAULT)
         .setDownsampleIntervalFromEnv(DOWNSAMPLE_INTERVAL_DEFAULT_MS)
diff --git a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2HazelcastJetFactory.java b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2HazelcastJetFactory.java
index 143b154f3726e75d2842766b49bd2e26f57ce39b..92029a78405deacae5e7ad352b184eb852cd842e 100644
--- a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2HazelcastJetFactory.java
+++ b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2HazelcastJetFactory.java
@@ -180,9 +180,9 @@ public class Uc2HazelcastJetFactory {
    * @return The Uc2HazelcastJetBuilder factory with set kafkaReadPropertiesForPipeline.
    */
   public Uc2HazelcastJetFactory setReadPropertiesFromEnv(// NOPMD
-                                                         final String bootstrapServersDefault,
-                                                         final String schemaRegistryUrlDefault,
-                                                         final String jobName) {
+      final String bootstrapServersDefault,
+      final String schemaRegistryUrlDefault,
+      final String jobName) {
     // Use KafkaPropertiesBuilder to build a properties object used for kafka
     final KafkaPropertiesBuilder propsBuilder = new KafkaPropertiesBuilder();
     final Properties kafkaReadProps =
diff --git a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineBuilder.java b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineBuilder.java
index 73377de6122d4a723c5dbbcb8198fa814c4bed1e..92e59d256c5f2d5b43644b2e498ca1f2dbca4202 100644
--- a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineBuilder.java
+++ b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineBuilder.java
@@ -14,8 +14,10 @@ import com.hazelcast.jet.pipeline.WindowDefinition;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc2.hazelcastjet.uc2specifics.StatsAccumulatorSupplier;
-import titan.ccp.model.records.ActivePowerRecord;
+
+
 
 /**
  * Builder to build a HazelcastJet Pipeline for UC2 which can be used for stream processing using
@@ -108,8 +110,7 @@ public class Uc2PipelineBuilder {
    * @return An AggregateOperation used by Hazelcast Jet in a streaming stage which aggregates
    *         ActivePowerRecord Objects into Stats Objects.
    */
-  public AggregateOperation1<Entry<String, ActivePowerRecord>,
-      StatsAccumulator, Stats> uc2AggregateOperation() {
+  public AggregateOperation1<Entry<String, ActivePowerRecord>, StatsAccumulator, Stats> uc2AggregateOperation() { // NOCS
     // Aggregate Operation to Create a Stats Object from Entry<String,ActivePowerRecord> items using
     // the Statsaccumulator.
     return AggregateOperation
@@ -129,7 +130,7 @@ public class Uc2PipelineBuilder {
         .andExportFinish(
             (accumulator) -> {
               return accumulator.snapshot();
-          });
+            });
   }
 
 }
diff --git a/theodolite-benchmarks/uc2-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineTest.java b/theodolite-benchmarks/uc2-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineTest.java
index ff72b9558f43334feb8846d50bef2c6714d9404a..0a579c8d4ad2c872f7c90b1d6456de78b3a20f91 100644
--- a/theodolite-benchmarks/uc2-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineTest.java
+++ b/theodolite-benchmarks/uc2-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineTest.java
@@ -19,7 +19,7 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Test methods for the Hazelcast Jet Implementation of UC2.
@@ -39,10 +39,10 @@ public class Uc2PipelineTest extends JetTestSupport {
   public void buildUc2Pipeline() {
 
     // Setup Configuration
-    int testItemsPerSecond = 1;
-    String testSensorName = "TEST-SENSOR";
-    Double testValueInW = 10.0;
-    int testWindowInMs = 5000;
+    final int testItemsPerSecond = 1;
+    final String testSensorName = "TEST-SENSOR";
+    final Double testValueInW = 10.0;
+    final int testWindowInMs = 5000;
 
     // Create mock jet instance with configuration
     final String testClusterName = randomName();
@@ -61,7 +61,7 @@ public class Uc2PipelineTest extends JetTestSupport {
         });
 
     // Create pipeline to test
-    Uc2PipelineBuilder pipelineBuilder = new Uc2PipelineBuilder();
+    final Uc2PipelineBuilder pipelineBuilder = new Uc2PipelineBuilder();
     this.testPipeline = Pipeline.create();
     this.uc2Topology =
         pipelineBuilder.extendUc2Topology(this.testPipeline, testSource, testWindowInMs);
@@ -75,14 +75,15 @@ public class Uc2PipelineTest extends JetTestSupport {
   public void testOutput() {
 
     // Assertion Configuration
-    int timeout = 14;
-    String expectedOutput = "Stats{count=5, mean=10.0, populationStandardDeviation=0.0, min=10.0, max=10.0}";
+    final int timeout = 14;
+    final String expectedOutput =
+        "Stats{count=5, mean=10.0, populationStandardDeviation=0.0, min=10.0, max=10.0}";
 
     // Assertion
     this.uc2Topology.apply(Assertions.assertCollectedEventually(timeout,
         collection -> Assert.assertTrue(
             "Not the right amount items in Stats Object!",
-            collection.get(collection.size()-1).getValue().equals(expectedOutput))));
+            collection.get(collection.size() - 1).getValue().equals(expectedOutput))));
 
     // Run the test!
     try {
diff --git a/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/HistoryService.java b/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/HistoryService.java
index 3b87053507a7739381482719acf317903fe2d361..4afc2d91eaaf98226f262f072cfd7e5aed6f847e 100644
--- a/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/HistoryService.java
+++ b/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/HistoryService.java
@@ -5,8 +5,8 @@ import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.KafkaStreams;
+import rocks.theodolite.benchmarks.commons.commons.configuration.ServiceConfigurations;
 import rocks.theodolite.benchmarks.commons.kstreams.ConfigurationKeys;
-import titan.ccp.common.configuration.ServiceConfigurations;
 
 /**
  * A microservice that manages the history and, therefore, stores and aggregates incoming
diff --git a/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/TopologyBuilder.java b/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/TopologyBuilder.java
index ae17c83bc141ef6056d7f9f89738d1442ba4afed..cd1d8cd92149d368a27452fa7689f5549a9c2bc7 100644
--- a/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/TopologyBuilder.java
+++ b/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/TopologyBuilder.java
@@ -13,10 +13,10 @@ import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.kstream.TimeWindows;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
+import rocks.theodolite.benchmarks.commons.kstreams.GenericSerde;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc2.kstreams.util.StatsFactory;
-import titan.ccp.common.kafka.GenericSerde;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Builds Kafka Stream Topology for the History microservice.
diff --git a/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/Uc2KafkaStreamsBuilder.java b/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/Uc2KafkaStreamsBuilder.java
index 9db55ef921e44ac6ebb8b31ca58c13862c33ddcb..d9d4a23ec512ce4f7799648a4ea4f629e7b369ad 100644
--- a/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/Uc2KafkaStreamsBuilder.java
+++ b/theodolite-benchmarks/uc2-kstreams/src/main/java/rocks/theodolite/benchmarks/uc2/kstreams/Uc2KafkaStreamsBuilder.java
@@ -5,8 +5,8 @@ import java.util.Objects;
 import java.util.Properties;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.Topology;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
 import rocks.theodolite.benchmarks.commons.kstreams.KafkaStreamsBuilder;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
 
 /**
  * Builder for the Kafka Streams configuration.
diff --git a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/HourOfDayKeySerde.java b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/HourOfDayKeySerde.java
index 1c09d7d508888b48c2a509d83f55ff49ca967f17..8bc32ccc2146f6467f6fcf374f95e8b87c2c351c 100644
--- a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/HourOfDayKeySerde.java
+++ b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/HourOfDayKeySerde.java
@@ -1,10 +1,10 @@
 package rocks.theodolite.benchmarks.uc3.beam;
 
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link BufferSerde} for a {@link HourOfDayKey}. Use the {@link #create()} method to create a new
diff --git a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/MapTimeFormat.java b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/MapTimeFormat.java
index 3c0d7acdbeccfaf03aac70df478e3db6dd1378e4..0cad038141bd7b30d765520403529e9184bbcb86 100644
--- a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/MapTimeFormat.java
+++ b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/MapTimeFormat.java
@@ -5,7 +5,7 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import org.apache.beam.sdk.transforms.SimpleFunction;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Changes the time format to us Europe/Paris time.
diff --git a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/PipelineFactory.java b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/PipelineFactory.java
index 9c766e41254555647dd7ef1eed0417613b7c1629..f6587be4c4660a2e34f34efdaa417a7080073d0e 100644
--- a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/PipelineFactory.java
+++ b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/PipelineFactory.java
@@ -23,7 +23,7 @@ import rocks.theodolite.benchmarks.commons.beam.AbstractPipelineFactory;
 import rocks.theodolite.benchmarks.commons.beam.ConfigurationKeys;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaActivePowerTimestampReader;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaWriterTransformation;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * {@link AbstractPipelineFactory} for UC3.
diff --git a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/StatsAggregation.java b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/StatsAggregation.java
index e479c0ab5e192f7e5239c100a05df454bd2973ad..4fca536baf6db33e57700263cefb837ca8eb5b8b 100644
--- a/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/StatsAggregation.java
+++ b/theodolite-benchmarks/uc3-beam/src/main/java/rocks/theodolite/benchmarks/uc3/beam/StatsAggregation.java
@@ -6,7 +6,7 @@ import java.io.Serializable;
 import org.apache.beam.sdk.coders.AvroCoder;
 import org.apache.beam.sdk.coders.DefaultCoder;
 import org.apache.beam.sdk.transforms.Combine.CombineFn;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 
 /**
diff --git a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/HistoryServiceFlinkJob.java b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/HistoryServiceFlinkJob.java
index ad38303b4f8957bcb6de23608451be2da4ae41ac..d80f64fafb69d3e0287347a8f90080584d4fcd82 100644
--- a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/HistoryServiceFlinkJob.java
+++ b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/HistoryServiceFlinkJob.java
@@ -17,11 +17,11 @@ import org.slf4j.LoggerFactory;
 import rocks.theodolite.benchmarks.commons.flink.AbstractFlinkService;
 import rocks.theodolite.benchmarks.commons.flink.KafkaConnectorFactory;
 import rocks.theodolite.benchmarks.commons.flink.serialization.StatsSerializer;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc3.flink.util.HourOfDayKey;
 import rocks.theodolite.benchmarks.uc3.flink.util.HourOfDayKeyFactory;
 import rocks.theodolite.benchmarks.uc3.flink.util.HourOfDayKeySerde;
 import rocks.theodolite.benchmarks.uc3.flink.util.StatsKeyFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * The History microservice implemented as a Flink job.
diff --git a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/StatsAggregateFunction.java b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/StatsAggregateFunction.java
index 38d277dac28e88c82a38a1b56ef15cab2c00db14..83951a4228fe0b73a4330bfae5177f508b9c1b0e 100644
--- a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/StatsAggregateFunction.java
+++ b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/StatsAggregateFunction.java
@@ -3,8 +3,8 @@ package rocks.theodolite.benchmarks.uc3.flink;
 import com.google.common.math.Stats;
 import com.google.common.math.StatsAccumulator;
 import org.apache.flink.api.common.functions.AggregateFunction;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc3.flink.util.StatsFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Statistical aggregation of {@link ActivePowerRecord}s using {@link Stats}.
diff --git a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayKeySerde.java b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayKeySerde.java
index 2c5bd40fe29f683693fb57bc679dd288e7d3bfb9..5b08fcad2ff744e3d0e14e51d35fad88d2900470 100644
--- a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayKeySerde.java
+++ b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayKeySerde.java
@@ -6,10 +6,10 @@ import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 import java.io.Serializable;
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link BufferSerde} for a {@link HourOfDayKey}. Use the {@link #create()} method to create a new
diff --git a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayRecordFactory.java b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayRecordFactory.java
index 5c52a446eac7f7ba39dfe12c247744054fd735d5..420179a0825d5b897f6927040eb57c43d27837ef 100644
--- a/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayRecordFactory.java
+++ b/theodolite-benchmarks/uc3-flink/src/main/java/rocks/theodolite/benchmarks/uc3/flink/util/HourOfDayRecordFactory.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc3.flink.util;
 
 import com.google.common.math.Stats;
 import org.apache.kafka.streams.kstream.Windowed;
-import titan.ccp.model.records.HourOfDayActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord;
 
 /**
  * {@link StatsRecordFactory} to create an {@link HourOfDayActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3HazelcastJetFactory.java b/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3HazelcastJetFactory.java
index be6d70d27b9a868914ec5d28e84b4a90454ab56c..d87aa19d316b278160dbc92b19b9be3d40a41d61 100644
--- a/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3HazelcastJetFactory.java
+++ b/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3HazelcastJetFactory.java
@@ -192,9 +192,9 @@ public class Uc3HazelcastJetFactory { // NOPMD
    * @return The Uc3HazelcastJetBuilder factory with set kafkaReadPropertiesForPipeline.
    */
   public Uc3HazelcastJetFactory setReadPropertiesFromEnv(// NOPMD
-                                                         final String bootstrapServersDefault,
-                                                         final String schemaRegistryUrlDefault,
-                                                         final String jobName) {
+      final String bootstrapServersDefault,
+      final String schemaRegistryUrlDefault,
+      final String jobName) {
     // Use KafkaPropertiesBuilder to build a properties object used for kafka
     final KafkaPropertiesBuilder propsBuilder = new KafkaPropertiesBuilder();
     final Properties kafkaReadProps =
diff --git a/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineBuilder.java b/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineBuilder.java
index c8427de60742c2923d4ec17703592f5b8310de0c..e651d44fd2d099ae41296cc08487c787501d9b46 100644
--- a/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineBuilder.java
+++ b/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineBuilder.java
@@ -15,10 +15,10 @@ import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc3.hazelcastjet.uc3specifics.HourOfDayKey;
 import rocks.theodolite.benchmarks.uc3.hazelcastjet.uc3specifics.HoursOfDayKeyFactory;
 import rocks.theodolite.benchmarks.uc3.hazelcastjet.uc3specifics.StatsKeyFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Builder to build a HazelcastJet Pipeline for UC3 which can be used for stream processing using
diff --git a/theodolite-benchmarks/uc3-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineTest.java b/theodolite-benchmarks/uc3-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineTest.java
index 3df4f4642f1bc6c8637f90bcae3f352f5c298e51..969ff27d1154a0bd52cb3a048eca2f12ca901138 100644
--- a/theodolite-benchmarks/uc3-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineTest.java
+++ b/theodolite-benchmarks/uc3-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineTest.java
@@ -14,20 +14,18 @@ import com.hazelcast.jet.pipeline.test.TestSources;
 import com.hazelcast.jet.test.SerialTest;
 import java.time.Instant;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
 import java.util.Map;
-import java.util.TimeZone;
 import java.util.Map.Entry;
+import java.util.TimeZone;
 import java.util.concurrent.CompletionException;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import rocks.theodolite.benchmarks.uc3.hazelcastjet.Uc3PipelineBuilder;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc3.hazelcastjet.uc3specifics.HourOfDayKey;
 import rocks.theodolite.benchmarks.uc3.hazelcastjet.uc3specifics.HourOfDayKeySerializer;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Test methods for the Hazelcast Jet Implementation of UC3.
@@ -49,13 +47,13 @@ public class Uc3PipelineTest extends JetTestSupport {
   public void buildUc3Pipeline() {
 
     // Setup Configuration
-    int testItemsPerSecond = 1;
-    String testSensorName = "TEST-SENSOR";
-    Double testValueInW = 10.0;
-    int testHopSizeInSec = 1;
-    int testWindowSizeInSec = 50;
+    final int testItemsPerSecond = 1;
+    final String testSensorName = "TEST-SENSOR";
+    final Double testValueInW = 10.0;
+    final int testHopSizeInSec = 1;
+    final int testWindowSizeInSec = 50;
     // Used to check hourOfDay
-    long mockTimestamp = 1632741651;
+    final long mockTimestamp = 1632741651;
 
 
     // Create mock jet instance with configuration
@@ -75,9 +73,9 @@ public class Uc3PipelineTest extends JetTestSupport {
         });
 
     // Create pipeline to test
-    Uc3PipelineBuilder pipelineBuilder = new Uc3PipelineBuilder();
+    final Uc3PipelineBuilder pipelineBuilder = new Uc3PipelineBuilder();
     this.testPipeline = Pipeline.create();
-    this.uc3Topology = pipelineBuilder.extendUc3Topology(testPipeline, testSource,
+    this.uc3Topology = pipelineBuilder.extendUc3Topology(this.testPipeline, testSource,
         testHopSizeInSec, testWindowSizeInSec);
   }
 
@@ -88,11 +86,11 @@ public class Uc3PipelineTest extends JetTestSupport {
   public void testOutput() {
 
     // Assertion Configuration
-    int timeout = 10;
-    String testSensorName = "TEST-SENSOR";
-    Double testValueInW = 10.0;
+    final int timeout = 10;
+    final String testSensorName = "TEST-SENSOR";
+    final Double testValueInW = 10.0;
     // Used to check hourOfDay
-    long mockTimestamp = 1632741651;
+    final long mockTimestamp = 1632741651;
 
     // Assertion
     this.uc3Topology.apply(Assertions.assertCollectedEventually(timeout,
@@ -105,17 +103,15 @@ public class Uc3PipelineTest extends JetTestSupport {
           boolean allOkay = true;
           if (collection != null) {
             System.out.println("DEBUG: CHECK 2 || Collection Size: " + collection.size());
-            for (int i = 0; i < collection.size(); i++) {
+            for (final Entry<String, String> currentEntry : collection) {
 
               // Build hour of day
-              long timestamp = mockTimestamp;
-              int expectedHour = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp),
+              final long timestamp = mockTimestamp;
+              final int expectedHour = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp),
                   TimeZone.getDefault().toZoneId()).getHour();
 
-              // Compare expected output with generated output
-              Entry<String, String> currentEntry = collection.get(i);
-              String expectedKey = testSensorName + ";" + expectedHour;
-              String expectedValue = testValueInW.toString();
+              final String expectedKey = testSensorName + ";" + expectedHour;
+              final String expectedValue = testValueInW.toString();
 
               // DEBUG
               System.out.println(
diff --git a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HistoryService.java b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HistoryService.java
index a327d2ecfa4c0727e7a29a69e7ab8910afdfd3d2..8776fcda3092d8282f6ab85f69c734bf834a2bcc 100644
--- a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HistoryService.java
+++ b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HistoryService.java
@@ -4,8 +4,8 @@ import java.time.Duration;
 import java.util.concurrent.CompletableFuture;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.KafkaStreams;
+import rocks.theodolite.benchmarks.commons.commons.configuration.ServiceConfigurations;
 import rocks.theodolite.benchmarks.commons.kstreams.ConfigurationKeys;
-import titan.ccp.common.configuration.ServiceConfigurations;
 
 /**
  * A microservice that manages the history and, therefore, stores and aggregates incoming
diff --git a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayKeySerde.java b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayKeySerde.java
index 4014e5e30dee36a737ab582e527fc8fb4b8a32a9..e2a3b03e1e51df2756299b66d24e89d9cf0403b9 100644
--- a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayKeySerde.java
+++ b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayKeySerde.java
@@ -1,10 +1,10 @@
 package rocks.theodolite.benchmarks.uc3.kstreams;
 
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link BufferSerde} for a {@link HourOfDayKey}. Use the {@link #create()} method to create a new
diff --git a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayRecordFactory.java b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayRecordFactory.java
index 3d67a6ebe86eb33378fe0711b6b8ca1ab1f5c6a9..4d2e2d5b5014dda3604085972fdcf56e8f8aa011 100644
--- a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayRecordFactory.java
+++ b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/HourOfDayRecordFactory.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc3.kstreams;
 
 import com.google.common.math.Stats;
 import org.apache.kafka.streams.kstream.Windowed;
-import titan.ccp.model.records.HourOfDayActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.HourOfDayActivePowerRecord;
 
 /**
  * {@link StatsRecordFactory} to create an {@link HourOfDayActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/TopologyBuilder.java b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/TopologyBuilder.java
index b956959c5680c3c23eb35c0548004bb55de09a20..f2825ca81f69b5a70e883dcf034c51093745221d 100644
--- a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/TopologyBuilder.java
+++ b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/TopologyBuilder.java
@@ -16,10 +16,10 @@ import org.apache.kafka.streams.kstream.Grouped;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.kstream.TimeWindows;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
+import rocks.theodolite.benchmarks.commons.kstreams.GenericSerde;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc3.kstreams.util.StatsFactory;
-import titan.ccp.common.kafka.GenericSerde;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * Builds Kafka Stream Topology for the History microservice.
diff --git a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/Uc3KafkaStreamsBuilder.java b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/Uc3KafkaStreamsBuilder.java
index 3c80e5eedef0c9dda8ac3c729f158d0872b5769b..e05b30f75a3a1e01f132e56595e50297160c5c66 100644
--- a/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/Uc3KafkaStreamsBuilder.java
+++ b/theodolite-benchmarks/uc3-kstreams/src/main/java/rocks/theodolite/benchmarks/uc3/kstreams/Uc3KafkaStreamsBuilder.java
@@ -5,8 +5,8 @@ import java.util.Objects;
 import java.util.Properties;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.Topology;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
 import rocks.theodolite.benchmarks.commons.kstreams.KafkaStreamsBuilder;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
 
 /**
  * Builder for the Kafka Streams configuration.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedActivePowerRecordEventTimePolicy.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedActivePowerRecordEventTimePolicy.java
index 3af4957aa210a5f6a184bf4b513202dd4087567f..1a2f99cd82a9f8b4af7b3b5a13ad8610036cbc72 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedActivePowerRecordEventTimePolicy.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedActivePowerRecordEventTimePolicy.java
@@ -5,7 +5,7 @@ import org.apache.beam.sdk.io.kafka.KafkaRecord;
 import org.apache.beam.sdk.io.kafka.TimestampPolicy;
 import org.apache.beam.sdk.transforms.windowing.BoundedWindow;
 import org.joda.time.Instant;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * TimeStampPolicy to use event time based on the timestamp of the record value.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedToActive.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedToActive.java
index 63f914dca0e6536d52ce225e791d2e3b89107394..4d1c2241eefa8706c29d08256304ecec8313e478 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedToActive.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/AggregatedToActive.java
@@ -2,8 +2,8 @@ package rocks.theodolite.benchmarks.uc4.beam;
 
 import org.apache.beam.sdk.transforms.SimpleFunction;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * Converts AggregatedActivePowerRecord to ActivePowerRecord.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/DuplicateAsFlatMap.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/DuplicateAsFlatMap.java
index 1b430c99bb127f0746772571443f625ae69be54d..1c4071f4a3bbe78683c9e4854f62d428fc8a07ad 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/DuplicateAsFlatMap.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/DuplicateAsFlatMap.java
@@ -10,7 +10,7 @@ import org.apache.beam.sdk.state.ValueState;
 import org.apache.beam.sdk.transforms.DoFn;
 import org.apache.beam.sdk.values.KV;
 import org.apache.beam.sdk.values.PCollectionView;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 
 /**
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterEvents.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterEvents.java
index 6a96d7270640c1cfa3a162e0d506792d577103c5..59818e18b7e86c53b80b2a6230087957870d2f47 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterEvents.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterEvents.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.beam;
 
 import org.apache.beam.sdk.transforms.SerializableFunction;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
 
 /**
  * Filters for {@code Event.SENSOR_REGISTRY_CHANGED} and {@code Event.SENSOR_REGISTRY_STATUS}
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterNullValues.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterNullValues.java
index 9aa48d7b8f6fdc64aad205821ec4db25f606156b..903204363ace1f19439c3686dfd278fc89da2be9 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterNullValues.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/FilterNullValues.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.beam;
 
 import org.apache.beam.sdk.transforms.SerializableFunction;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Filters {@code null} Values.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/GenerateParentsFn.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/GenerateParentsFn.java
index e6f01c3d59c5c92f5d0c51ac807a76f0a37612b1..a020d32735893c4dd0851d902dcf62304223199d 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/GenerateParentsFn.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/GenerateParentsFn.java
@@ -8,10 +8,10 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.apache.beam.sdk.transforms.DoFn;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.sensorregistry.AggregatedSensor;
-import titan.ccp.model.sensorregistry.Sensor;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.Sensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 /**
  * DoFn class to generate a child-parent pair for every sensor in the hierarchy.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/PipelineFactory.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/PipelineFactory.java
index 42d12d82026df0682f771b0cec5c1705ead83b2e..955f7101515c9467edc2e4900aa5464437f0e904 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/PipelineFactory.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/PipelineFactory.java
@@ -40,15 +40,15 @@ import rocks.theodolite.benchmarks.commons.beam.ConfigurationKeys;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaActivePowerTimestampReader;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaGenericReader;
 import rocks.theodolite.benchmarks.commons.beam.kafka.KafkaWriterTransformation;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 import rocks.theodolite.benchmarks.uc4.beam.serialization.AggregatedActivePowerRecordCoder;
 import rocks.theodolite.benchmarks.uc4.beam.serialization.AggregatedActivePowerRecordDeserializer;
 import rocks.theodolite.benchmarks.uc4.beam.serialization.AggregatedActivePowerRecordSerializer;
 import rocks.theodolite.benchmarks.uc4.beam.serialization.EventCoder;
 import rocks.theodolite.benchmarks.uc4.beam.serialization.EventDeserializer;
 import rocks.theodolite.benchmarks.uc4.beam.serialization.SensorParentKeyCoder;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
 
 /**
  * {@link AbstractPipelineFactory} for UC4.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/RecordAggregation.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/RecordAggregation.java
index 6fbf6ff3f3abcdfd4f5ca0de93d68c2532655b4d..e853e0b6e5a22d68f9b315799f86f1b6dfa1947a 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/RecordAggregation.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/RecordAggregation.java
@@ -4,8 +4,8 @@ import java.io.Serializable;
 import org.apache.beam.sdk.coders.AvroCoder;
 import org.apache.beam.sdk.coders.DefaultCoder;
 import org.apache.beam.sdk.transforms.Combine.CombineFn;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 
 
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetIdForAggregated.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetIdForAggregated.java
index 23ebb6d0104ef3992b4e2a4763dd23e722fe30f9..a616a966733e2dd3ead7d2c126efaa7c37577ff6 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetIdForAggregated.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetIdForAggregated.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.beam;
 
 import org.apache.beam.sdk.transforms.SimpleFunction;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * Sets the identifier for new {@link AggregatedActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetKeyToGroup.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetKeyToGroup.java
index 3ffba12823aca2da88250eb601615de1ac5177e2..8477e987cad81625d373ee7d1155eaf701a53087 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetKeyToGroup.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/SetKeyToGroup.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.beam;
 
 import org.apache.beam.sdk.transforms.SimpleFunction;
 import org.apache.beam.sdk.values.KV;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Set the Key for a group of {@code ActivePowerRecords} to their Parent.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordCoder.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordCoder.java
index f460d42de2042064952434f6bf044920f217138a..759b8baab70b73ad2a32c50768b7911059c68aab 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordCoder.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordCoder.java
@@ -8,7 +8,7 @@ import java.util.List;
 import org.apache.beam.sdk.coders.AvroCoder;
 import org.apache.beam.sdk.coders.Coder;
 import org.apache.beam.sdk.coders.CoderException;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * {@link Coder} for an {@link AggregatedActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordDeserializer.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordDeserializer.java
index 2c481f8e6f68a3a0decbcb73c3751f464646b7cf..1083103f7394e88c5d59ccd97aaa0885ff6b634b 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordDeserializer.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordDeserializer.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.beam.serialization;
 
 import io.confluent.kafka.streams.serdes.avro.SpecificAvroDeserializer;
 import org.apache.kafka.common.serialization.Deserializer;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * {@link Deserializer} for an {@link AggregatedActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordSerializer.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordSerializer.java
index 073c3d0f94c24872460ae58c6236a0c4e19e0d5d..2c742ca65d288e2ee04bfb860fb89cf7ecbb8bbf 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordSerializer.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/AggregatedActivePowerRecordSerializer.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.beam.serialization;
 
 import io.confluent.kafka.streams.serdes.avro.SpecificAvroSerializer;
 import org.apache.kafka.common.serialization.Serializer;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * {@link Serializer} for an {@link AggregatedActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventCoder.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventCoder.java
index b96398398e61f3db0f0632f8384d11f30ccc7aca..2d555ef12db49b76fa3d8c4a9398ce562eaa6453 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventCoder.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventCoder.java
@@ -10,8 +10,8 @@ import java.util.List;
 import org.apache.beam.sdk.coders.Coder;
 import org.apache.beam.sdk.coders.CoderException;
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.configuration.events.EventSerde;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.EventSerde;
 
 /**
  * Wrapper Class that encapsulates a Event Serde in a org.apache.beam.sdk.coders.Coder.
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventDeserializer.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventDeserializer.java
index ae9c480e1c76949f8cfa5d27c73282e270232d0a..9399a42606d6e8e7f3f58bf4a515e5f83041a88d 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventDeserializer.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/EventDeserializer.java
@@ -3,7 +3,7 @@ package rocks.theodolite.benchmarks.uc4.beam.serialization;
 import java.util.Map;
 import org.apache.kafka.common.serialization.ByteBufferDeserializer;
 import org.apache.kafka.common.serialization.Deserializer;
-import titan.ccp.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
 
 /**
  * Deserializer for Events(SensorRegistry changes).
diff --git a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/SensorParentKeySerde.java b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/SensorParentKeySerde.java
index 64242b3fd2618b154e47cc46ce2fe6f9375be209..9c8d1eff664c72fcb31e6dcfddff5f53b97ff055 100644
--- a/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/SensorParentKeySerde.java
+++ b/theodolite-benchmarks/uc4-beam/src/main/java/rocks/theodolite/benchmarks/uc4/beam/serialization/SensorParentKeySerde.java
@@ -1,11 +1,11 @@
 package rocks.theodolite.benchmarks.uc4.beam.serialization;
 
 import org.apache.kafka.common.serialization.Serde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 import rocks.theodolite.benchmarks.uc4.beam.SensorParentKey;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link Serde} factory for {@link SensorParentKey}.
diff --git a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/AggregationServiceFlinkJob.java b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/AggregationServiceFlinkJob.java
index 35ef7dd1426f287c7529ca12f00c7c1d23606ab1..5f4515cb851439841d1de3193f21275545033481 100644
--- a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/AggregationServiceFlinkJob.java
+++ b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/AggregationServiceFlinkJob.java
@@ -16,20 +16,20 @@ import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
 import org.apache.kafka.common.serialization.Serdes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.EventSerde;
 import rocks.theodolite.benchmarks.commons.flink.AbstractFlinkService;
 import rocks.theodolite.benchmarks.commons.flink.KafkaConnectorFactory;
 import rocks.theodolite.benchmarks.commons.flink.TupleType;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.ImmutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 import rocks.theodolite.benchmarks.uc4.flink.util.ImmutableSensorRegistrySerializer;
 import rocks.theodolite.benchmarks.uc4.flink.util.ImmutableSetSerializer;
 import rocks.theodolite.benchmarks.uc4.flink.util.SensorParentKey;
 import rocks.theodolite.benchmarks.uc4.flink.util.SensorParentKeySerializer;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.configuration.events.EventSerde;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
-import titan.ccp.model.sensorregistry.ImmutableSensorRegistry;
-import titan.ccp.model.sensorregistry.SensorRegistry;
 
 /**
  * The Aggregation microservice implemented as a Flink job.
diff --git a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/ChildParentsFlatMapFunction.java b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/ChildParentsFlatMapFunction.java
index c439df1e49381f8779a64814ae056635bd408c64..77391393d2977218ff15972f0329393388d24453 100644
--- a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/ChildParentsFlatMapFunction.java
+++ b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/ChildParentsFlatMapFunction.java
@@ -13,9 +13,9 @@ import org.apache.flink.api.common.typeinfo.TypeInformation;
 import org.apache.flink.api.java.tuple.Tuple2;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.util.Collector;
-import titan.ccp.model.sensorregistry.AggregatedSensor;
-import titan.ccp.model.sensorregistry.Sensor;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.Sensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 /**
  * Transforms a {@link SensorRegistry} into key value pairs of Sensor identifiers and their parents'
diff --git a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/JoinAndDuplicateCoFlatMapFunction.java b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/JoinAndDuplicateCoFlatMapFunction.java
index 624327a69feb8bce2f1b85af3e57cf5db9511e74..0171e4b0b0c876242834edc76e8117615dc6b3b2 100644
--- a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/JoinAndDuplicateCoFlatMapFunction.java
+++ b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/JoinAndDuplicateCoFlatMapFunction.java
@@ -9,8 +9,8 @@ import org.apache.flink.api.java.tuple.Tuple2;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.streaming.api.functions.co.RichCoFlatMapFunction;
 import org.apache.flink.util.Collector;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.uc4.flink.util.SensorParentKey;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * A {@link RichCoFlatMapFunction} which joins each incoming {@link ActivePowerRecord} with its
diff --git a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/RecordAggregationProcessWindowFunction.java b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/RecordAggregationProcessWindowFunction.java
index 29e1ea32235ae0789e72f4931932b2697c60759b..6dff6edaf5fb6343f0c6c4b12cbff4a9175751eb 100644
--- a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/RecordAggregationProcessWindowFunction.java
+++ b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/RecordAggregationProcessWindowFunction.java
@@ -11,9 +11,9 @@ import org.apache.flink.configuration.Configuration;
 import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
 import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
 import org.apache.flink.util.Collector;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 import rocks.theodolite.benchmarks.uc4.flink.util.SensorParentKey;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
 
 /**
  * A {@link ProcessWindowFunction} which performs the windowed aggregation of all
diff --git a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/util/ImmutableSensorRegistrySerializer.java b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/util/ImmutableSensorRegistrySerializer.java
index 54d8826900cc70a5eb86d71df7fcf9c4a4da4a7f..c491adc47d31211e809a00ad283266511e96c534 100644
--- a/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/util/ImmutableSensorRegistrySerializer.java
+++ b/theodolite-benchmarks/uc4-flink/src/main/java/rocks/theodolite/benchmarks/uc4/flink/util/ImmutableSensorRegistrySerializer.java
@@ -5,7 +5,7 @@ import com.esotericsoftware.kryo.Serializer;
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 import java.io.Serializable;
-import titan.ccp.model.sensorregistry.ImmutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.ImmutableSensorRegistry;
 
 /**
  * A {@link Serializer} for {@link ImmutableSensorRegistry}s.
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4HazelcastJetFactory.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4HazelcastJetFactory.java
index 9b6aa71267150296d8b65268b1922925b7ada796..69ccee100f2946237390c8b19ff0f20036237d37 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4HazelcastJetFactory.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4HazelcastJetFactory.java
@@ -13,13 +13,13 @@ import org.slf4j.Logger;
 import rocks.theodolite.benchmarks.commons.hazelcastjet.ConfigurationKeys;
 import rocks.theodolite.benchmarks.commons.hazelcastjet.JetInstanceBuilder;
 import rocks.theodolite.benchmarks.commons.hazelcastjet.KafkaPropertiesBuilder;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.ImmutableSensorRegistry;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.EventDeserializer;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ImmutableSensorRegistryUc4Serializer;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.SensorGroupKey;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.SensorGroupKeySerializer;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ValueGroup;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ValueGroupSerializer;
-import titan.ccp.model.sensorregistry.ImmutableSensorRegistry;
 
 /**
  * A Hazelcast Jet factory which can build a Hazelcast Jet Instance and Pipeline for the UC4
@@ -57,18 +57,8 @@ public class Uc4HazelcastJetFactory {
    * @throws Exception If either no JetInstance or Pipeline is set, a job cannot be startet.
    */
   public void runUc4Job(final String jobName) throws IllegalStateException { // NOPMD
-
-    // Check if a Jet Instance for UC4 is set.
-    if (this.uc4JetInstance == null) {
-      throw new IllegalStateException("Jet Instance is not set! "
-          + "Cannot start a hazelcast jet job for UC4.");
-    }
-
-    // Check if a Pipeline for UC3 is set.
-    if (this.uc4JetPipeline == null) {
-      throw new IllegalStateException(
-          "Hazelcast Pipeline is not set! Cannot start a hazelcast jet job for UC4.");
-    }
+    Objects.requireNonNull(this.uc4JetInstance, "Jet instance is not set.");
+    Objects.requireNonNull(this.uc4JetPipeline, "Jet pipeline is not set.");
 
     // Adds the job name and joins a job to the JetInstance defined in this factory
     final JobConfig jobConfig = new JobConfig()
@@ -197,9 +187,9 @@ public class Uc4HazelcastJetFactory {
    * @return The Uc4HazelcastJetBuilder factory with set kafkaReadPropertiesForPipeline.
    */
   public Uc4HazelcastJetFactory setReadPropertiesFromEnv(// NOPMD
-                                                         final String bootstrapServersDefault,
-                                                         final String schemaRegistryUrlDefault,
-                                                         final String jobName) {
+      final String bootstrapServersDefault,
+      final String schemaRegistryUrlDefault,
+      final String jobName) {
     // Use KafkaPropertiesBuilder to build a properties object used for kafka
     final KafkaPropertiesBuilder propsBuilder = new KafkaPropertiesBuilder();
 
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineBuilder.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineBuilder.java
index 2efb8250c0e1136b34412e4553b2d216c5e24b43..87d10bc5c0fd417082c12c5a1a26bbf9116c8a50 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineBuilder.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineBuilder.java
@@ -1,4 +1,4 @@
-package rocks.theodolite.benchmarks.uc4.hazelcastjet;
+package rocks.theodolite.benchmarks.uc4.hazelcastjet; // NOPMD Excessive imports
 
 import com.hazelcast.function.BiFunctionEx;
 import com.hazelcast.jet.Traverser;
@@ -17,7 +17,6 @@ import com.hazelcast.jet.pipeline.StreamStageWithKey;
 import com.hazelcast.jet.pipeline.WindowDefinition;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -25,20 +24,19 @@ import java.util.Properties;
 import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.AggregatedActivePowerRecordAccumulator;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ChildParentsTransformer;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.SensorGroupKey;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ValueGroup;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
-import titan.ccp.model.sensorregistry.SensorRegistry;
 
 /**
  * Builder to build a HazelcastJet Pipeline for UC4 which can be used for stream processing using
  * Hazelcast Jet.
  */
-@SuppressWarnings("PMD.ExcessiveImports")
 public class Uc4PipelineBuilder {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(Uc4PipelineBuilder.class);
@@ -117,9 +115,9 @@ public class Uc4PipelineBuilder {
    *
    * <p>
    * UC4 takes {@code ActivePowerRecord} events from sensors and a {@code SensorRegistry} with maps
-   * from keys to groups to map values to their according groups. A feedback stream allows for
-   * group keys to be mapped to values and eventually to be mapped to other top level groups defines
-   * by the {@code SensorRegistry}.
+   * from keys to groups to map values to their according groups. A feedback stream allows for group
+   * keys to be mapped to values and eventually to be mapped to other top level groups defines by
+   * the {@code SensorRegistry}.
    * </p>
    *
    * <p>
@@ -180,10 +178,10 @@ public class Uc4PipelineBuilder {
 
     //////////////////////////////////
     // (2) UC4 Merge Input with aggregation stream
-    final StreamStageWithKey<Entry<String, ActivePowerRecord>, String>
-        mergedInputAndAggregations = inputStream
-        .merge(aggregations)
-        .groupingKey(Entry::getKey);
+    final StreamStageWithKey<Entry<String, ActivePowerRecord>, String> mergedInputAndAggregations =
+        inputStream
+            .merge(aggregations)
+            .groupingKey(Entry::getKey);
 
     //////////////////////////////////
     // (3) UC4 Join Configuration and Merges Input/Aggregation Stream
@@ -192,20 +190,10 @@ public class Uc4PipelineBuilder {
         .<Set<String>, Entry<String, ValueGroup>>mapUsingIMap(
             SENSOR_PARENT_MAP_NAME,
             (sensorEvent, sensorParentsSet) -> {
-              // Check whether a groupset exists for a key or not
-              if (sensorParentsSet == null) {
-                // No group set exists for this key: return valuegroup with default null group set.
-                final Set<String> nullSet = new HashSet<>();
-                nullSet.add("NULL-GROUPSET");
-                return Util.entry(sensorEvent.getKey(),
-                    new ValueGroup(sensorEvent.getValue(), nullSet));
-              } else {
-                // Group set exists for this key: return valuegroup with the groupset.
-                final ValueGroup valueParentsPair =
-                    new ValueGroup(sensorEvent.getValue(), sensorParentsSet);
-                // Return solution
-                return Util.entry(sensorEvent.getKey(), valueParentsPair);
-              }
+              final ValueGroup valueParentsPair = new ValueGroup(
+                  sensorEvent.getValue(),
+                  sensorParentsSet == null ? Set.of() : sensorParentsSet);
+              return Util.entry(sensorEvent.getKey(), valueParentsPair);
             });
 
     //////////////////////////////////
@@ -235,28 +223,25 @@ public class Uc4PipelineBuilder {
     //////////////////////////////////
     // (5) UC4 Last Value Map
     // Table with tumbling window differentiation [ (sensorKey,Group) , value ],Time
-    final StageWithWindow<Entry<SensorGroupKey, ActivePowerRecord>>
-        windowedLastValues = dupliAsFlatmappedStage
-        .window(WindowDefinition.tumbling(windowSize));
+    final StageWithWindow<Entry<SensorGroupKey, ActivePowerRecord>> windowedLastValues =
+        dupliAsFlatmappedStage
+            .window(WindowDefinition.tumbling(windowSize));
 
-    final AggregateOperation1<Entry<SensorGroupKey, ActivePowerRecord>,
-        AggregatedActivePowerRecordAccumulator, AggregatedActivePowerRecord> aggrOp =
+    final AggregateOperation1<Entry<SensorGroupKey, ActivePowerRecord>, AggregatedActivePowerRecordAccumulator, AggregatedActivePowerRecord> aggrOp = // NOCS
         AggregateOperation
-        .withCreate(AggregatedActivePowerRecordAccumulator::new)
-        .<Entry<SensorGroupKey, ActivePowerRecord>>andAccumulate((acc, rec) -> {
-          acc.setId(rec.getKey().getGroup());
-          acc.addInputs(rec.getValue());
-        })
-        .andCombine((acc, acc2) ->
-            acc.addInputs(acc2.getId(), acc2.getSumInW(), acc2.getCount(), acc.getTimestamp()))
-        .andDeduct((acc, acc2) -> acc.removeInputs(acc2.getSumInW(), acc2.getCount()))
-        .andExportFinish(acc ->
-            new AggregatedActivePowerRecord(acc.getId(),
+            .withCreate(AggregatedActivePowerRecordAccumulator::new)
+            .<Entry<SensorGroupKey, ActivePowerRecord>>andAccumulate((acc, rec) -> {
+              acc.setId(rec.getKey().getGroup());
+              acc.addInputs(rec.getValue());
+            })
+            .andCombine((acc, acc2) -> acc.addInputs(acc2.getId(), acc2.getSumInW(),
+                acc2.getCount(), acc.getTimestamp()))
+            .andDeduct((acc, acc2) -> acc.removeInputs(acc2.getSumInW(), acc2.getCount()))
+            .andExportFinish(acc -> new AggregatedActivePowerRecord(acc.getId(),
                 acc.getTimestamp(),
                 acc.getCount(),
                 acc.getSumInW(),
-                acc.getAverageInW())
-        );
+                acc.getAverageInW()));
 
     // write aggregation back to kafka
 
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/AggregatedActivePowerRecordAccumulator.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/AggregatedActivePowerRecordAccumulator.java
index 3166f16cd31bf0e6d4dff6548468791e7a5e5c5c..14934fbe3ceec6e01836958c1f7686e225ea40fd 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/AggregatedActivePowerRecordAccumulator.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/AggregatedActivePowerRecordAccumulator.java
@@ -1,6 +1,6 @@
 package rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics;
 
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Accumulator class for AggregatedActivePowerRecords.
@@ -25,10 +25,10 @@ public class AggregatedActivePowerRecordAccumulator {
    * Creates an AggregationObject.
    */
   public AggregatedActivePowerRecordAccumulator(final String id,
-                                                final long timestamp,
-                                                final long count,
-                                                final double sumInW,
-                                                final double averageInW) {
+      final long timestamp,
+      final long count,
+      final double sumInW,
+      final double averageInW) {
     this.id = id;
     this.timestamp = timestamp;
     this.count = count;
@@ -50,16 +50,16 @@ public class AggregatedActivePowerRecordAccumulator {
     this.count += 1;
     this.sumInW += record.getValueInW();
     this.timestamp = record.getTimestamp();
-    this.averageInW = sumInW / count;
+    this.averageInW = this.sumInW / this.count;
   }
 
   /**
    * Adds the records from another aggregator.
    */
   public void addInputs(final String id,
-                        final double sumInW,
-                        final long count,
-                        final long timestamp) {
+      final double sumInW,
+      final long count,
+      final long timestamp) {
     this.id = this.id == null ? id : this.id;
     this.sumInW += sumInW;
     this.count += count;
@@ -68,8 +68,8 @@ public class AggregatedActivePowerRecordAccumulator {
   }
 
   /**
-   * Removes the values of another aggreagator.
-   * Not a complete reset since the old timestamp is lost.
+   * Removes the values of another aggreagator. Not a complete reset since the old timestamp is
+   * lost.
    */
   public void removeInputs(final double sumInW, final long count) {
     this.sumInW -= sumInW;
@@ -79,22 +79,22 @@ public class AggregatedActivePowerRecordAccumulator {
   }
 
   public long getCount() {
-    return count;
+    return this.count;
   }
 
   public double getSumInW() {
-    return sumInW;
+    return this.sumInW;
   }
 
   public double getAverageInW() {
-    return averageInW;
+    return this.averageInW;
   }
 
   public String getId() {
-    return id;
+    return this.id;
   }
 
   public long getTimestamp() {
-    return timestamp;
+    return this.timestamp;
   }
 }
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ChildParentsTransformer.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ChildParentsTransformer.java
index ad3b2294cb934ba04b07df2e2b2d3dbdd6e1a905..3ba604270e37d746c2e98bc4eef5c80d2526b446 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ChildParentsTransformer.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ChildParentsTransformer.java
@@ -10,10 +10,11 @@ import org.apache.kafka.streams.kstream.Transformer;
 import org.apache.kafka.streams.processor.ProcessorContext;
 import org.apache.kafka.streams.state.KeyValueIterator;
 import org.apache.kafka.streams.state.KeyValueStore;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.sensorregistry.AggregatedSensor;
-import titan.ccp.model.sensorregistry.Sensor;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.Sensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
+
 
 /**
  * Transforms a {@link SensorRegistry} into key value pairs of Sensor identifiers and their parents'
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/EventDeserializer.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/EventDeserializer.java
index c8d06b497009944b9a9a0fda4ab224e5fe992e3d..ebdc9de86e82a9c8c16a71830190d26e6f0e34fa 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/EventDeserializer.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/EventDeserializer.java
@@ -2,8 +2,8 @@ package rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics;
 
 import java.util.Map;
 import org.apache.kafka.common.serialization.Deserializer;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.configuration.events.EventSerde;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.EventSerde;
 
 /**
  * Deserializer for Event Objects.
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ImmutableSensorRegistryUc4Serializer.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ImmutableSensorRegistryUc4Serializer.java
index 53d22f7f156891cf11e5b8915eed17b74c3d57fb..84e007dde7fb3a075a605bacfbbda05f206c2ee4 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ImmutableSensorRegistryUc4Serializer.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ImmutableSensorRegistryUc4Serializer.java
@@ -4,7 +4,7 @@ import com.hazelcast.nio.ObjectDataInput;
 import com.hazelcast.nio.ObjectDataOutput;
 import com.hazelcast.nio.serialization.StreamSerializer;
 import java.io.IOException;
-import titan.ccp.model.sensorregistry.ImmutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.ImmutableSensorRegistry;
 
 /**
  * {@link StreamSerializer} for Hazelcast Jet to serialize and deserialize an
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ValueGroup.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ValueGroup.java
index 893efcf74fe8a16202d795fca5cc43b63190dc50..b5f5fc7cb2822667dcaa26560fa83b2da3a513d9 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ValueGroup.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/uc4specifics/ValueGroup.java
@@ -2,7 +2,8 @@ package rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics;
 
 import java.util.Objects;
 import java.util.Set;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+
 
 /**
  * Structure: (valueInW, Set(Groups)).
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineTest.java b/theodolite-benchmarks/uc4-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineTest.java
index b74c2874b92a51b138ffe8b44b1cf750dfce5880..e59f4cabc5acb09943f1f53dcb881dae001ffc26 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineTest.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/test/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineTest.java
@@ -22,24 +22,23 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import rocks.theodolite.benchmarks.uc4.hazelcastjet.Uc4PipelineBuilder;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.ImmutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MachineSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableAggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableSensorRegistry;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ImmutableSensorRegistryUc4Serializer;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.SensorGroupKey;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.SensorGroupKeySerializer;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ValueGroup;
 import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.ValueGroupSerializer;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
-import titan.ccp.model.sensorregistry.ImmutableSensorRegistry;
-import titan.ccp.model.sensorregistry.MachineSensor;
-import titan.ccp.model.sensorregistry.MutableAggregatedSensor;
-import titan.ccp.model.sensorregistry.MutableSensorRegistry;
+
 
 @Category(SerialTest.class)
 public class Uc4PipelineTest extends JetTestSupport {
 
-  // TEst Machinery
   JetInstance testInstance = null;
   Pipeline testPipeline = null;
   StreamStage<Entry<String, AggregatedActivePowerRecord>> uc4Topology = null;
@@ -55,7 +54,7 @@ public class Uc4PipelineTest extends JetTestSupport {
     final Double testValueInW = 10.0;
     final int testWindowSize = 5000; // As window size is bugged, not necessary.
 
-    // Create mock jet instance with configuration
+    // Create mocked Hazelcast Jet instance with configuration
     final String testClusterName = randomName();
     final JetConfig testJetConfig = new JetConfig();
     testJetConfig.getHazelcastConfig().setClusterName(testClusterName);
@@ -75,7 +74,7 @@ public class Uc4PipelineTest extends JetTestSupport {
     final StreamSource<Entry<String, AggregatedActivePowerRecord>> testAggregationSource =
         TestSources.itemStream(testItemsPerSecond, (timestamp, item) -> {
 
-          AggregatedActivePowerRecord test =
+          final AggregatedActivePowerRecord test =
               new AggregatedActivePowerRecord(testSensorName,
                   System.currentTimeMillis(),
                   1L,
@@ -100,7 +99,7 @@ public class Uc4PipelineTest extends JetTestSupport {
 
           // Topology:
           // level2Group -> level1Group -> testSensor
-          
+
           // Create Registry
           final MutableSensorRegistry testRegistry = new MutableSensorRegistry(testLevel2GroupName);
           // Add Sensors
@@ -118,7 +117,7 @@ public class Uc4PipelineTest extends JetTestSupport {
     // Create pipeline to test
     final Uc4PipelineBuilder pipelineBuilder = new Uc4PipelineBuilder();
     this.testPipeline = Pipeline.create();
-    this.uc4Topology = pipelineBuilder.extendUc4Topology(testPipeline,
+    this.uc4Topology = pipelineBuilder.extendUc4Topology(this.testPipeline,
         testInputSource, testAggregationSource, testConfigSource, testWindowSize);
 
     this.uc4Topology.writeTo(Sinks.logger());
@@ -130,8 +129,8 @@ public class Uc4PipelineTest extends JetTestSupport {
   @Test
   public void testOutput() {
 
-//    System.out.println("DEBUG DEBUG DEBUG || ENTERED TEST 1");
-    
+    // System.out.println("DEBUG DEBUG DEBUG || ENTERED TEST 1");
+
     // Assertion Configuration
     final int timeout = 20;
     final String testSensorName = "TEST-SENSOR";
@@ -141,7 +140,7 @@ public class Uc4PipelineTest extends JetTestSupport {
 
 
     // Assertion
-    this.uc4Topology.apply(Assertions.assertCollectedEventually(timeout, 
+    this.uc4Topology.apply(Assertions.assertCollectedEventually(timeout,
         collection -> {
           System.out.println("DEBUG || ENTERED ASSERTION COLLECTED EVENTUALLY");
 
@@ -168,11 +167,11 @@ public class Uc4PipelineTest extends JetTestSupport {
                 testLevel1contained = true;
               }
 
-              if(Objects.equals(key, testLevel2GroupName)){
+              if (Objects.equals(key, testLevel2GroupName)) {
                 testLevel2contained = true;
               }
 
-              if (testValueInW != agg.getAverageInW()){
+              if (testValueInW != agg.getAverageInW()) {
                 averageEqTest = false;
               }
 
@@ -191,10 +190,10 @@ public class Uc4PipelineTest extends JetTestSupport {
           System.out.println("avOk: " + avOk);
 
           Assert.assertTrue("Assertion did not complete!", allOkay);
-          
+
         }));
 
-    try{
+    try {
 
       final JobConfig jobConfig = new JobConfig()
           .registerSerializer(ValueGroup.class, ValueGroupSerializer.class)
@@ -209,7 +208,7 @@ public class Uc4PipelineTest extends JetTestSupport {
           "Job was expected to complete with AssertionCompletedException, but completed with: "
               + e.getCause(),
           errorMsg.contains(AssertionCompletedException.class.getName()));
-    } catch (Exception e){
+    } catch (final Exception e) {
       System.out.println("ERRORORORO TEST BROKEN !!!!");
       System.out.println(e);
     }
@@ -218,7 +217,6 @@ public class Uc4PipelineTest extends JetTestSupport {
 
   @After
   public void after() {
-    System.out.println("Shutting down");
     // Shuts down all running Jet Instances
     Jet.shutdownAll();
   }
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/AggregationService.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/AggregationService.java
index 341c37bc086dabb3a93dcd3b0f221dd91007b8b3..26ea02957fb013c61c4ee0c3e2f280b0b9b8c993 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/AggregationService.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/AggregationService.java
@@ -4,8 +4,8 @@ import java.time.Duration;
 import java.util.concurrent.CompletableFuture;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.KafkaStreams;
+import rocks.theodolite.benchmarks.commons.commons.configuration.ServiceConfigurations;
 import rocks.theodolite.benchmarks.commons.kstreams.ConfigurationKeys;
-import titan.ccp.common.configuration.ServiceConfigurations;
 
 /**
  * A microservice that manages the history and, therefore, stores and aggregates incoming
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformer.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformer.java
index bdc8fc7d4267fbdb427d8dc217ef296c0553da1b..d311ff009c138c6afe29cf9e95c323ea46a6bc0f 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformer.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformer.java
@@ -10,10 +10,10 @@ import org.apache.kafka.streams.kstream.Transformer;
 import org.apache.kafka.streams.processor.ProcessorContext;
 import org.apache.kafka.streams.state.KeyValueIterator;
 import org.apache.kafka.streams.state.KeyValueStore;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.sensorregistry.AggregatedSensor;
-import titan.ccp.model.sensorregistry.Sensor;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.Sensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 /**
  * Transforms a {@link SensorRegistry} into key value pairs of Sensor identifiers and their parents'
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformerSupplier.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformerSupplier.java
index 538643f0cdb119988e446f3eae793e2efcccadd6..734989af63b6b2a7fc97b368bb2651112c98fda5 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformerSupplier.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ChildParentsTransformerSupplier.java
@@ -10,8 +10,8 @@ import org.apache.kafka.streams.kstream.TransformerSupplier;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.StoreBuilder;
 import org.apache.kafka.streams.state.Stores;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 /**
  * Supplier class for a {@link ChildParentsTransformer}.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformer.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformer.java
index 38cbca81d664ca72494525263d8a7ab3a7523bfc..06cbe1f40719fcbb6b9b8a22767ec415def3dc80 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformer.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformer.java
@@ -9,7 +9,7 @@ import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.kstream.Transformer;
 import org.apache.kafka.streams.processor.ProcessorContext;
 import org.apache.kafka.streams.state.KeyValueStore;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Transforms the join result of an {@link ActivePowerRecord} and the corresponding sensor parents
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformerSupplier.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformerSupplier.java
index 2e635ec368bca87bdb882580b51f763abba8f32a..67efca0671ad347add9d5dcc1f255a9c8d9de09b 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformerSupplier.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointFlatTransformerSupplier.java
@@ -9,7 +9,7 @@ import org.apache.kafka.streams.kstream.TransformerSupplier;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.StoreBuilder;
 import org.apache.kafka.streams.state.Stores;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * Supplier class for {@link JointFlatTransformerSupplier}.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointRecordParents.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointRecordParents.java
index 5892c6d3ac84c6d1ff56cfb440186e07fd9d9eb0..85b3a817564367098996196694994497b9db8793 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointRecordParents.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/JointRecordParents.java
@@ -2,7 +2,7 @@ package rocks.theodolite.benchmarks.uc4.kstreams;
 
 import java.util.Objects;
 import java.util.Set;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 /**
  * A joined pair of an {@link ActivePowerRecord} and its associated parents. Both the record and the
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/OptionalParentsSerde.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/OptionalParentsSerde.java
index 3738fadd52b22abb8e13f20ae6066017112f0455..e5ff9c676b4ea539fb9605fc51c93920c3757fc8 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/OptionalParentsSerde.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/OptionalParentsSerde.java
@@ -4,10 +4,10 @@ import java.util.HashSet;
 import java.util.Optional;
 import java.util.Set;
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link Serde} factory for an optional {@link Set} of parent identifiers.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ParentsSerde.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ParentsSerde.java
index dac58c84bc1914b4e54fe5eb6da0930204e34eb5..b70df46325f60c82a3759219827e9ab54b17b57a 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ParentsSerde.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/ParentsSerde.java
@@ -3,10 +3,10 @@ package rocks.theodolite.benchmarks.uc4.kstreams;
 import java.util.HashSet;
 import java.util.Set;
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link Serde} factory for {@link Set} of parent identifiers.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/RecordAggregator.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/RecordAggregator.java
index d107dedbfdb58489a6f00e2baf248f15bb823db9..bbc6079521d38b75ae35ea49fda26e7504746b23 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/RecordAggregator.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/RecordAggregator.java
@@ -1,8 +1,8 @@
 package rocks.theodolite.benchmarks.uc4.kstreams;
 
 import org.apache.kafka.streams.kstream.Windowed;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
 
 /**
  * Updates an {@link AggregatedActivePowerRecord} by a new {@link ActivePowerRecord}.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/SensorParentKeySerde.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/SensorParentKeySerde.java
index 80fd16f64c6f08e32a89bb3558b61d3f560be890..1beab6094bcc87bed0bbbedbc449edadf3523c19 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/SensorParentKeySerde.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/SensorParentKeySerde.java
@@ -1,10 +1,10 @@
 package rocks.theodolite.benchmarks.uc4.kstreams;
 
 import org.apache.kafka.common.serialization.Serde;
-import titan.ccp.common.kafka.simpleserdes.BufferSerde;
-import titan.ccp.common.kafka.simpleserdes.ReadBuffer;
-import titan.ccp.common.kafka.simpleserdes.SimpleSerdes;
-import titan.ccp.common.kafka.simpleserdes.WriteBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.BufferSerde;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.ReadBuffer;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.SimpleSerdes;
+import rocks.theodolite.benchmarks.commons.kafka.simpleserdes.WriteBuffer;
 
 /**
  * {@link Serde} factory for {@link SensorParentKey}.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/TopologyBuilder.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/TopologyBuilder.java
index fbd3ed109965b103e4f1cdeb4324581bc6c82e8b..876e53422183306963cf07853939247bbb012464 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/TopologyBuilder.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/TopologyBuilder.java
@@ -18,12 +18,12 @@ import org.apache.kafka.streams.kstream.Suppressed.BufferConfig;
 import org.apache.kafka.streams.kstream.TimeWindows;
 import org.apache.kafka.streams.kstream.Windowed;
 import org.apache.kafka.streams.kstream.WindowedSerdes;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.configuration.events.EventSerde;
-import titan.ccp.model.records.ActivePowerRecord;
-import titan.ccp.model.records.AggregatedActivePowerRecord;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.EventSerde;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.AggregatedActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 /**
  * Builds Kafka Stream Topology for the History microservice.
diff --git a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/Uc4KafkaStreamsBuilder.java b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/Uc4KafkaStreamsBuilder.java
index 4d2b96ccb751dbb804eab0806303312a88702dc0..209eb519f9e61b2aaa684686e391ccc11aa808e7 100644
--- a/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/Uc4KafkaStreamsBuilder.java
+++ b/theodolite-benchmarks/uc4-kstreams/src/main/java/rocks/theodolite/benchmarks/uc4/kstreams/Uc4KafkaStreamsBuilder.java
@@ -5,8 +5,8 @@ import java.util.Objects;
 import java.util.Properties;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.kafka.streams.Topology;
+import rocks.theodolite.benchmarks.commons.kafka.avro.SchemaRegistryAvroSerdeFactory;
 import rocks.theodolite.benchmarks.commons.kstreams.KafkaStreamsBuilder;
-import titan.ccp.common.kafka.avro.SchemaRegistryAvroSerdeFactory;
 
 /**
  * Builder for the Kafka Streams configuration.
diff --git a/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/ConfigPublisher.java b/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/ConfigPublisher.java
index 98f470b0df1873766c3bf56fb7e6a8eae0019ce4..60c95321f05edff35681d8984baa03ca711f48da 100644
--- a/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/ConfigPublisher.java
+++ b/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/ConfigPublisher.java
@@ -7,8 +7,8 @@ import org.apache.kafka.clients.producer.Producer;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.clients.producer.ProducerRecord;
 import org.apache.kafka.common.serialization.StringSerializer;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.configuration.events.EventSerde;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.configuration.events.EventSerde;
 
 /**
  * Class to publish a configuration to Kafka.
diff --git a/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/LoadGenerator.java b/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/LoadGenerator.java
index 2077de2d9918d46a7a3e671ae9820a7c7abadbfc..3f02a4b5ebf232e4dcb3ff236f656cf6fb485989 100644
--- a/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/LoadGenerator.java
+++ b/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/LoadGenerator.java
@@ -3,9 +3,9 @@ package rocks.theodolite.benchmarks.uc4.loadgenerator;
 import java.util.Objects;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import rocks.theodolite.benchmarks.commons.configuration.events.Event;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 import rocks.theodolite.benchmarks.loadgenerator.KeySpace;
-import titan.ccp.configuration.events.Event;
-import titan.ccp.model.sensorregistry.SensorRegistry;
 
 /**
  * Load generator for Theodolite use case UC4.
diff --git a/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilder.java b/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilder.java
index c69dffb6093f914111b8c74bc25f3ca3a0a34ae6..c9dcfa0af8676460c5cc59ed2f4f6b4641911525 100644
--- a/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilder.java
+++ b/theodolite-benchmarks/uc4-load-generator/src/main/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilder.java
@@ -1,8 +1,8 @@
 package rocks.theodolite.benchmarks.uc4.loadgenerator;
 
-import titan.ccp.model.sensorregistry.MutableAggregatedSensor;
-import titan.ccp.model.sensorregistry.MutableSensorRegistry;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableAggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MutableSensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 /**
  * Builder for creating a nested {@link SensorRegistry} with {@code numNestedGroups} levels and
diff --git a/theodolite-benchmarks/uc4-load-generator/src/test/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilderTest.java b/theodolite-benchmarks/uc4-load-generator/src/test/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilderTest.java
index a169eddb10ac34b91b814a657bf327a79ae00ac4..037bd8119ef1ea93ed3dae346282538ff5399f25 100644
--- a/theodolite-benchmarks/uc4-load-generator/src/test/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilderTest.java
+++ b/theodolite-benchmarks/uc4-load-generator/src/test/java/rocks/theodolite/benchmarks/uc4/loadgenerator/SensorRegistryBuilderTest.java
@@ -5,10 +5,10 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.junit.Assert;
 import org.junit.Test;
-import titan.ccp.model.sensorregistry.AggregatedSensor;
-import titan.ccp.model.sensorregistry.MachineSensor;
-import titan.ccp.model.sensorregistry.Sensor;
-import titan.ccp.model.sensorregistry.SensorRegistry;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.AggregatedSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.MachineSensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.Sensor;
+import rocks.theodolite.benchmarks.commons.model.sensorregistry.SensorRegistry;
 
 public class SensorRegistryBuilderTest {
 
diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml
index c901e61360c05b2f1cf2b1767a20f624eb262231..cfc9d3bd6a196cd5740463d41beb64276f4ffa57 100644
--- a/theodolite/crd/crd-benchmark.yaml
+++ b/theodolite/crd/crd-benchmark.yaml
@@ -20,12 +20,16 @@ spec:
         properties:
           spec:
             type: object
-            required: ["sut", "loadGenerator", "resourceTypes", "loadTypes"]
+            required: ["sut", "loadGenerator", "resourceTypes", "loadTypes", "slos"]
             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.
                 type: string
                 default: ""
+              waitForResourcesEnabled:
+                description: If true, Theodolite waits to create the resource for the SUT until the infrastructure resources are ready, and analogously, Theodolite waits to create the load-gen resource until the resources of the SUT are ready.
+                type: boolean
+                default: false
               infrastructure:
                 description: (Optional) A list of file names that reference Kubernetes resources that are deployed on the cluster to create the required infrastructure.
                 type: object
@@ -70,29 +74,33 @@ spec:
                     description: Infrastructure before actions are executed before the infrastructure is set up.
                     items:
                       type: object
+                      anyOf:
+                        - required: [ exec ]
+                        - required: [ delete ]
                       properties:
-                        selector:
+                        exec:
                           type: object
-                          description: The selector specifies which resource should be selected for the execution of the command.
+                          description: Specifies a command that gets executed within a Container of a Pod
+                          required: [ selector, command, timeoutSeconds ]
                           properties:
-                            pod:
+                            selector:
                               type: object
-                              description: Specifies the pod.
+                              description: The selector specifies which resource should be selected for the execution of the command.
                               properties:
-                                matchLabels:
+                                pod:
                                   type: object
-                                  description: The matchLabels of the desired pod.
-                                  additionalProperties: true
-                                  x-kubernetes-map-type: "granular"
-                                  default: { }
-                            container:
-                              description: Specifies the container.
-                              default: ""
-                              type: string
-                        exec:
-                          type: object
-                          description: Specifies command to be executed.
-                          properties:
+                                  description: Specifies the pod.
+                                  properties:
+                                    matchLabels:
+                                      type: object
+                                      description: The matchLabels of the desired pod.
+                                      additionalProperties: true
+                                      x-kubernetes-map-type: "granular"
+                                      default: { }
+                                container:
+                                  description: Specifies the container.
+                                  default: ""
+                                  type: string
                             command:
                               type: array
                               description: The command to be executed as string array.
@@ -101,35 +109,59 @@ spec:
                             timeoutSeconds:
                               description: Specifies the timeout (in seconds) for the specified command.
                               type: integer
+                        delete:
+                          type: object
+                          description: Specifies deletion of a resource.
+                          required: [ selector ]
+                          properties:
+                            selector:
+                              type: object
+                              description: Defines how to select the resource to delete.
+                              required: [ apiVersion, kind ]
+                              properties:
+                                apiVersion:
+                                  type: string
+                                  description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.
+                                kind:
+                                  type: string
+                                  description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.
+                                nameRegex:
+                                  type: string
+                                  description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.
+                                  default: "*"
                   afterActions:
                     type: array
-                    default: []
+                    default: [ ]
                     description: Infrastructure after actions are executed after the teardown of the infrastructure.
                     items:
                       type: object
+                      anyOf:
+                        - required: [ exec ]
+                        - required: [ delete ]
                       properties:
-                        selector:
+                        exec:
                           type: object
-                          description: The selector specifies which resource should be selected for the execution of the command.
+                          description: Specifies a command that gets executed within a Container of a Pod
+                          required: [ selector, command, timeoutSeconds ]
                           properties:
-                            pod:
+                            selector:
                               type: object
-                              description: Specifies the pod.
+                              description: The selector specifies which resource should be selected for the execution of the command.
                               properties:
-                                matchLabels:
+                                pod:
                                   type: object
-                                  description: The matchLabels of the desired pod.
-                                  additionalProperties: true
-                                  x-kubernetes-map-type: "granular"
-                                  default: { }
-                            container:
-                              description: Specifies the container.
-                              default: ""
-                              type: string
-                        exec:
-                          type: object
-                          description: Specifies command to be executed.
-                          properties:
+                                  description: Specifies the pod.
+                                  properties:
+                                    matchLabels:
+                                      type: object
+                                      description: The matchLabels of the desired pod.
+                                      additionalProperties: true
+                                      x-kubernetes-map-type: "granular"
+                                      default: { }
+                                container:
+                                  description: Specifies the container.
+                                  default: ""
+                                  type: string
                             command:
                               type: array
                               description: The command to be executed as string array.
@@ -138,6 +170,26 @@ spec:
                             timeoutSeconds:
                               description: Specifies the timeout (in seconds) for the specified command.
                               type: integer
+                        delete:
+                          type: object
+                          description: Specifies deletion of a resource.
+                          required: [ selector ]
+                          properties:
+                            selector:
+                              type: object
+                              description: Defines how to select the resource to delete.
+                              required: [ apiVersion, kind ]
+                              properties:
+                                apiVersion:
+                                  type: string
+                                  description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.
+                                kind:
+                                  type: string
+                                  description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.
+                                nameRegex:
+                                  type: string
+                                  description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.
+                                  default: "*"
               sut:
                 description: The appResourceSets specifies all Kubernetes resources required to start the sut. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet.
                 type: object
@@ -177,33 +229,37 @@ spec:
                                 type: string
                   beforeActions:
                     type: array
-                    default: []
+                    default: [ ]
                     description: SUT before actions are executed before the SUT is started.
                     items:
                       type: object
+                      anyOf:
+                        - required: [ exec ]
+                        - required: [ delete ]
                       properties:
-                        selector:
+                        exec:
                           type: object
-                          description: The selector specifies which resource should be selected for the execution of the command.
+                          description: Specifies a command that gets executed within a Container of a Pod
+                          required: [ selector, command, timeoutSeconds ]
                           properties:
-                            pod:
+                            selector:
                               type: object
-                              description: Specifies the pod.
+                              description: The selector specifies which resource should be selected for the execution of the command.
                               properties:
-                                matchLabels:
+                                pod:
                                   type: object
-                                  description: The matchLabels of the desired pod.
-                                  additionalProperties: true
-                                  x-kubernetes-map-type: "granular"
-                                  default: { }
-                            container:
-                              description: Specifies the container.
-                              default: ""
-                              type: string
-                        exec:
-                          type: object
-                          description: Specifies command to be executed.
-                          properties:
+                                  description: Specifies the pod.
+                                  properties:
+                                    matchLabels:
+                                      type: object
+                                      description: The matchLabels of the desired pod.
+                                      additionalProperties: true
+                                      x-kubernetes-map-type: "granular"
+                                      default: { }
+                                container:
+                                  description: Specifies the container.
+                                  default: ""
+                                  type: string
                             command:
                               type: array
                               description: The command to be executed as string array.
@@ -212,34 +268,59 @@ spec:
                             timeoutSeconds:
                               description: Specifies the timeout (in seconds) for the specified command.
                               type: integer
+                        delete:
+                          type: object
+                          description: Specifies deletion of a resource.
+                          required: [ selector ]
+                          properties:
+                            selector:
+                              type: object
+                              description: Defines how to select the resource to delete.
+                              required: [ apiVersion, kind ]
+                              properties:
+                                apiVersion:
+                                  type: string
+                                  description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.
+                                kind:
+                                  type: string
+                                  description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.
+                                nameRegex:
+                                  type: string
+                                  description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.
+                                  default: "*"
                   afterActions:
                     type: array
-                    default: []
+                    default: [ ]
+                    description: SUT after actions are executed after the teardown of the SUT.
                     items:
                       type: object
+                      anyOf:
+                        - required: [ exec ]
+                        - required: [ delete ]
                       properties:
-                        selector:
+                        exec:
                           type: object
-                          description: The selector specifies which resource should be selected for the execution of the command.
+                          description: Specifies a command that gets executed within a Container of a Pod
+                          required: [ selector, command, timeoutSeconds ]
                           properties:
-                            pod:
+                            selector:
                               type: object
-                              description: Specifies the pod.
+                              description: The selector specifies which resource should be selected for the execution of the command.
                               properties:
-                                matchLabels:
+                                pod:
                                   type: object
-                                  description: The matchLabels of the desired pod.
-                                  additionalProperties: true
-                                  x-kubernetes-map-type: "granular"
-                                  default: { }
-                            container:
-                              description: Specifies the container.
-                              default: ""
-                              type: string
-                        exec:
-                          type: object
-                          description: Specifies command to be executed.
-                          properties:
+                                  description: Specifies the pod.
+                                  properties:
+                                    matchLabels:
+                                      type: object
+                                      description: The matchLabels of the desired pod.
+                                      additionalProperties: true
+                                      x-kubernetes-map-type: "granular"
+                                      default: { }
+                                container:
+                                  description: Specifies the container.
+                                  default: ""
+                                  type: string
                             command:
                               type: array
                               description: The command to be executed as string array.
@@ -248,6 +329,26 @@ spec:
                             timeoutSeconds:
                               description: Specifies the timeout (in seconds) for the specified command.
                               type: integer
+                        delete:
+                          type: object
+                          description: Specifies deletion of a resource.
+                          required: [ selector ]
+                          properties:
+                            selector:
+                              type: object
+                              description: Defines how to select the resource to delete.
+                              required: [ apiVersion, kind ]
+                              properties:
+                                apiVersion:
+                                  type: string
+                                  description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.
+                                kind:
+                                  type: string
+                                  description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.
+                                nameRegex:
+                                  type: string
+                                  description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.
+                                  default: "*"
               loadGenerator:
                 description: The loadGenResourceSets specifies all Kubernetes resources required to start the load generator. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet.
                 type: object
@@ -291,29 +392,33 @@ spec:
                     description: Load generator before actions are executed before the load generator is started.
                     items:
                       type: object
+                      anyOf:
+                        - required: [ exec ]
+                        - required: [ delete ]
                       properties:
-                        selector:
+                        exec:
                           type: object
-                          description: The selector specifies which resource should be selected for the execution of the command.
+                          description: Specifies a command that gets executed within a Container of a Pod
+                          required: [ selector, command, timeoutSeconds ]
                           properties:
-                            pod:
+                            selector:
                               type: object
-                              description: Specifies the pod.
+                              description: The selector specifies which resource should be selected for the execution of the command.
                               properties:
-                                matchLabels:
+                                pod:
                                   type: object
-                                  description: The matchLabels of the desired pod.
-                                  additionalProperties: true
-                                  x-kubernetes-map-type: "granular"
-                                  default: { }
-                            container:
-                              description: Specifies the container.
-                              default: ""
-                              type: string
-                        exec:
-                          type: object
-                          description: Specifies command to be executed.
-                          properties:
+                                  description: Specifies the pod.
+                                  properties:
+                                    matchLabels:
+                                      type: object
+                                      description: The matchLabels of the desired pod.
+                                      additionalProperties: true
+                                      x-kubernetes-map-type: "granular"
+                                      default: { }
+                                container:
+                                  description: Specifies the container.
+                                  default: ""
+                                  type: string
                             command:
                               type: array
                               description: The command to be executed as string array.
@@ -322,35 +427,59 @@ spec:
                             timeoutSeconds:
                               description: Specifies the timeout (in seconds) for the specified command.
                               type: integer
+                        delete:
+                          type: object
+                          description: Specifies deletion of a resource.
+                          required: [ selector ]
+                          properties:
+                            selector:
+                              type: object
+                              description: Defines how to select the resource to delete.
+                              required: [ apiVersion, kind ]
+                              properties:
+                                apiVersion:
+                                  type: string
+                                  description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.
+                                kind:
+                                  type: string
+                                  description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.
+                                nameRegex:
+                                  type: string
+                                  description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.
+                                  default: "*"
                   afterActions:
                     type: array
-                    default: []
+                    default: [ ]
                     description: Load generator after actions are executed after the teardown of the load generator.
                     items:
                       type: object
+                      anyOf:
+                        - required: [ exec ]
+                        - required: [ delete ]
                       properties:
-                        selector:
+                        exec:
                           type: object
-                          description: The selector specifies which resource should be selected for the execution of the command.
+                          description: Specifies a command that gets executed within a Container of a Pod
+                          required: [ selector, command, timeoutSeconds ]
                           properties:
-                            pod:
+                            selector:
                               type: object
-                              description: Specifies the pod.
+                              description: The selector specifies which resource should be selected for the execution of the command.
                               properties:
-                                matchLabels:
+                                pod:
                                   type: object
-                                  description: The matchLabels of the desired pod.
-                                  additionalProperties: true
-                                  x-kubernetes-map-type: "granular"
-                                  default: { }
-                            container:
-                              description: Specifies the container.
-                              default: ""
-                              type: string
-                        exec:
-                          type: object
-                          description: Specifies command to be executed.
-                          properties:
+                                  description: Specifies the pod.
+                                  properties:
+                                    matchLabels:
+                                      type: object
+                                      description: The matchLabels of the desired pod.
+                                      additionalProperties: true
+                                      x-kubernetes-map-type: "granular"
+                                      default: { }
+                                container:
+                                  description: Specifies the container.
+                                  default: ""
+                                  type: string
                             command:
                               type: array
                               description: The command to be executed as string array.
@@ -359,6 +488,26 @@ spec:
                             timeoutSeconds:
                               description: Specifies the timeout (in seconds) for the specified command.
                               type: integer
+                        delete:
+                          type: object
+                          description: Specifies deletion of a resource.
+                          required: [ selector ]
+                          properties:
+                            selector:
+                              type: object
+                              description: Defines how to select the resource to delete.
+                              required: [ apiVersion, kind ]
+                              properties:
+                                apiVersion:
+                                  type: string
+                                  description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.
+                                kind:
+                                    type: string
+                                    description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.
+                                nameRegex:
+                                  type: string
+                                  description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.
+                                  default: "*"
               resourceTypes:
                 description: A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object.
                 type: array
@@ -425,6 +574,31 @@ spec:
                             additionalProperties: true
                             x-kubernetes-map-type: "granular"
                             default: {}
+              slos: # def of service level objectives
+                description: List of resource values for the specified resource type.
+                type: array
+                items:
+                  type: object
+                  required: ["name", "sloType", "prometheusUrl", "offset"]
+                  properties:
+                    name:
+                      description: The name of the SLO.
+                      type: string
+                    sloType:
+                      description: The type of the SLO. It must match 'lag trend'.
+                      type: string
+                    prometheusUrl:
+                      description: Connection string for Promehteus.
+                      type: string
+                    offset:
+                      description: Hours by which the start and end timestamp will be shifted (for different timezones).
+                      type: integer
+                    properties:
+                      description: (Optional) SLO specific additional arguments.
+                      type: object
+                      additionalProperties: true
+                      x-kubernetes-map-type: "granular"
+                      default: { }
               kafkaConfig:
                 description: Contains the Kafka configuration.
                 type: object
diff --git a/theodolite/crd/crd-execution.yaml b/theodolite/crd/crd-execution.yaml
index 92a8ca18d87009143620097caf2abfe8da202c82..0db251864bac3e6f2541534eec8895297b21cf39 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", "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"]
@@ -56,21 +56,15 @@ spec:
                     items:
                       type: integer
               slos: # def of service level objectives
-                description:  List of resource values for the specified resource type.
+                description:  List of SLOs with their properties, which differ from the benchmark definition.
                 type: array
                 items:
                   type: object
-                  required: ["sloType", "prometheusUrl", "offset"]
+                  required: ["name", "properties"]
                   properties:
-                    sloType:
-                      description: The type of the SLO. It must match 'lag trend'.
+                    name:
+                      description: The name of the SLO. It must match a SLO specified in the Benchmark.
                       type: string
-                    prometheusUrl:
-                      description: Connection string for Promehteus.
-                      type: string
-                    offset:
-                      description: Hours by which the start and end timestamp will be shifted (for different timezones).
-                      type: integer
                     properties:
                         description: (Optional) SLO specific additional arguments.
                         type: object
@@ -80,25 +74,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-benchmark.yaml b/theodolite/examples/operator/example-benchmark.yaml
index 62920091e831ff914fb67e85a67cd3f1d98995ab..be7116c46f8222eeba0f3bffd086f7cc2b6ee227 100644
--- a/theodolite/examples/operator/example-benchmark.yaml
+++ b/theodolite/examples/operator/example-benchmark.yaml
@@ -33,6 +33,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "150000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 3000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
diff --git a/theodolite/examples/operator/example-execution.yaml b/theodolite/examples/operator/example-execution.yaml
index 576a74b90dfc38483de79502ac14d42f6bedfb49..87e6275a8409177394dd313f2f1f0436e2162577 100644
--- a/theodolite/examples/operator/example-execution.yaml
+++ b/theodolite/examples/operator/example-execution.yaml
@@ -4,27 +4,25 @@ metadata:
   name: theodolite-example-execution
 spec:
   benchmark: "example-benchmark"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
     resourceType: "Instances"
     resourceValues: [1, 2, 3, 4, 5]
   slos:
-    - sloType: "lag trend"
-      prometheusUrl: "http://prometheus-operated:9090"
-      offset: 0
+    - name: "lag trend"
       properties:
         threshold: 2000
-        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/rocks/theodolite/core/Config.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/Config.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c429d6b3f456c345c7ab2adb1ccd95635603ef4f
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/Config.kt
@@ -0,0 +1,21 @@
+package rocks.theodolite.core
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.strategies.searchstrategy.SearchStrategy
+
+/**
+ * Config class that represents a configuration of a theodolite run.
+ *
+ * @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<Int>,
+        val resources: List<Int>,
+        val searchStrategy: SearchStrategy,
+        val metric: Metric
+)
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/ExecutionRunner.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/ExecutionRunner.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a63269bb8ebb009ecd858be145523c4029814888
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/ExecutionRunner.kt
@@ -0,0 +1,50 @@
+package rocks.theodolite.core
+
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.strategies.searchstrategy.SearchStrategy
+
+
+class ExecutionRunner (private val searchStrategy: SearchStrategy,
+                       private val resources: List<Int>, private val loads: List<Int>,
+                       private val metric: Metric, private val executionId: Int) {
+
+    /**
+     * Run all experiments for given loads and resources.
+     * Called by [rocks.theodolite.kubernetes.execution.TheodoliteExecutor] to run an Execution.
+     */
+    fun run() {
+
+        val ioHandler = IOHandler()
+        val resultsFolder = ioHandler.getResultFolderURL()
+
+        //execute benchmarks for each load for the demand metric, or for each resource amount for capacity metric
+        try {
+            searchStrategy.applySearchStrategyByMetric(loads, resources, metric)
+
+        } finally {
+            ioHandler.writeToJSONFile(
+                    searchStrategy.experimentRunner.results,
+                    "${resultsFolder}exp${executionId}-result"
+            )
+            // Create expXYZ_demand.csv file or expXYZ_capacity.csv depending on metric
+            when(metric) {
+                Metric.DEMAND ->
+                    ioHandler.writeToCSVFile(
+                            "${resultsFolder}exp${executionId}_demand",
+                            calculateMetric(loads, searchStrategy.experimentRunner.results),
+                            listOf("load","resources")
+                    )
+                Metric.CAPACITY ->
+                    ioHandler.writeToCSVFile(
+                            "${resultsFolder}exp${executionId}_capacity",
+                            calculateMetric(resources, searchStrategy.experimentRunner.results),
+                            listOf("resource", "loads")
+                    )
+            }
+        }
+    }
+
+    private fun calculateMetric(xValues: List<Int>, results: Results): List<List<String>> {
+        return xValues.map { listOf(it.toString(), results.getOptYDimensionValue(it).toString()) }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/ExperimentRunner.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/ExperimentRunner.kt
new file mode 100644
index 0000000000000000000000000000000000000000..830469320d98cf66cd9395e3cdf74b2443758c3c
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/ExperimentRunner.kt
@@ -0,0 +1,29 @@
+package rocks.theodolite.core
+
+import java.util.concurrent.atomic.AtomicBoolean
+
+
+/**
+ * Abstract class acts as an interface for the theodolite core to run experiments.
+ * The results of the experiments are stored in [results].
+ *
+ * @property results
+ */
+abstract class ExperimentRunner(val results: Results) {
+
+    var run: AtomicBoolean = AtomicBoolean(true)
+
+    /**
+     * Run an experiment for the given parametrization, evaluate the
+     * experiment and save the result.
+     *
+     * @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 (demand metric), or
+     *     True, if there is a load suitable for the
+     *     given resource, false otherwise.
+     */
+    abstract fun runExperiment(load: Int, resource: Int): Boolean
+
+}
diff --git a/theodolite/src/main/kotlin/theodolite/util/IOHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/IOHandler.kt
similarity index 99%
rename from theodolite/src/main/kotlin/theodolite/util/IOHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/IOHandler.kt
index 8b580c733ab7ae527d99c676223f4b09b392c6fd..4d2cab0da938b18950def8cfb5cc6f104e110125 100644
--- a/theodolite/src/main/kotlin/theodolite/util/IOHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/IOHandler.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.core
 
 import com.google.gson.GsonBuilder
 import mu.KotlinLogging
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/Results.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/Results.kt
new file mode 100644
index 0000000000000000000000000000000000000000..16e6b517e1f570fd17a1b9688aff4f41ec8c9884
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/Results.kt
@@ -0,0 +1,127 @@
+package rocks.theodolite.core
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.core.strategies.Metric
+
+/**
+ * Central class that saves the state of an execution of Theodolite. For an execution, it is used to save the result of
+ * individual experiments. Further, it is used by the RestrictionStrategy to
+ * perform the [theodolite.strategies.restriction.RestrictionStrategy].
+ */
+@RegisterForReflection
+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 and update the [optInstances] list accordingly.
+     *
+     * @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<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 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.
+     *
+     */
+    fun getResult(experiment: Pair<Int, Int>): Boolean? {
+        return this.results[experiment]
+    }
+
+    /**
+     * 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 xValue the Value of the x-dimension of the current metric
+     *
+     * @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 getOptYDimensionValue(xValue: Int?): Int? {
+        if (xValue != null) {
+            val res = optInstances[xValue]
+            if (res != Int.MAX_VALUE && res != Int.MIN_VALUE) {
+                return res
+            }
+        }
+        return null
+    }
+
+    /**
+     * 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 xValue the Value of the x-dimension of the current metric
+     *
+     * @return the largest tested x-Value or null, if there wasn't any tested which is smaller than the [xValue].
+     */
+    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 maxBenchmarkedXValue
+    }
+
+    /**
+     * Checks whether the results are empty.
+     *
+     * @return true if [results] is empty.
+     */
+    fun isEmpty(): Boolean{
+        return results.isEmpty()
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/Metric.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/Metric.kt
new file mode 100644
index 0000000000000000000000000000000000000000..db161d10c61fae512e28ba059e604835d22aeb96
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/Metric.kt
@@ -0,0 +1,11 @@
+package rocks.theodolite.core.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/rocks/theodolite/core/strategies/StrategyFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/StrategyFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d2925c798e29705f3333130e8c9f09e32d7ec31c
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/StrategyFactory.kt
@@ -0,0 +1,84 @@
+package rocks.theodolite.core.strategies
+
+import rocks.theodolite.core.strategies.guessstrategy.PrevInstanceOptGuess
+import rocks.theodolite.core.strategies.restrictionstrategy.LowerBoundRestriction
+import rocks.theodolite.core.strategies.restrictionstrategy.RestrictionStrategy
+import rocks.theodolite.core.strategies.searchstrategy.*
+import rocks.theodolite.core.ExperimentRunner
+import rocks.theodolite.core.Results
+
+/**
+ * Factory for creating [SearchStrategy] and [RestrictionStrategy] strategies.
+ */
+class StrategyFactory {
+
+    /**
+     * Create a [SearchStrategy].
+     *
+     * @param executor The [theodolite.execution.BenchmarkExecutor] that executes individual experiments.
+     * @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: ExperimentRunner, name: String, searchStrategy: String, restrictions: List<String>,
+                             guessStrategy: String, results: Results): SearchStrategy {
+
+        var strategy : SearchStrategy = when (name) {
+            "FullSearch" -> FullSearch(executor)
+            "LinearSearch" -> LinearSearch(executor)
+            "BinarySearch" -> BinarySearch(executor)
+            "RestrictionSearch" -> when (searchStrategy){
+                "FullSearch" -> composeSearchRestrictionStrategy(executor, FullSearch(executor), results, restrictions)
+                "LinearSearch" -> composeSearchRestrictionStrategy(executor, LinearSearch(executor), results, restrictions)
+                "BinarySearch" -> composeSearchRestrictionStrategy(executor, BinarySearch(executor), results, restrictions)
+                else -> throw IllegalArgumentException("Search Strategy $searchStrategy for RestrictionSearch not found")
+            }
+            "InitialGuessSearch" -> when (guessStrategy){
+                "PrevResourceMinGuess" -> InitialGuessSearchStrategy(executor, PrevInstanceOptGuess(), results)
+                else -> throw IllegalArgumentException("Guess Strategy $guessStrategy not found")
+            }
+            else -> throw IllegalArgumentException("Search Strategy not found")
+        }
+
+        return strategy
+    }
+
+    /**
+     * Create a [RestrictionStrategy].
+     *
+     * @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 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.
+     */
+    private fun createRestrictionStrategy(results: Results, restrictionStrings: List<String>): Set<RestrictionStrategy> {
+        return restrictionStrings
+            .map { restriction ->
+                when (restriction) {
+                    "LowerBound" -> LowerBoundRestriction(results)
+                    else -> throw IllegalArgumentException("Restriction Strategy $restrictionStrings not found")
+                }
+            }.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: ExperimentRunner, 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/rocks/theodolite/core/strategies/guessstrategy/GuessStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/GuessStrategy.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6ab5c1b6d10da318c4b5b3f24d6cc521ff247e79
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/GuessStrategy.kt
@@ -0,0 +1,22 @@
+package rocks.theodolite.core.strategies.guessstrategy
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+
+/**
+ * Base class for the implementation of Guess strategies. Guess strategies are strategies to determine the resource
+ * demand (demand metric) or load (capacity metric) we start with in our initial guess search strategy.
+ */
+
+@RegisterForReflection
+abstract class GuessStrategy {
+    /**
+     * Computing the resource demand (demand metric) or load (capacity metric) for the initial guess search strategy
+     * to start with.
+     *
+     * @param valuesToCheck List of all possible resources/loads.
+     * @param lastOptValue Previous minimal/maximal resource/load value for the given load/resource.
+     *
+     * @return the resource/load to start the initial guess search strategy with or null
+     */
+    abstract fun firstGuess(valuesToCheck: List<Int>, lastOptValue: Int?): Int?
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/PrevInstanceOptGuess.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/PrevInstanceOptGuess.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3b2d7b1b0e6c4133b939742a83afc55fabb7b101
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/PrevInstanceOptGuess.kt
@@ -0,0 +1,28 @@
+package rocks.theodolite.core.strategies.guessstrategy
+
+
+/**
+ * [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/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestriction.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestriction.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2e5a51018fd742abbb18edb1d788a6644e94d2f1
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestriction.kt
@@ -0,0 +1,24 @@
+package rocks.theodolite.core.strategies.restrictionstrategy
+
+import rocks.theodolite.core.Results
+
+/**
+ * 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(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 = yValues[0]
+        }
+        return yValues.filter { x -> x >= lowerBound }
+    }
+
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/RestrictionStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/RestrictionStrategy.kt
new file mode 100644
index 0000000000000000000000000000000000000000..16532c32e2c9c64ac69d1c5ed32f6ec0d3345747
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/RestrictionStrategy.kt
@@ -0,0 +1,24 @@
+package rocks.theodolite.core.strategies.restrictionstrategy
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.core.Results
+
+/**
+ * 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
+ */
+@RegisterForReflection
+abstract class RestrictionStrategy(val results: Results) {
+    /**
+     * 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 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(xValue: Int, yValues: List<Int>): List<Int>
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/BinarySearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/BinarySearch.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7c339c449e85a0fa73484d60a455016931cee473
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/BinarySearch.kt
@@ -0,0 +1,108 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import mu.KotlinLogging
+import rocks.theodolite.core.ExperimentRunner
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ *  Binary-search-like implementation for determining the smallest suitable number of instances.
+ *
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
+ */
+class BinarySearch(experimentRunner: ExperimentRunner) : SearchStrategy(experimentRunner) {
+    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 for the demand metric.
+     *
+     * @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 binarySearchDemand(load: Int, resources: List<Int>, lower: Int, upper: Int): Int {
+        if (lower > upper) {
+            throw IllegalArgumentException()
+        }
+        // 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' and resource '$res'" }
+            if (this.experimentRunner.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]`
+            val mid = (upper + lower) / 2
+            val res = resources[mid]
+            logger.info { "Running experiment with load '$load' and resource '$res'" }
+            if (this.experimentRunner.runExperiment(load, res)) {
+                // case length = 2
+                if (mid == lower) {
+                    return lower
+                }
+                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.experimentRunner.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.experimentRunner.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 binarySearchCapacity(resource, loads, lower, mid - 1)
+            }
+        }
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/FullSearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/FullSearch.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7cd1dfe08cfef7ea42f0a663bbc80eb63f8ca9fe
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/FullSearch.kt
@@ -0,0 +1,39 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import mu.KotlinLogging
+import rocks.theodolite.core.ExperimentRunner
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ * [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 the desired resource (demand) or load (capacity) is found.
+ *
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
+ */
+class FullSearch(experimentRunner: ExperimentRunner) : SearchStrategy(experimentRunner) {
+
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
+        var minimalSuitableResources: Int? = null
+        for (res in resources) {
+            logger.info { "Running experiment with load '$load' and resources '$res'" }
+            val result = this.experimentRunner.runExperiment(load, res)
+            if (result && minimalSuitableResources == null) {
+                minimalSuitableResources = res
+            }
+        }
+        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.experimentRunner.runExperiment(load, resource)) maxSuitableLoad = load
+        }
+        return maxSuitableLoad
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategy.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8d257bb329729cab033e10195e7a9df3260aeeb3
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategy.kt
@@ -0,0 +1,133 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import mu.KotlinLogging
+import rocks.theodolite.core.strategies.guessstrategy.GuessStrategy
+import rocks.theodolite.core.ExperimentRunner
+import rocks.theodolite.core.Results
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ *  Search strategy implementation for determining the smallest suitable resource demand.
+ *  Starting with a resource amount provided by a guess strategy.
+ *
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
+ * @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(
+        experimentRunner: ExperimentRunner,
+        private val guessStrategy: GuessStrategy,
+        private var results: Results
+) : SearchStrategy(experimentRunner) {
+
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
+
+        var lastLowestResource : Int? = null
+
+        // Getting the lastLowestResource from results and calling firstGuess() with it
+        if (!results.isEmpty()) {
+            val maxLoad: Int? = this.results.getMaxBenchmarkedXDimensionValue(load)
+            lastLowestResource = this.results.getOptYDimensionValue(maxLoad)
+        }
+        lastLowestResource = this.guessStrategy.firstGuess(resources, lastLowestResource)
+
+        if (lastLowestResource != null) {
+            val resourcesToCheck: List<Int>
+            val startIndex: Int = resources.indexOf(lastLowestResource)
+
+            logger.info { "Running experiment with load '$load' and resources '$lastLowestResource'" }
+
+            // If the first experiment passes, starting downward linear search
+            // otherwise starting upward linear search
+            if (this.experimentRunner.runExperiment(load, lastLowestResource)) {
+
+                resourcesToCheck = resources.subList(0, startIndex).reversed()
+                if (resourcesToCheck.isEmpty()) return lastLowestResource
+
+                var currentMin: Int = lastLowestResource
+                for (res in resourcesToCheck) {
+
+                    logger.info { "Running experiment with load '$load' and resources '$res'" }
+                    if (this.experimentRunner.runExperiment(load, res)) {
+                        currentMin = res
+                    }
+                }
+                return currentMin
+            }
+            else {
+                if (resources.size <= startIndex + 1) {
+                    logger.info{ "No more resources left to check." }
+                    return null
+                }
+                resourcesToCheck = resources.subList(startIndex + 1, resources.size)
+
+                for (res in resourcesToCheck) {
+
+                    logger.info { "Running experiment with load '$load' and resources '$res'" }
+                    if (this.experimentRunner.runExperiment(load, res)) return res
+                }
+            }
+        }
+        else {
+            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.experimentRunner.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.experimentRunner.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.experimentRunner.runExperiment(load, resource)) {
+                        currentMax = load
+                    }
+                }
+                return currentMax
+            }
+        }
+        else {
+            logger.info { "lastMaxLoad was null." }
+        }
+        return null
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/LinearSearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/LinearSearch.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c3276f05e141d15652012952991a47a1fde30ad4
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/LinearSearch.kt
@@ -0,0 +1,34 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import mu.KotlinLogging
+import rocks.theodolite.core.ExperimentRunner
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ *  Linear-search-like implementation for determining the smallest/biggest suitable number of resources/loads,
+ *  depending on the metric.
+ *
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
+ */
+class LinearSearch(experimentRunner: ExperimentRunner) : SearchStrategy(experimentRunner) {
+
+    override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
+        for (res in resources) {
+            logger.info { "Running experiment with load '$load' and resources '$res'" }
+            if (this.experimentRunner.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.experimentRunner.runExperiment(load, resource)) {
+                maxSuitableLoad = load
+            } else break
+        }
+        return maxSuitableLoad
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearch.kt
new file mode 100644
index 0000000000000000000000000000000000000000..703a7de8b9e084b2bb55bc9270b9d07ea6adfe83
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearch.kt
@@ -0,0 +1,43 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.core.strategies.restrictionstrategy.RestrictionStrategy
+import rocks.theodolite.core.ExperimentRunner
+
+/**
+ *  Strategy that combines a SearchStrategy and a set of RestrictionStrategy.
+ *
+ * @param experimentRunner 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(
+        experimentRunner: ExperimentRunner,
+        private val searchStrategy: SearchStrategy,
+        private val restrictionStrategies: Set<RestrictionStrategy>
+) : SearchStrategy(experimentRunner) {
+
+    /**
+     * 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/rocks/theodolite/core/strategies/searchstrategy/SearchStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/SearchStrategy.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d08581ff70c509f54a9b8e5f972bb3661cb0b8f8
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/SearchStrategy.kt
@@ -0,0 +1,63 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.ExperimentRunner
+
+/**
+ *  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 experimentRunner 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 experimentRunner: ExperimentRunner) {
+
+
+    /**
+     * 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 (experimentRunner.run.get()) {
+                        this.findSuitableResource(load, resources)
+                    }
+                }
+            Metric.CAPACITY ->
+                for (resource in resources) {
+                    if (experimentRunner.run.get()) {
+                        this.findSuitableLoad(resource, loads)
+                    }
+                }
+        }
+    }
+
+    /**
+     * Find the smallest suitable resource from the specified resource list for the given load.
+     *
+     * @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: 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/rocks/theodolite/kubernetes/Action.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt
new file mode 100644
index 0000000000000000000000000000000000000000..bdabb719672abf2975fdf8a0ad59868bbc6c1edf
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt
@@ -0,0 +1,31 @@
+package rocks.theodolite.kubernetes
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import io.quarkus.runtime.annotations.RegisterForReflection
+
+@JsonDeserialize
+@RegisterForReflection
+@JsonInclude(JsonInclude.Include.NON_NULL)
+class Action {
+
+    @JsonProperty("exec")
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    var execCommand: ExecCommand? = null
+    @JsonProperty("delete")
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    var deleteCommand: DeleteCommand? = null
+
+    fun exec(client: NamespacedKubernetesClient) {
+        return if (execCommand != null) {
+            execCommand?.exec(client= client) !!
+        } else if (deleteCommand != null) {
+            deleteCommand?.exec(client= client ) !!
+        } else {
+            throw DeploymentFailedException("Could not execute action. The action type must either be 'exec' or 'delete'.")
+        }
+    }
+
+}
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt
similarity index 98%
rename from theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt
index 9f0578f7d1456d823a29049daae6dbe886c95e2a..eefacbea9268f44969fd88d7650d5ddc5e00fb8e 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommand.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.api.model.Status
 import io.fabric8.kubernetes.client.KubernetesClientException
@@ -7,8 +7,6 @@ import io.fabric8.kubernetes.client.dsl.ExecListener
 import io.fabric8.kubernetes.client.dsl.ExecWatch
 import io.fabric8.kubernetes.client.utils.Serialization
 import mu.KotlinLogging
-import theodolite.util.ActionCommandFailedException
-import theodolite.util.Configuration
 import java.io.ByteArrayOutputStream
 import java.time.Duration
 import java.util.concurrent.CountDownLatch
diff --git a/theodolite/src/main/kotlin/theodolite/util/ActionCommandFailedException.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommandFailedException.kt
similarity index 76%
rename from theodolite/src/main/kotlin/theodolite/util/ActionCommandFailedException.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommandFailedException.kt
index c1a8fc401961370d2f07bfffe43f0ae4dc441d25..8472b0cc9b46a952dbeb14eb73093c821cd6ed57 100644
--- a/theodolite/src/main/kotlin/theodolite/util/ActionCommandFailedException.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ActionCommandFailedException.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes
 
 class ActionCommandFailedException(message: String, e: Exception? = null) : DeploymentFailedException(message,e) {
 }
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkDeployment.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/BenchmarkDeployment.kt
similarity index 93%
rename from theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkDeployment.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/BenchmarkDeployment.kt
index fd01ecd986775ef704949743fef0d19f5492e9a6..df303b3b85175d6133e8bc9e7a2748cf8c46464c 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkDeployment.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/BenchmarkDeployment.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 /**
  *  A BenchmarkDeployment contains the necessary infrastructure to execute a benchmark.
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/BenchmarkDeploymentBuilder.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/BenchmarkDeploymentBuilder.kt
new file mode 100644
index 0000000000000000000000000000000000000000..544f8bd5ae227ca682e688dff9fc9df0efec60c3
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/BenchmarkDeploymentBuilder.kt
@@ -0,0 +1,25 @@
+package rocks.theodolite.kubernetes
+
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
+
+/**
+ * This interface is needed for test purposes.
+ */
+interface BenchmarkDeploymentBuilder {
+
+    /**
+     * Builds a Deployment that can be deployed.
+     * @return a BenchmarkDeployment.
+     */
+    fun buildDeployment(
+        load: Int,
+        loadPatcherDefinitions: List<PatcherDefinition>,
+        resource: Int,
+        resourcePatcherDefinitions: List<PatcherDefinition>,
+        configurationOverrides: List<ConfigurationOverride?>,
+        loadGenerationDelay: Long,
+        afterTeardownDelay: Long,
+        waitForResourcesEnabled: Boolean
+    ): BenchmarkDeployment
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt
index eea5b15cb1db7242328033a1bc46fb224d287bc2..43c478b983d879135b00e6208df8bb36b7978c8f 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSet.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.HasMetadata
@@ -6,7 +6,6 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.client.KubernetesClientException
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.DeploymentFailedException
 import java.lang.IllegalArgumentException
 
 @RegisterForReflection
diff --git a/theodolite/src/main/kotlin/theodolite/util/Configuration.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Configuration.kt
similarity index 90%
rename from theodolite/src/main/kotlin/theodolite/util/Configuration.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Configuration.kt
index 0a63cfa84de9e60fba04707372ef884d77a1543b..e28e2a2a7644222f656bdebd05d122cd853ac456 100644
--- a/theodolite/src/main/kotlin/theodolite/util/Configuration.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Configuration.kt
@@ -1,6 +1,4 @@
-package theodolite.util
-
-import theodolite.execution.ExecutionModes
+package rocks.theodolite.kubernetes
 
 // Defaults
 private const val DEFAULT_NAMESPACE = "default"
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ef4409e5bdebfa8b232d5ed1080e93571cbaa618
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt
@@ -0,0 +1,49 @@
+package rocks.theodolite.kubernetes
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import io.fabric8.kubernetes.client.KubernetesClientException
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import io.quarkus.runtime.annotations.RegisterForReflection
+import mu.KotlinLogging
+
+private val logger = KotlinLogging.logger {}
+
+@JsonDeserialize
+@RegisterForReflection
+@JsonInclude(JsonInclude.Include.NON_NULL)
+class DeleteCommand {
+
+    lateinit var selector: DeleteActionSelector
+
+    fun exec(client: NamespacedKubernetesClient) {
+        logger.info { "Deleting all resources with apiVersion ${selector.apiVersion} and Kind ${selector.kind} matching regular expression ${selector.nameRegex}" }
+        val regExp = selector.nameRegex.toRegex()
+        val k8sManager = K8sManager(client)
+        client
+            .genericKubernetesResources(selector.apiVersion, selector.kind)
+            .inNamespace(client.namespace)
+            .list()
+            .items
+            .filter { regExp.matches(it.metadata.name) }
+            .forEach{
+                logger.info { "Deleting resource ${it.metadata.name} of Kind ${it.kind} and api/version ${it.apiVersion}." }
+                try {
+                    k8sManager.remove(it)
+                } catch (e: KubernetesClientException) {
+                    logger.error { "An error occured when deleting resource ${it.metadata.name} of Kind ${it.kind} and api/version ${it.apiVersion}. Error: ${e.message}"}
+                }
+            }
+    }
+}
+
+@JsonDeserialize
+@RegisterForReflection
+class DeleteActionSelector {
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    lateinit var apiVersion: String
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    lateinit var kind: String
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    lateinit var nameRegex: String
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeploymentFailedException.kt
similarity index 75%
rename from theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeploymentFailedException.kt
index 9f4caedf3db1e09dca7924bf0035c6ace0b835d7..cde0021255b471354e8513139cad0f6e083f804a 100644
--- a/theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeploymentFailedException.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes
 
 
 open class DeploymentFailedException(message: String, e: Exception? = null) : TheodoliteException(message,e)
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt
similarity index 72%
rename from theodolite/src/main/kotlin/theodolite/benchmark/Action.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt
index 8bd16d04d6a5e5ef3f362ff7d5611bf73e367a7e..b8ce10efcd3e4fb5ea552aa7f922fd81c5c13656 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt
@@ -1,28 +1,25 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.annotation.JsonInclude
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.ActionCommandFailedException
-import theodolite.util.Configuration
 
 @JsonDeserialize
 @RegisterForReflection
 @JsonInclude(JsonInclude.Include.NON_NULL)
-class Action {
-
-    lateinit var selector: ActionSelector
-    lateinit var exec: Command
-
+class ExecCommand {
+    lateinit var selector: ExecActionSelector
+    lateinit var command: Array<String>
+    var timeoutSeconds: Long = Configuration.TIMEOUT_SECONDS
     fun exec(client: NamespacedKubernetesClient) {
         val exitCode = ActionCommand(client = client)
             .exec(
                 matchLabels = selector.pod.matchLabels,
                 container = selector.container,
-                timeout = exec.timeoutSeconds,
-                command = exec.command
-        )
+                timeout = timeoutSeconds,
+                command = command
+            )
         if (exitCode != 0){
             throw ActionCommandFailedException("Error while executing action, finished with exit code $exitCode")
         }
@@ -31,18 +28,14 @@ class Action {
 
 @JsonDeserialize
 @RegisterForReflection
-class ActionSelector {
+class ExecActionSelector {
+    @JsonInclude(JsonInclude.Include.NON_NULL)
     lateinit var pod: PodSelector
+    @JsonInclude(JsonInclude.Include.NON_NULL)
     var container: String = ""
 }
 @JsonDeserialize
 @RegisterForReflection
 class PodSelector {
     lateinit var matchLabels: Map<String, String>
-}
-@JsonDeserialize
-@RegisterForReflection
-class Command {
-    lateinit var command: Array<String>
-    var timeoutSeconds: Long = Configuration.TIMEOUT_SECONDS
 }
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/util/ExecutionFailedException.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecutionFailedException.kt
similarity index 75%
rename from theodolite/src/main/kotlin/theodolite/util/ExecutionFailedException.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecutionFailedException.kt
index 2e181dad35786d386226f8a57dfffbc2c3966754..8924dd18199e0ff937c783873878c6f245d01ea5 100644
--- a/theodolite/src/main/kotlin/theodolite/util/ExecutionFailedException.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecutionFailedException.kt
@@ -1,3 +1,3 @@
-package theodolite.util
+package rocks.theodolite.kubernetes
 
 open class ExecutionFailedException(message: String, e: Exception? = null) : TheodoliteException(message,e)
diff --git a/theodolite/src/main/kotlin/theodolite/execution/ExecutionModes.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecutionModes.kt
similarity index 74%
rename from theodolite/src/main/kotlin/theodolite/execution/ExecutionModes.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecutionModes.kt
index 370b87e062d942a512e059ee4041dca776376ddf..e8e4b642689c455b7be6c32d0bdedad58861238c 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/ExecutionModes.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecutionModes.kt
@@ -1,4 +1,4 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes
 
 enum class ExecutionModes(val value: String) {
     OPERATOR("operator"),
diff --git a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
similarity index 52%
rename from theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
index 2e938be3a6e503a5e7e3f94c18a9454e173db5b0..e1ce46ea24fc97bb7b0421b8e3507c8e989d654a 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
@@ -1,57 +1,53 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes
 
 import io.quarkus.runtime.annotations.RegisterForReflection
 import mu.KotlinLogging
-import theodolite.benchmark.Benchmark
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.evaluation.AnalysisExecutor
-import theodolite.execution.operator.EventCreator
-import theodolite.util.*
+import rocks.theodolite.core.ExperimentRunner
+import rocks.theodolite.core.Results
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
+import rocks.theodolite.kubernetes.operator.EventCreator
+import rocks.theodolite.kubernetes.slo.AnalysisExecutor
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
 import java.time.Duration
 import java.time.Instant
 
 private val logger = KotlinLogging.logger {}
 
 @RegisterForReflection
-class BenchmarkExecutorImpl(
-    benchmark: Benchmark,
+class ExperimentRunnerImpl(
     results: Results,
-    executionDuration: Duration,
-    configurationOverrides: List<ConfigurationOverride?>,
-    slos: List<BenchmarkExecution.Slo>,
-    repetitions: Int,
-    executionId: Int,
-    loadGenerationDelay: Long,
-    afterTeardownDelay: Long,
-    executionName: String
-) : BenchmarkExecutor(
-    benchmark,
-    results,
-    executionDuration,
-    configurationOverrides,
-    slos,
-    repetitions,
-    executionId,
-    loadGenerationDelay,
-    afterTeardownDelay,
-    executionName
+    private val benchmarkDeploymentBuilder: BenchmarkDeploymentBuilder,
+    private val executionDuration: Duration,
+    private val configurationOverrides: List<ConfigurationOverride?>,
+    private val slos: List<Slo>,
+    private val repetitions: Int,
+    private val executionId: Int,
+    private val loadGenerationDelay: Long,
+    private val afterTeardownDelay: Long,
+    private val executionName: String,
+    private val loadPatcherDefinitions: List<PatcherDefinition>,
+    private val resourcePatcherDefinitions: List<PatcherDefinition>,
+    private val waitForResourcesEnabled: Boolean
+) : ExperimentRunner(
+    results
 ) {
     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,41 +56,44 @@ 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> {
-        val benchmarkDeployment = benchmark.buildDeployment(
+    private fun runSingleExperiment(load: Int, resource: Int): Pair<Instant, Instant> {
+        val benchmarkDeployment = benchmarkDeploymentBuilder.buildDeployment(
             load,
-            res,
+            this.loadPatcherDefinitions,
+            resource,
+            this.resourcePatcherDefinitions,
             this.configurationOverrides,
             this.loadGenerationDelay,
-            this.afterTeardownDelay
+            this.afterTeardownDelay,
+            this.waitForResourcesEnabled
         )
-        val from = Instant.now()
+        val from: Instant
 
         try {
             benchmarkDeployment.setup()
+            from = Instant.now()
+
             this.waitAndLog()
             if (mode == ExecutionModes.OPERATOR.value) {
                 eventCreator.createEvent(
                     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 +103,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)
         }
@@ -130,4 +129,25 @@ class BenchmarkExecutorImpl(
         }
         return Pair(from, to)
     }
+
+    /**
+     * Wait while the benchmark is running and log the number of minutes executed every 1 minute.
+     */
+    fun waitAndLog() {
+        logger.info { "Execution of a new experiment started." }
+
+        var secondsRunning = 0L
+
+        while (run.get() && secondsRunning < executionDuration.toSeconds()) {
+            secondsRunning++
+            Thread.sleep(Duration.ofSeconds(1).toMillis())
+
+            if ((secondsRunning % 60) == 0L) {
+                logger.info { "Executed: ${secondsRunning / 60} minutes." }
+            }
+        }
+
+        logger.debug { "Executor shutdown gracefully." }
+
+    }
 }
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt
index e95a637ab88f11902062de73b0c34603b08aded3..44dacc044e2af477814be0399d23a5b14818bcee 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSet.kt
@@ -1,11 +1,10 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.DeploymentFailedException
 import java.io.BufferedReader
 import java.io.FileInputStream
 import java.io.FileNotFoundException
diff --git a/theodolite/src/main/kotlin/theodolite/k8s/K8sContextFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sContextFactory.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/k8s/K8sContextFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sContextFactory.kt
index 38224f26a38a241e92b38e8b92a7fa5b4e198f5e..880449d1952247bd7bf1784e083acc14ee59fea5 100644
--- a/theodolite/src/main/kotlin/theodolite/k8s/K8sContextFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sContextFactory.kt
@@ -1,4 +1,4 @@
-package theodolite.k8s
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext
 
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7856451edf4c31d668288f618fcee46b7246a619
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt
@@ -0,0 +1,51 @@
+package rocks.theodolite.kubernetes
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import mu.KotlinLogging
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ * This class is used to deploy or remove different Kubernetes resources.
+ * Supports: Deployments, Services, ConfigMaps, StatefulSets, and CustomResources.
+ * @param client KubernetesClient used to deploy or remove.
+ */
+class K8sManager(private val client: NamespacedKubernetesClient) {
+
+    /**
+     * Deploys different k8s resources using the client.
+     * @throws IllegalArgumentException if KubernetesResource not supported.
+     */
+    fun deploy(resource: HasMetadata) {
+        client.resource(resource).createOrReplace()
+    }
+
+    /**
+     * Removes different k8s resources using the client.
+     * @throws KubernetesClientException if an error occurs in the underlying NamespacedKubernetesClient when deleting the resource.
+     */
+    fun remove(resource: HasMetadata,  blockUntilDeleted: Boolean = true) {
+        client.resource(resource).delete()
+        if(blockUntilDeleted) {
+            when (resource) {
+                is Deployment -> {
+                    ResourceByLabelHandler(client = client)
+                        .blockUntilPodsDeleted(
+                            matchLabels = resource.spec.selector.matchLabels
+                        )
+                    logger.info { "Deployment '${resource.metadata.name}' deleted." }
+                }
+                is StatefulSet -> {
+                    ResourceByLabelHandler(client = client)
+                        .blockUntilPodsDeleted(
+                            matchLabels = resource.spec.selector.matchLabels
+                        )
+                    logger.info { "StatefulSet '$resource.metadata.name' deleted." }
+                }
+            }
+        }
+    }
+}
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeployment.kt
similarity index 74%
rename from theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeployment.kt
index b30032c524b1e421301e0e9d1ffe83772b43d900..28ac651a043134d061123956cea0cfc6d9535ce6 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeployment.kt
@@ -1,15 +1,16 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.KubernetesResource
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
 import mu.KotlinLogging
 import org.apache.kafka.clients.admin.NewTopic
-import theodolite.k8s.K8sManager
-import theodolite.k8s.ResourceByLabelHandler
-import theodolite.k8s.TopicManager
-import theodolite.util.KafkaConfig
+import rocks.theodolite.kubernetes.kafka.TopicManager
+import rocks.theodolite.kubernetes.model.crd.KafkaConfig
+import theodolite.benchmark.RolloutManager
 import java.time.Duration
 
 private val logger = KotlinLogging.logger {}
@@ -28,6 +29,7 @@ class KubernetesBenchmarkDeployment(
     private val sutAfterActions: List<Action>,
     private val loadGenBeforeActions: List<Action>,
     private val loadGenAfterActions: List<Action>,
+    private val rolloutMode: Boolean,
     val appResources: List<HasMetadata>,
     val loadGenResources: List<HasMetadata>,
     private val loadGenerationDelay: Long,
@@ -41,25 +43,28 @@ class KubernetesBenchmarkDeployment(
     private val LAG_EXPORTER_POD_LABEL_NAME = "app.kubernetes.io/name"
     private val LAG_EXPORTER_POD_LABEL_VALUE = "kafka-exporter"
 
+
+
     /**
      * Setup a [KubernetesBenchmark] using the [TopicManager] and the [K8sManager]:
      *  - Create the needed topics.
      *  - Deploy the needed resources.
      */
     override fun setup() {
+        val rolloutManager = RolloutManager(rolloutMode, client)
         if (this.topics.isNotEmpty()) {
             val kafkaTopics = this.topics
                 .filter { !it.removeOnly }
                 .map { NewTopic(it.name, it.numPartitions, it.replicationFactor) }
             kafkaController.createTopics(kafkaTopics)
         }
+
         sutBeforeActions.forEach { it.exec(client = client) }
-        appResources.forEach { kubernetesManager.deploy(it) }
+        rolloutManager.rollout(appResources)
         logger.info { "Wait ${this.loadGenerationDelay} seconds before starting the load generator." }
         Thread.sleep(Duration.ofSeconds(this.loadGenerationDelay).toMillis())
         loadGenBeforeActions.forEach { it.exec(client = client) }
-        loadGenResources.forEach { kubernetesManager.deploy(it) }
-
+        rolloutManager.rollout(loadGenResources)
     }
 
     /**
@@ -69,14 +74,25 @@ class KubernetesBenchmarkDeployment(
      *  - Remove the [KubernetesResource]s.
      */
     override fun teardown() {
-        loadGenResources.forEach { kubernetesManager.remove(it) }
+        val podCleaner = ResourceByLabelHandler(client)
+        loadGenResources.forEach { kubernetesManager.remove(it, false) }
         loadGenAfterActions.forEach { it.exec(client = client) }
-        appResources.forEach { kubernetesManager.remove(it) }
+        appResources.forEach { kubernetesManager.remove(it,false) }
         sutAfterActions.forEach { it.exec(client = client) }
         if (this.topics.isNotEmpty()) {
             kafkaController.removeTopics(this.topics.map { topic -> topic.name })
         }
-        ResourceByLabelHandler(client).removePods(
+
+        listOf(loadGenResources, appResources)
+            .forEach {
+                if (it is Deployment) {
+                    podCleaner.blockUntilPodsDeleted(it.spec.selector.matchLabels)
+                } else if (it is StatefulSet) {
+                    podCleaner.blockUntilPodsDeleted(it.spec.selector.matchLabels)
+                }
+            }
+
+        podCleaner.removePods(
             labelName = LAG_EXPORTER_POD_LABEL_NAME,
             labelValue = LAG_EXPORTER_POD_LABEL_VALUE
         )
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeploymentBuilder.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeploymentBuilder.kt
new file mode 100644
index 0000000000000000000000000000000000000000..67fe92afb8aa4c9edda2474fc6307c16c21a41f6
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeploymentBuilder.kt
@@ -0,0 +1,92 @@
+package rocks.theodolite.kubernetes
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import mu.KotlinLogging
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.patcher.PatchHandler
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
+
+private val logger = KotlinLogging.logger {}
+
+class KubernetesBenchmarkDeploymentBuilder (val kubernetesBenchmark: KubernetesBenchmark,
+                                            private var client: NamespacedKubernetesClient)
+    : BenchmarkDeploymentBuilder {
+
+
+    /**
+     * Builds a deployment.
+     * 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: Int,
+            loadPatcherDefinitions: List<PatcherDefinition>,
+            resource: Int,
+            resourcePatcherDefinitions: List<PatcherDefinition>,
+            configurationOverrides: List<ConfigurationOverride?>,
+            loadGenerationDelay: Long,
+            afterTeardownDelay: Long,
+            waitForResourcesEnabled: Boolean
+    ): BenchmarkDeployment {
+        logger.info { "Using ${this.client.namespace} as namespace." }
+
+        val appResources = loadKubernetesResources(kubernetesBenchmark.sut.resources, this.client).toResourceMap()
+        val loadGenResources = loadKubernetesResources(kubernetesBenchmark.loadGenerator.resources, this.client).toResourceMap()
+
+        // patch the load dimension the resources
+        loadPatcherDefinitions.forEach { patcherDefinition ->
+            loadGenResources[patcherDefinition.resource] =
+                PatchHandler.patchResource(loadGenResources, patcherDefinition, load.toString())
+        }
+        resourcePatcherDefinitions.forEach { patcherDefinition ->
+            appResources[patcherDefinition.resource] =
+                PatchHandler.patchResource(appResources, patcherDefinition, resource.toString())
+        }
+
+        // Patch the given overrides
+        configurationOverrides.forEach { override ->
+            override?.let {
+                if (appResources.keys.contains(it.patcher.resource)) {
+                    appResources[it.patcher.resource] =
+                        PatchHandler.patchResource(appResources, override.patcher, override.value)
+                } else {
+                    loadGenResources[it.patcher.resource] =
+                        PatchHandler.patchResource(loadGenResources, override.patcher, override.value)
+                }
+            }
+        }
+
+        val kafkaConfig = kubernetesBenchmark.kafkaConfig
+
+        return KubernetesBenchmarkDeployment(
+                sutBeforeActions = kubernetesBenchmark.sut.beforeActions,
+                sutAfterActions = kubernetesBenchmark.sut.afterActions,
+                loadGenBeforeActions = kubernetesBenchmark.loadGenerator.beforeActions,
+                loadGenAfterActions = kubernetesBenchmark.loadGenerator.afterActions,
+                appResources = appResources.toList().flatMap { it.second },
+                loadGenResources = loadGenResources.toList().flatMap { it.second },
+                loadGenerationDelay = loadGenerationDelay,
+                afterTeardownDelay = afterTeardownDelay,
+                kafkaConfig = if (kafkaConfig != null) mapOf("bootstrap.servers" to kafkaConfig.bootstrapServer) else mapOf(),
+                topics = kafkaConfig?.topics ?: listOf(),
+                client = this.client,
+                rolloutMode = waitForResourcesEnabled
+        )
+    }
+
+}
+
+private fun Collection<Pair<String, HasMetadata>>.toResourceMap(): MutableMap<String, List<HasMetadata>> {
+    return this.toMap()
+        .toMutableMap()
+        .map { Pair(it.key, listOf(it.value)) }
+        .toMap()
+        .toMutableMap()
+}
diff --git a/theodolite/src/main/kotlin/theodolite/execution/Main.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt
similarity index 57%
rename from theodolite/src/main/kotlin/theodolite/execution/Main.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt
index 17b3d4e7b86f9e430abfb6093e79aa7865cd5923..cbd7c3106b39c4571d559d4071cd4ac16e180bc8 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/Main.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt
@@ -1,9 +1,11 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes
 
+import io.fabric8.kubernetes.client.DefaultKubernetesClient
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.QuarkusMain
 import mu.KotlinLogging
-import theodolite.execution.operator.TheodoliteOperator
-import theodolite.util.Configuration
+import rocks.theodolite.kubernetes.operator.TheodoliteOperator
+import rocks.theodolite.kubernetes.standalone.TheodoliteStandalone
 import kotlin.system.exitProcess
 
 private val logger = KotlinLogging.logger {}
@@ -17,9 +19,12 @@ object Main {
         val mode = Configuration.EXECUTION_MODE
         logger.info { "Start Theodolite with mode $mode" }
 
+        val namespace = Configuration.NAMESPACE
+        val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace)
+
         when (mode.lowercase()) {
-            ExecutionModes.STANDALONE.value -> TheodoliteStandalone().start()
-            ExecutionModes.OPERATOR.value -> TheodoliteOperator().start()
+            ExecutionModes.STANDALONE.value -> TheodoliteStandalone(client).start()
+            ExecutionModes.OPERATOR.value -> TheodoliteOperator(client).start()
             else -> {
                 logger.error { "MODE $mode not found" }
                 exitProcess(1)
diff --git a/theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt
similarity index 99%
rename from theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt
index 518b8eae211dd064e3c12b0713382bf3b12bb1ba..c65235f5fef304a7644399573380b4147704cb6c 100644
--- a/theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceByLabelHandler.kt
@@ -1,4 +1,4 @@
-package theodolite.k8s
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSet.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSet.kt
index 19fc85845ae99c7a5e4f7369db4b6cd383c3131b..9910d0ac89a9b423047f4f20f07a8015cbb24f9a 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSet.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.KubernetesResource
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSets.kt
similarity index 56%
rename from theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSets.kt
index 0626a6e24369348d50b60fbb555665c58dd17281..f57835a1e2459b0ce8989a4f1c745cc272e5f1e9 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSets.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.annotation.JsonInclude
 import com.fasterxml.jackson.annotation.JsonProperty
@@ -7,11 +7,17 @@ import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.DeploymentFailedException
+
+/**
+ * Loads [KubernetesResource]s.
+ */
+fun loadKubernetesResources(resourceSet: List<ResourceSets>, client: NamespacedKubernetesClient): Collection<Pair<String, HasMetadata>> {
+    return resourceSet.flatMap { it.loadResourceSet(client) }
+}
 
 @JsonDeserialize
 @RegisterForReflection
-class ResourceSets: KubernetesResource {
+class ResourceSets : KubernetesResource {
     @JsonProperty("configMap")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     var configMap: ConfigMapResourceSet? = null
@@ -20,14 +26,14 @@ class ResourceSets: KubernetesResource {
     @JsonInclude(JsonInclude.Include.NON_NULL)
     var fileSystem: FileSystemResourceSet? = null
 
+
     fun loadResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, HasMetadata>> {
-        // TODO Find out whether field access (::configMap) is really what we want to do here (see #362)
-        return if (::configMap != null) {
-                configMap?.getResourceSet(client= client) !!
-            } else if (::fileSystem != null) {
-                fileSystem?.getResourceSet(client= client ) !!
-            } else {
-                throw DeploymentFailedException("Could not load resourceSet.")
-            }
+        return if (this.configMap != null) {
+            configMap?.getResourceSet(client = client)!!
+        } else if (this.fileSystem != null) {
+            fileSystem?.getResourceSet(client = client)!!
+        } else {
+            throw DeploymentFailedException("Could not load resourceSet.")
+        }
     }
 }
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/RolloutManager.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/RolloutManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f760bb407ec2a6c4ab2ee08d3521ad72d12dd25d
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/RolloutManager.kt
@@ -0,0 +1,39 @@
+package theodolite.benchmark
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.DaemonSet
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.ReplicaSet
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+import io.fabric8.kubernetes.api.model.batch.v1.Job
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import rocks.theodolite.kubernetes.K8sManager
+
+private var SLEEP_TIME_MS = 500L
+class RolloutManager(private val blockUntilResourcesReady: Boolean, private val client: NamespacedKubernetesClient) {
+
+    fun rollout(resources: List<HasMetadata>) {
+        resources
+            .forEach { K8sManager(client).deploy(it) }
+
+        if (blockUntilResourcesReady) {
+            resources
+                .forEach {
+                    when (it) {
+                        is Deployment -> waitFor { client.apps().deployments().withName(it.metadata.name).isReady }
+                        is StatefulSet -> waitFor { client.apps().statefulSets().withName(it.metadata.name).isReady }
+                        is DaemonSet -> waitFor { client.apps().daemonSets().withName(it.metadata.name).isReady }
+                        is ReplicaSet -> waitFor { client.apps().replicaSets().withName(it.metadata.name).isReady }
+                        is Job -> waitFor { client.batch().v1().cronjobs().withName(it.metadata.name).isReady }
+                    }
+                }
+        }
+    }
+
+    private fun waitFor(isResourceReady: () -> Boolean) {
+        while (!isResourceReady()) {
+            Thread.sleep(SLEEP_TIME_MS)
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt
similarity index 58%
rename from theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt
index 29ac39c122f68636e08c6c5ecd5a6c01751edafb..e970c84d345031b79f8afeedf56591e071bb154f 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt
@@ -1,10 +1,9 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes
 
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import mu.KotlinLogging
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
 
 private val logger = KotlinLogging.logger {}
 
@@ -14,7 +13,9 @@ private val logger = KotlinLogging.logger {}
  * @property benchmarkExecution
  * @property benchmark
  */
-class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val benchmark: KubernetesBenchmark) {
+class Shutdown(private val benchmarkExecution: BenchmarkExecution,
+               private val benchmark: KubernetesBenchmark,
+               private val client: NamespacedKubernetesClient) {
 
     /**
      * Run
@@ -22,15 +23,19 @@ class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val b
      */
     fun run() {
         // Build Configuration to teardown
+        val benchmarkDeploymentBuilder = KubernetesBenchmarkDeploymentBuilder(benchmark, this.client)
         try {
             logger.info { "Received shutdown signal -> Shutting down" }
             val deployment =
-                benchmark.buildDeployment(
-                    load = LoadDimension(0, emptyList()),
-                    res = Resource(0, emptyList()),
+                    benchmarkDeploymentBuilder.buildDeployment(
+                    load = 0,
+                    loadPatcherDefinitions = emptyList(),
+                    resource = 0,
+                    resourcePatcherDefinitions = emptyList(),
                     configurationOverrides = benchmarkExecution.configOverrides,
                     loadGenerationDelay = 0L,
-                    afterTeardownDelay = 5L
+                    afterTeardownDelay = 5L,
+                    waitForResourcesEnabled = benchmark.waitForResourcesEnabled
                 )
             deployment.teardown()
             logger.info { "Finished teardown of all benchmark resources." }
diff --git a/theodolite/src/main/kotlin/theodolite/util/TheodoliteException.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteException.kt
similarity index 72%
rename from theodolite/src/main/kotlin/theodolite/util/TheodoliteException.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteException.kt
index fc7453bae6aaa4c5c526eee72c006562ea887eb5..6a4374c3e3c9435c498c8e15e8c5efaa01fd89cd 100644
--- a/theodolite/src/main/kotlin/theodolite/util/TheodoliteException.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteException.kt
@@ -1,3 +1,3 @@
-package theodolite.util
+package rocks.theodolite.kubernetes
 
 open class TheodoliteException (message: String, e: Exception? = null) : Exception(message,e)
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteExecutor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..69615522ba9bbd5ef0944528eacbf1dce318caf9
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteExecutor.kt
@@ -0,0 +1,169 @@
+package rocks.theodolite.kubernetes
+
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import mu.KotlinLogging
+import rocks.theodolite.core.ExecutionRunner
+import rocks.theodolite.core.ExperimentRunner
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.patcher.PatcherDefinitionFactory
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.strategies.StrategyFactory
+import rocks.theodolite.core.Config
+import rocks.theodolite.core.IOHandler
+import rocks.theodolite.core.Results
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.slo.SloFactory
+import java.io.File
+import java.time.Duration
+
+
+private val logger = KotlinLogging.logger {}
+
+/**
+ * The Theodolite executor runs all the experiments defined with the given execution and benchmark configuration.
+ *
+ * @property benchmarkExecution Configuration of a execution
+ * @property benchmark Configuration of a benchmark
+ * @constructor Create empty Theodolite executor
+ */
+class TheodoliteExecutor(
+        private val benchmarkExecution: BenchmarkExecution,
+        private val benchmark: KubernetesBenchmark,
+        private val client: NamespacedKubernetesClient
+) {
+    /**
+     * An executor object, configured with the specified benchmark, evaluation method, experiment duration
+     * and overrides which are given in the execution.
+     */
+    lateinit var experimentRunner: ExperimentRunner
+
+    /**
+     * Creates all required components to start Theodolite.
+     *
+     * @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(Metric.from(benchmarkExecution.execution.metric))
+        val strategyFactory = StrategyFactory()
+
+        val executionDuration = Duration.ofSeconds(benchmarkExecution.execution.duration)
+
+        val resourcePatcherDefinition =
+            PatcherDefinitionFactory().createPatcherDefinition(
+                benchmarkExecution.resources.resourceType,
+                this.benchmark.resourceTypes
+            )
+
+        val loadDimensionPatcherDefinition =
+            PatcherDefinitionFactory().createPatcherDefinition(
+                benchmarkExecution.loads.loadType,
+                this.benchmark.loadTypes
+            )
+
+        val slos = SloFactory().createSlos(this.benchmarkExecution, this.benchmark)
+
+        experimentRunner =
+            ExperimentRunnerImpl(
+                benchmarkDeploymentBuilder = KubernetesBenchmarkDeploymentBuilder(this.benchmark,this.client),
+                results = results,
+                executionDuration = executionDuration,
+                configurationOverrides = benchmarkExecution.configOverrides,
+                slos = slos,
+                repetitions = benchmarkExecution.execution.repetitions,
+                executionId = benchmarkExecution.executionId,
+                loadGenerationDelay = benchmarkExecution.execution.loadGenerationDelay,
+                afterTeardownDelay = benchmarkExecution.execution.afterTeardownDelay,
+                executionName = benchmarkExecution.name,
+                loadPatcherDefinitions = loadDimensionPatcherDefinition,
+                resourcePatcherDefinitions = resourcePatcherDefinition,
+                waitForResourcesEnabled = this.benchmark.waitForResourcesEnabled
+            )
+
+        if (benchmarkExecution.loads.loadValues != benchmarkExecution.loads.loadValues.sorted()) {
+            benchmarkExecution.loads.loadValues = benchmarkExecution.loads.loadValues.sorted()
+            logger.info {
+                "Load values are not sorted correctly, Theodolite sorts them in ascending order." +
+                        "New order is: ${benchmarkExecution.loads.loadValues}"
+            }
+        }
+
+        if (benchmarkExecution.resources.resourceValues != benchmarkExecution.resources.resourceValues.sorted()) {
+            benchmarkExecution.resources.resourceValues = benchmarkExecution.resources.resourceValues.sorted()
+            logger.info {
+                "Load values are not sorted correctly, Theodolite sorts them in ascending order." +
+                        "New order is: ${benchmarkExecution.resources.resourceValues}"
+            }
+        }
+
+        return Config(
+            loads = benchmarkExecution.loads.loadValues,
+            resources = benchmarkExecution.resources.resourceValues,
+            searchStrategy = strategyFactory.createSearchStrategy(experimentRunner, benchmarkExecution.execution.strategy.name,
+                    benchmarkExecution.execution.strategy.searchStrategy, benchmarkExecution.execution.strategy.restrictions,
+                    benchmarkExecution.execution.strategy.guessStrategy, results),
+            metric = Metric.from(benchmarkExecution.execution.metric)
+        )
+    }
+
+    /**
+     * Sets up the Infrastructure, increments the executionId, calls the [ExecutionRunner] that runs
+     * all experiments which are specified in the corresponding execution and benchmark objects.
+     */
+    fun setupAndRunExecution() {
+        setupInfrastructure()
+
+        val ioHandler = IOHandler()
+        val resultsFolder = ioHandler.getResultFolderURL()
+        this.benchmarkExecution.executionId = getAndIncrementExecutionID(resultsFolder + "expID.txt")
+        ioHandler.writeToJSONFile(this.benchmarkExecution, "${resultsFolder}exp${this.benchmarkExecution.executionId}-execution-configuration")
+        ioHandler.writeToJSONFile(
+                benchmark,
+            "${resultsFolder}exp${this.benchmarkExecution.executionId}-benchmark-configuration"
+        )
+
+        val config = buildConfig()
+
+        val executionRunner = ExecutionRunner(config.searchStrategy, config.resources, config.loads,config.metric,
+                                              this.benchmarkExecution.executionId)
+
+        executionRunner.run()
+
+        teardownInfrastructure()
+    }
+
+    private fun setupInfrastructure() {
+        benchmark.infrastructure.beforeActions.forEach { it.exec(client = client) }
+        val kubernetesManager = K8sManager(this.client)
+        loadKubernetesResources(benchmark.infrastructure.resources, this.client)
+                .map { it.second }
+                .forEach { kubernetesManager.deploy(it) }
+    }
+
+    private fun teardownInfrastructure() {
+        val kubernetesManager = K8sManager(this.client)
+        loadKubernetesResources(benchmark.infrastructure.resources, this.client)
+                .map { it.second }
+                .forEach { kubernetesManager.remove(it) }
+        benchmark.infrastructure.afterActions.forEach { it.exec(client = client) }
+    }
+
+    private fun getAndIncrementExecutionID(fileURL: String): Int {
+        val ioHandler = IOHandler()
+        var executionID = 0
+        if (File(fileURL).exists()) {
+            executionID = ioHandler.readFileAsString(fileURL).toInt() + 1
+        }
+        ioHandler.writeStringToTextFile(fileURL, (executionID).toString())
+        return executionID
+    }
+
+    private fun calculateMetric(xValues: List<Int>, results: Results): List<List<String>> {
+        return xValues.map { listOf(it.toString(), results.getOptYDimensionValue(it).toString()) }
+    }
+
+    fun getExecution(): BenchmarkExecution {
+        return this.benchmarkExecution
+    }
+}
diff --git a/theodolite/src/main/kotlin/theodolite/k8s/TopicManager.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/kafka/TopicManager.kt
similarity index 98%
rename from theodolite/src/main/kotlin/theodolite/k8s/TopicManager.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/kafka/TopicManager.kt
index ed1e06571d20c53fc82439833c8a31800a48b602..e9a0cb4b3c0863baf54a8dda58b96c81a80af60d 100644
--- a/theodolite/src/main/kotlin/theodolite/k8s/TopicManager.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/kafka/TopicManager.kt
@@ -1,4 +1,4 @@
-package theodolite.k8s
+package rocks.theodolite.kubernetes.kafka
 
 import mu.KotlinLogging
 import org.apache.kafka.clients.admin.AdminClient
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/BenchmarkExecution.kt
similarity index 58%
rename from theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/BenchmarkExecution.kt
index f2dda487d390c5f771e4f47c0f9c7ebf2cf971e7..167423ec911cd740b0ee0246e8512dde8402f1e9 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/BenchmarkExecution.kt
@@ -1,9 +1,9 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes.model
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.ConfigurationOverride
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
 import kotlin.properties.Delegates
 
 /**
@@ -12,9 +12,9 @@ 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.
+ *  - The [slos] further restrict the Benchmark SLOs for the evaluation of the experiments.
  *  - An [execution] that encapsulates: the strategy, the duration, and the restrictions
  *  for the execution of the benchmark.
  *  - [configOverrides] additional configurations.
@@ -28,48 +28,55 @@ 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 slos: List<SloConfiguration>
     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
     }
 
     /**
-     * Measurable metric.
-     * [sloType] determines the type of the metric.
-     * It is evaluated using the [theodolite.evaluation.ExternalSloChecker] by data measured by Prometheus.
-     * The evaluation checks if a [threshold] is reached or not.
-     * [offset] determines the shift in hours by which the start and end timestamps should be shifted.
-     * The [warmup] determines after which time the metric should be evaluated to avoid starting interferences.
-     * The [warmup] time unit depends on the Slo: for the lag trend it is in seconds.
+     * 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 Slo : KubernetesResource {
-        lateinit var sloType: String
-        lateinit var prometheusUrl: String
-        var offset by Delegates.notNull<Int>()
-        lateinit var properties: MutableMap<String, String>
+    class Strategy : KubernetesResource {
+        lateinit var name: String
+        var restrictions = emptyList<String>()
+        var guessStrategy = ""
+        var searchStrategy = ""
     }
 
     /**
-     * Represents a Load that should be created and checked.
-     * It can be set to [loadValues].
+     * Further SLO configurations for the SLOs specified in the Benchmark.
+     */
+    @JsonDeserialize
+    @RegisterForReflection
+    class SloConfiguration : KubernetesResource {
+        lateinit var name: String
+        var properties: MutableMap<String, String>? = null
+    }
+
+    /**
+     * 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 +86,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/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9c1412af7e6a86fbb248e8be7d1a97259a59c8d0
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt
@@ -0,0 +1,77 @@
+package rocks.theodolite.kubernetes.model
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import io.fabric8.kubernetes.api.model.KubernetesResource
+import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.kubernetes.Action
+import rocks.theodolite.kubernetes.ResourceSets
+import rocks.theodolite.kubernetes.model.crd.KafkaConfig
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
+import kotlin.properties.Delegates
+
+/**
+ * Represents a benchmark in Kubernetes. An example for this is the BenchmarkType.yaml
+ * Contains a of:
+ * - [name] of the benchmark,
+ * - [appResource] list of the resources that have to be deployed for the benchmark,
+ * - [loadGenResource] resource that generates the load,
+ * - [resourceTypes] types of scaling resources,
+ * - [loadTypes] types of loads that can be scaled for the benchmark,
+ * - [kafkaConfig] for the [theodolite.k8s.TopicManager],
+ * - [namespace] for the client,
+ * - [path] under which the resource yamls can be found.
+ *
+ *  This class is used for the parsing(in the [theodolite.execution.TheodoliteStandalone]) and
+ *  for the deserializing in the [theodolite.execution.operator.TheodoliteOperator].
+ * @constructor construct an empty Benchmark.
+ */
+@JsonDeserialize
+@RegisterForReflection
+class KubernetesBenchmark : KubernetesResource {
+    lateinit var name: String
+    var waitForResourcesEnabled = false
+    lateinit var resourceTypes: List<TypeName>
+    lateinit var loadTypes: List<TypeName>
+    lateinit var slos: MutableList<Slo>
+    var kafkaConfig: KafkaConfig? = null
+    lateinit var infrastructure: Resources
+    lateinit var sut: Resources
+    lateinit var loadGenerator: Resources
+
+    /**
+     * The TypeName encapsulates a list of [PatcherDefinition] along with a typeName that specifies for what the [PatcherDefinition] should be used.
+     */
+    @RegisterForReflection
+    @JsonDeserialize
+    class TypeName {
+        lateinit var typeName: String
+        lateinit var patchers: List<PatcherDefinition>
+    }
+
+    /**
+     * Measurable metric.
+     * [sloType] determines the type of the metric.
+     * It is evaluated using the [theodolite.evaluation.ExternalSloChecker] by data measured by Prometheus.
+     * The evaluation checks if a [threshold] is reached or not.
+     * [offset] determines the shift in hours by which the start and end timestamps should be shifted.
+     * The [warmup] determines after which time the metric should be evaluated to avoid starting interferences.
+     * The [warmup] time unit depends on the Slo: for the lag trend it is in seconds.
+     */
+    @JsonDeserialize
+    @RegisterForReflection
+    class Slo : KubernetesResource {
+        lateinit var name: String
+        lateinit var sloType: String
+        lateinit var prometheusUrl: String
+        var offset by Delegates.notNull<Int>()
+        lateinit var properties: MutableMap<String, String>
+    }
+
+    @JsonDeserialize
+    @RegisterForReflection
+    class Resources {
+        lateinit var resources: List<ResourceSets>
+        lateinit var beforeActions: List<Action>
+        lateinit var afterActions: List<Action>
+    }
+}
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkCRD.kt
similarity index 86%
rename from theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkCRD.kt
index 0ec6decbdea5e192721a4f9b6d0d85ea65665a5a..f480177e4482ab48df01593fdc10ea459a87ca43 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkCRD.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.Namespaced
@@ -6,7 +6,7 @@ import io.fabric8.kubernetes.client.CustomResource
 import io.fabric8.kubernetes.model.annotation.Group
 import io.fabric8.kubernetes.model.annotation.Kind
 import io.fabric8.kubernetes.model.annotation.Version
-import theodolite.benchmark.KubernetesBenchmark
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
 
 @JsonDeserialize
 @Version("v1")
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkExecutionList.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkExecutionList.kt
similarity index 72%
rename from theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkExecutionList.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkExecutionList.kt
index 2b2dcc07f9c37f1712109e3d092f2db0c139e1c8..768cd7c4f7edf2f254905539214177638ad5283c 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkExecutionList.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkExecutionList.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import io.fabric8.kubernetes.client.CustomResourceList
 
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkState.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkState.kt
similarity index 77%
rename from theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkState.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkState.kt
index dc2c6f9ba971367c0bb142a54745629eb29c07d5..928a411725f5eaf71839f4b7109b69ff40eb8807 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkState.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkState.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.annotation.JsonValue
 
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStatus.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkStatus.kt
similarity index 87%
rename from theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStatus.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkStatus.kt
index d4a17dbefb6cf3a53d545c32cb18e1d9acd7067f..691e5e1a83da5ccb3897f0b6342ee78ce437ba6b 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStatus.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkStatus.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.KubernetesResource
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionCRD.kt
similarity index 86%
rename from theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionCRD.kt
index 3be0aaf2a30cd4ef279edd34854eb936cc6e7e7c..df7b0f0c1ca326db21885beb1c714060aa56b251 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionCRD.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.fabric8.kubernetes.api.model.Namespaced
@@ -6,7 +6,7 @@ import io.fabric8.kubernetes.client.CustomResource
 import io.fabric8.kubernetes.model.annotation.Group
 import io.fabric8.kubernetes.model.annotation.Kind
 import io.fabric8.kubernetes.model.annotation.Version
-import theodolite.benchmark.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
 
 @JsonDeserialize
 @Version("v1")
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionState.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionState.kt
similarity index 86%
rename from theodolite/src/main/kotlin/theodolite/model/crd/ExecutionState.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionState.kt
index 9ce38d9f56a968ccc408966e56609ee4f70570a4..d74d70eb8e91246946923532967534aa46b958f7 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionState.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionState.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.annotation.JsonValue
 
diff --git a/theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStateComparator.kt
similarity index 74%
rename from theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStateComparator.kt
index 81bf350b58901bc10535f143d5ccdb295b5fe85f..9e859c3e943df4c72a2265941f14ea218b35ab12 100644
--- a/theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStateComparator.kt
@@ -1,7 +1,7 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.model.crd
 
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 
 class ExecutionStateComparator(private val preferredState: ExecutionState): Comparator<ExecutionCRD> {
 
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStatus.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStatus.kt
similarity index 97%
rename from theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStatus.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStatus.kt
index 1f843ccf9152676e778bc4ed359776e37205e998..6bec7197ddde61185ca37b3e0e96f471a910a0aa 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStatus.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStatus.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties
 import com.fasterxml.jackson.core.JsonGenerator
diff --git a/theodolite/src/main/kotlin/theodolite/util/KafkaConfig.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/KafkaConfig.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/util/KafkaConfig.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/KafkaConfig.kt
index 4e72ccb0d86749a6538c26556241ac114ef8d9a4..adde94c5126e370816966e6991670b6d400ba79a 100644
--- a/theodolite/src/main/kotlin/theodolite/util/KafkaConfig.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/KafkaConfig.kt
@@ -1,8 +1,8 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.KafkaConfig.TopicWrapper
+import rocks.theodolite.kubernetes.model.crd.KafkaConfig.TopicWrapper
 import kotlin.properties.Delegates
 import kotlin.reflect.KProperty
 
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/KubernetesBenchmarkList.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/KubernetesBenchmarkList.kt
similarity index 72%
rename from theodolite/src/main/kotlin/theodolite/model/crd/KubernetesBenchmarkList.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/KubernetesBenchmarkList.kt
index 8ad0a493d948bf5f78741052100766dcf6e316ec..be34662bd63b39808099a968ec4b89b5499ef34b 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/KubernetesBenchmarkList.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/crd/KubernetesBenchmarkList.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import io.fabric8.kubernetes.client.CustomResourceList
 
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt
similarity index 98%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt
index 84343ea7e8d7d420bcf320f36be02c39c41a1945..96593914cf07c427c924a1631a00f76dc3649ed3 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/AbstractStateHandler.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.KubernetesResourceList
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateChecker.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt
similarity index 82%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateChecker.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt
index c20b2ba87e386dc7c0a14245e03bedfb067720e6..c2c7db6cd6c5d6a02132353228714c3a3b19ec80 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateChecker.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt
@@ -1,22 +1,24 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.StatefulSet
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.fabric8.kubernetes.client.dsl.MixedOperation
 import io.fabric8.kubernetes.client.dsl.Resource
-import theodolite.benchmark.Action
-import theodolite.benchmark.ActionSelector
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.benchmark.ResourceSets
-import theodolite.model.crd.BenchmarkCRD
-import theodolite.model.crd.BenchmarkState
-import theodolite.model.crd.KubernetesBenchmarkList
+import rocks.theodolite.kubernetes.ExecActionSelector
+import rocks.theodolite.kubernetes.Action
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.ResourceSets
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
+import rocks.theodolite.kubernetes.model.crd.BenchmarkState
+import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList
+import rocks.theodolite.kubernetes.loadKubernetesResources
+
 
 class BenchmarkStateChecker(
-    private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>,
-    private val benchmarkStateHandler: BenchmarkStateHandler,
-    private val client: NamespacedKubernetesClient
+        private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>,
+        private val benchmarkStateHandler: BenchmarkStateHandler,
+        private val client: NamespacedKubernetesClient,
 
 ) {
 
@@ -91,7 +93,7 @@ class BenchmarkStateChecker(
      */
     private fun checkIfActionPossible(resourcesSets: List<ResourceSets>, actions: List<Action>): Boolean {
         return !actions.map {
-            checkIfResourceIsDeployed(it.selector) || checkIfResourceIsInfrastructure(resourcesSets, it.selector)
+            it.deleteCommand != null || checkIfResourceIsDeployed(it.execCommand!!.selector) || checkIfResourceIsInfrastructure(resourcesSets, it.execCommand!!.selector)
         }.contains(false)
     }
 
@@ -101,7 +103,7 @@ class BenchmarkStateChecker(
      * @param selector the actionSelector to check
      * @return true if the required resources are found, else false
      */
-    fun checkIfResourceIsDeployed(selector: ActionSelector): Boolean {
+    fun checkIfResourceIsDeployed(selector: ExecActionSelector): Boolean {
         val pods = this.client
             .pods()
             .withLabels(selector.pod.matchLabels)
@@ -128,8 +130,9 @@ class BenchmarkStateChecker(
      * @param selector the actionSelector to check
      * @return true if the required resources are found, else false
      */
-    fun checkIfResourceIsInfrastructure(resourcesSets: List<ResourceSets>, selector: ActionSelector): Boolean {
-        val resources = resourcesSets.flatMap { it.loadResourceSet(this.client) }
+    fun checkIfResourceIsInfrastructure(resourcesSets: List<ResourceSets>, selector: ExecActionSelector): Boolean {
+        val resources = loadKubernetesResources(resourcesSets, this.client)
+
         if (resources.isEmpty()) {
             return false
         }
@@ -176,9 +179,9 @@ class BenchmarkStateChecker(
     fun checkResources(benchmark: KubernetesBenchmark): BenchmarkState {
         return try {
             val appResources =
-                benchmark.loadKubernetesResources(resourceSet = benchmark.sut.resources)
+                    loadKubernetesResources(resourceSet = benchmark.sut.resources, this.client)
             val loadGenResources =
-                benchmark.loadKubernetesResources(resourceSet = benchmark.loadGenerator.resources)
+                    loadKubernetesResources(resourceSet = benchmark.loadGenerator.resources, this.client)
             if (appResources.isNotEmpty() && loadGenResources.isNotEmpty()) {
                 BenchmarkState.READY
             } else {
@@ -188,6 +191,8 @@ class BenchmarkStateChecker(
             BenchmarkState.PENDING
         }
     }
+
+
 }
 
 private fun <K, V> Map<K, V>.containsMatchLabels(matchLabels: Map<V, V>): Boolean {
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt
similarity index 80%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt
index 3b46859737d86a34b58a5514c0ae31ae215b9c7d..9a272b43f911bf523adf7c64c5ab34793b7a7dc5 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateHandler.kt
@@ -1,7 +1,9 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
-import theodolite.model.crd.*
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
+import rocks.theodolite.kubernetes.model.crd.BenchmarkState
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 
 class BenchmarkStateHandler(val client: NamespacedKubernetesClient) :
     AbstractStateHandler<BenchmarkCRD>(
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt
similarity index 84%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt
index e67be01ea80178b6d6bfb01b32bfd28c111addb9..a84bacb8296d62b8d6863046561dc797443e6084 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt
@@ -1,21 +1,21 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.client.KubernetesClientException
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.fabric8.kubernetes.client.dsl.MixedOperation
 import io.fabric8.kubernetes.client.dsl.Resource
 import mu.KotlinLogging
-import theodolite.execution.Shutdown
-import theodolite.k8s.K8sContextFactory
-import theodolite.k8s.ResourceByLabelHandler
-import theodolite.model.crd.*
+import rocks.theodolite.kubernetes.K8sContextFactory
+import rocks.theodolite.kubernetes.ResourceByLabelHandler
+import rocks.theodolite.kubernetes.model.crd.*
+import rocks.theodolite.kubernetes.Shutdown
 
 private val logger = KotlinLogging.logger {}
 
 class ClusterSetup(
-    private val executionCRDClient: MixedOperation<ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>>,
-    private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>,
-    private val client: NamespacedKubernetesClient
+        private val executionCRDClient: MixedOperation<ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>>,
+        private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>,
+        private val client: NamespacedKubernetesClient
 
 ) {
     private val serviceMonitorContext = K8sContextFactory().create(
@@ -53,7 +53,7 @@ class ClusterSetup(
                 if (benchmark != null) {
                     execution.spec.name = execution.metadata.name
                     benchmark.spec.name = benchmark.metadata.name
-                    Shutdown(execution.spec, benchmark.spec).run()
+                    Shutdown(execution.spec, benchmark.spec, client).run()
                 } else {
                     throw IllegalStateException("Execution with state ${ExecutionState.RUNNING.value} was found, but no corresponding benchmark. " +
                             "Could not initialize cluster.")
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/EventCreator.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt
similarity index 83%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/EventCreator.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt
index fab098ebd5fe765a455d787ddb7fcbfbb6c9ffc7..6803da62f045efcaf1b5504a33b42b2200d16baa 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/EventCreator.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.api.model.EventBuilder
 import io.fabric8.kubernetes.api.model.EventSource
@@ -6,14 +6,14 @@ import io.fabric8.kubernetes.api.model.ObjectReference
 import io.fabric8.kubernetes.client.DefaultKubernetesClient
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import mu.KotlinLogging
-import theodolite.util.Configuration
+import rocks.theodolite.kubernetes.Configuration
 import java.time.Instant
 import java.util.*
 import kotlin.NoSuchElementException
 private val logger = KotlinLogging.logger {}
 
 class EventCreator {
-    val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(Configuration.NAMESPACE)
+    private val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(Configuration.NAMESPACE)
 
     fun createEvent(executionName: String, type: String, message: String, reason: String) {
         val uuid = UUID.randomUUID().toString()
@@ -34,15 +34,15 @@ class EventCreator {
             event.source = source
 
             event.involvedObject = objectRef
-            client.v1().events().inNamespace(Configuration.NAMESPACE).createOrReplace(event)
+            this.client.v1().events().inNamespace(Configuration.NAMESPACE).createOrReplace(event)
         } catch (e: NoSuchElementException) {
                 logger.warn {"Could not create event: type: $type, message: $message, reason: $reason, no corresponding execution found."}
         }
     }
 
     private fun buildObjectReference(executionName: String): ObjectReference {
-        val exec = TheodoliteOperator()
-            .getExecutionClient(client = client)
+        val exec = TheodoliteOperator(this.client)
+            .getExecutionClient()
             .list()
             .items
             .first{it.metadata.name == executionName}
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandler.kt
similarity index 91%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandler.kt
index 25c627a350e3939530c4b453ec6db846b546cc08..58120d25d7e26daab015c01fece85cf72344bffa 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandler.kt
@@ -1,11 +1,12 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import com.google.gson.Gson
 import com.google.gson.GsonBuilder
 import io.fabric8.kubernetes.client.informers.ResourceEventHandler
 import mu.KotlinLogging
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.model.crd.*
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 
 private val logger = KotlinLogging.logger {}
 
@@ -18,8 +19,8 @@ private val logger = KotlinLogging.logger {}
  * @see BenchmarkExecution
  */
 class ExecutionEventHandler(
-    private val controller: TheodoliteController,
-    private val stateHandler: ExecutionStateHandler
+        private val controller: TheodoliteController,
+        private val stateHandler: ExecutionStateHandler
 ) : ResourceEventHandler<ExecutionCRD> {
 
     private val gson: Gson = GsonBuilder().enableComplexMapKeySerialization().create()
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt
index 340044e5be954d4d7673120e5bf2cba5aed02d92..6264b574d2be297865fab3b2a4d020bc57c56678 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ExecutionStateHandler.kt
@@ -1,9 +1,9 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.api.model.MicroTime
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 import java.lang.Thread.sleep
 import java.time.Instant
 import java.util.concurrent.atomic.AtomicBoolean
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/LeaderElector.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/LeaderElector.kt
similarity index 97%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/LeaderElector.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/LeaderElector.kt
index 558d06ce03074c38741b6c0a72c6ffa6eff96019..8a713d040e931a0e60266059c4faa44fdf5bddbc 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/LeaderElector.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/LeaderElector.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.client.DefaultKubernetesClient
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/StateHandler.kt
similarity index 90%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/StateHandler.kt
index 28563ac5a640d0226224b812a8e0691cde83942a..eaa3b39ec1391cb1e27573dfc85345add4c32330 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/StateHandler.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 private const val MAX_RETRIES: Int = 5
 
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt
similarity index 69%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt
index d9cb33b189da02b807301dde8550f2ae532d7e5a..67a9a40fe260c8105e30fef3c9c44436b7a37c5e 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt
@@ -1,14 +1,19 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.fabric8.kubernetes.client.dsl.MixedOperation
 import io.fabric8.kubernetes.client.dsl.Resource
 import mu.KotlinLogging
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.execution.TheodoliteExecutor
-import theodolite.model.crd.*
-import theodolite.patcher.ConfigOverrideModifier
-import theodolite.util.ExecutionStateComparator
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.TheodoliteExecutor
+import rocks.theodolite.kubernetes.model.crd.*
+import rocks.theodolite.kubernetes.patcher.ConfigOverrideModifier
+import rocks.theodolite.kubernetes.model.crd.ExecutionStateComparator
+import rocks.theodolite.kubernetes.loadKubernetesResources
 import java.lang.Thread.sleep
 
 private val logger = KotlinLogging.logger {}
@@ -25,10 +30,12 @@ const val CREATED_BY_LABEL_VALUE = "theodolite"
  */
 
 class TheodoliteController(
-    private val executionCRDClient: MixedOperation<ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>>,
-    private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>,
-    private val executionStateHandler: ExecutionStateHandler,
-    private val benchmarkStateChecker: BenchmarkStateChecker
+        private val client: NamespacedKubernetesClient,
+        private val executionCRDClient: MixedOperation<ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>>,
+        private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>,
+        private val executionStateHandler: ExecutionStateHandler,
+        private val benchmarkStateChecker: BenchmarkStateChecker,
+
 ) {
     lateinit var executor: TheodoliteExecutor
 
@@ -68,28 +75,28 @@ class TheodoliteController(
     private fun runExecution(execution: BenchmarkExecution, benchmark: KubernetesBenchmark) {
         try {
             val modifier = ConfigOverrideModifier(
-            execution = execution,
-            resources = benchmark.loadKubernetesResources(benchmark.sut.resources).map { it.first }
-                    + benchmark.loadKubernetesResources(benchmark.loadGenerator.resources).map { it.first }
-        )
-        modifier.setAdditionalLabels(
-            labelValue = execution.name,
-            labelName = DEPLOYED_FOR_EXECUTION_LABEL_NAME
-        )
-        modifier.setAdditionalLabels(
-            labelValue = benchmark.name,
-            labelName = DEPLOYED_FOR_BENCHMARK_LABEL_NAME
-        )
-        modifier.setAdditionalLabels(
-            labelValue = CREATED_BY_LABEL_VALUE,
-            labelName = CREATED_BY_LABEL_NAME
-        )
+                    execution = execution,
+                    resources = loadKubernetesResources(benchmark.sut.resources, this.client).map { it.first }
+                            + loadKubernetesResources(benchmark.loadGenerator.resources, this.client).map { it.first }
+            )
+            modifier.setAdditionalLabels(
+                labelValue = execution.name,
+                labelName = DEPLOYED_FOR_EXECUTION_LABEL_NAME
+            )
+            modifier.setAdditionalLabels(
+                labelValue = benchmark.name,
+                labelName = DEPLOYED_FOR_BENCHMARK_LABEL_NAME
+            )
+            modifier.setAdditionalLabels(
+                labelValue = CREATED_BY_LABEL_VALUE,
+                labelName = CREATED_BY_LABEL_NAME
+            )
 
-        executionStateHandler.setExecutionState(execution.name, ExecutionState.RUNNING)
-        executionStateHandler.startDurationStateTimer(execution.name)
+            executionStateHandler.setExecutionState(execution.name, ExecutionState.RUNNING)
+            executionStateHandler.startDurationStateTimer(execution.name)
 
-            executor = TheodoliteExecutor(execution, benchmark)
-            executor.run()
+            executor = TheodoliteExecutor(execution, benchmark, this.client)
+            executor.setupAndRunExecution()
             when (executionStateHandler.getExecutionState(execution.name)) {
                 ExecutionState.RESTART -> runExecution(execution, benchmark)
                 ExecutionState.RUNNING -> {
@@ -119,7 +126,7 @@ class TheodoliteController(
         if (restart) {
             executionStateHandler.setExecutionState(this.executor.getExecution().name, ExecutionState.RESTART)
         }
-        this.executor.executor.run.set(false)
+        this.executor.experimentRunner.run.set(false)
     }
 
     /**
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt
similarity index 62%
rename from theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt
index ada30ec945dd602dabe3ddb5f0e635a4eeea7b5f..bdaa2692d374b4002a1f890f706e2c1ec0d8733c 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt
@@ -1,20 +1,18 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
-import io.fabric8.kubernetes.client.DefaultKubernetesClient
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.fabric8.kubernetes.client.dsl.MixedOperation
 import io.fabric8.kubernetes.client.dsl.Resource
 import io.fabric8.kubernetes.client.informers.SharedInformerFactory
 import io.fabric8.kubernetes.internal.KubernetesDeserializer
 import mu.KotlinLogging
-import theodolite.model.crd.BenchmarkCRD
-import theodolite.model.crd.BenchmarkExecutionList
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.KubernetesBenchmarkList
-import theodolite.util.Configuration
+import rocks.theodolite.kubernetes.Configuration
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
+import rocks.theodolite.kubernetes.model.crd.BenchmarkExecutionList
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList
 
 
-private const val DEFAULT_NAMESPACE = "default"
 private const val EXECUTION_SINGULAR = "execution"
 private const val BENCHMARK_SINGULAR = "benchmark"
 private const val API_VERSION = "v1"
@@ -27,10 +25,7 @@ private val logger = KotlinLogging.logger {}
  *
  * **See Also:** [Kubernetes Operator Pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)
  */
-class TheodoliteOperator {
-    private val namespace = Configuration.NAMESPACE
-
-    private val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace)
+class TheodoliteOperator(private val client: NamespacedKubernetesClient) {
     private lateinit var controller: TheodoliteController
     private lateinit var executionStateHandler: ExecutionStateHandler
     private lateinit var benchmarkStateHandler: BenchmarkStateHandler
@@ -39,7 +34,7 @@ class TheodoliteOperator {
 
     fun start() {
         LeaderElector(
-            client = client,
+            client = this.client,
             name = Configuration.COMPONENT_NAME
         ).getLeadership(::startOperator)
     }
@@ -48,7 +43,7 @@ class TheodoliteOperator {
      * Start the operator.
      */
     private fun startOperator() {
-        logger.info { "Becoming the leading operator. Use namespace '$namespace'." }
+        logger.info { "Becoming the leading operator. Use namespace '${this.client.namespace}'." }
         client.use {
             KubernetesDeserializer.registerCustomKind(
                 "$GROUP/$API_VERSION",
@@ -63,28 +58,26 @@ class TheodoliteOperator {
             )
 
             ClusterSetup(
-                executionCRDClient = getExecutionClient(client),
-                benchmarkCRDClient = getBenchmarkClient(client),
-                client = client
+                executionCRDClient = getExecutionClient(),
+                benchmarkCRDClient = getBenchmarkClient(),
+                client = this.client
             ).clearClusterState()
 
             controller = getController(
-                client = client,
-                executionStateHandler = getExecutionStateHandler(client = client),
-                benchmarkStateChecker = getBenchmarkStateChecker(client = client)
+                executionStateHandler = getExecutionStateHandler(),
+                benchmarkStateChecker = getBenchmarkStateChecker()
 
             )
-            getExecutionEventHandler(controller, client).startAllRegisteredInformers()
+            getExecutionEventHandler(controller).startAllRegisteredInformers()
             controller.run()
         }
     }
 
-    fun getExecutionEventHandler(
-        controller: TheodoliteController,
-        client: NamespacedKubernetesClient
+    private fun getExecutionEventHandler(
+            controller: TheodoliteController,
     ): SharedInformerFactory {
-        val factory = client.informers()
-            .inNamespace(client.namespace)
+        val factory = this.client.informers()
+            .inNamespace(this.client.namespace)
 
         factory.sharedIndexInformerForCustomResource(
             ExecutionCRD::class.java,
@@ -92,46 +85,46 @@ class TheodoliteOperator {
         ).addEventHandler(
             ExecutionEventHandler(
                 controller = controller,
-                stateHandler = ExecutionStateHandler(client)
+                stateHandler = ExecutionStateHandler(this.client)
             )
         )
         return factory
     }
 
-    fun getExecutionStateHandler(client: NamespacedKubernetesClient): ExecutionStateHandler {
+    fun getExecutionStateHandler(): ExecutionStateHandler {
         if (!::executionStateHandler.isInitialized) {
-            this.executionStateHandler = ExecutionStateHandler(client = client)
+            this.executionStateHandler = ExecutionStateHandler(client = this.client)
         }
         return executionStateHandler
     }
 
-    fun getBenchmarkStateHandler(client: NamespacedKubernetesClient) : BenchmarkStateHandler {
+    fun getBenchmarkStateHandler() : BenchmarkStateHandler {
         if (!::benchmarkStateHandler.isInitialized) {
-            this.benchmarkStateHandler = BenchmarkStateHandler(client = client)
+            this.benchmarkStateHandler = BenchmarkStateHandler(client = this.client)
         }
         return benchmarkStateHandler
     }
 
-    fun getBenchmarkStateChecker(client: NamespacedKubernetesClient) : BenchmarkStateChecker {
+    fun getBenchmarkStateChecker() : BenchmarkStateChecker {
         if (!::benchmarkStateChecker.isInitialized) {
             this.benchmarkStateChecker = BenchmarkStateChecker(
-                client = client,
-                benchmarkStateHandler = getBenchmarkStateHandler(client = client),
-                benchmarkCRDClient = getBenchmarkClient(client = client))
+                client = this.client,
+                benchmarkStateHandler = getBenchmarkStateHandler(),
+                benchmarkCRDClient = getBenchmarkClient())
         }
         return benchmarkStateChecker
     }
 
 
     fun getController(
-        client: NamespacedKubernetesClient,
-        executionStateHandler: ExecutionStateHandler,
-        benchmarkStateChecker: BenchmarkStateChecker
+            executionStateHandler: ExecutionStateHandler,
+            benchmarkStateChecker: BenchmarkStateChecker
     ): TheodoliteController {
         if (!::controller.isInitialized) {
             this.controller = TheodoliteController(
-                benchmarkCRDClient = getBenchmarkClient(client),
-                executionCRDClient = getExecutionClient(client),
+                client = this.client,
+                benchmarkCRDClient = getBenchmarkClient(),
+                executionCRDClient = getExecutionClient(),
                 executionStateHandler = executionStateHandler,
                 benchmarkStateChecker = benchmarkStateChecker
             )
@@ -139,21 +132,21 @@ class TheodoliteOperator {
         return this.controller
     }
 
-    fun getExecutionClient(client: NamespacedKubernetesClient): MixedOperation<
+    fun getExecutionClient(): MixedOperation<
             ExecutionCRD,
             BenchmarkExecutionList,
             Resource<ExecutionCRD>> {
-        return client.customResources(
+        return this.client.customResources(
             ExecutionCRD::class.java,
             BenchmarkExecutionList::class.java
         )
     }
 
-    fun getBenchmarkClient(client: NamespacedKubernetesClient): MixedOperation<
+    fun getBenchmarkClient(): MixedOperation<
             BenchmarkCRD,
             KubernetesBenchmarkList,
             Resource<BenchmarkCRD>> {
-        return client.customResources(
+        return this.client.customResources(
             BenchmarkCRD::class.java,
             KubernetesBenchmarkList::class.java
         )
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a20a26b351e730de60497ac014b3aba855ac01f5
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcher.kt
@@ -0,0 +1,30 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.client.utils.Serialization
+
+/**
+ * A Patcher is able to modify values of a Kubernetes resource, see [Patcher].
+ *
+ * An AbstractPatcher is created with up to three parameters.
+ *
+ *
+ *
+ * **For example** to patch the load dimension of a load generator, the patcher should be created as follow:
+ *
+ * k8sResource: `uc-1-workload-generator.yaml`
+ * container: `workload`
+ * variableName: `NUM_SENSORS`
+ *
+ */
+abstract class AbstractPatcher : Patcher {
+
+    override fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> {
+        return resources
+            .map { Serialization.clone(it)}
+            .map { patchSingleResource(it, value) }
+    }
+
+    abstract fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata
+
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ConfigOverrideModifier.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifier.kt
similarity index 89%
rename from theodolite/src/main/kotlin/theodolite/patcher/ConfigOverrideModifier.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifier.kt
index 8f77b1b95f3bf5cc9422cda55cb261048cebaeb6..c45808b5a81e5ffdfa5fd09b263ae49312a8d7fa 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ConfigOverrideModifier.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifier.kt
@@ -1,8 +1,7 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.util.ConfigurationOverride
-import theodolite.util.PatcherDefinition
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
 
 /**
  * The ConfigOverrideModifier makes it possible to update the configuration overrides of an execution.
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
similarity index 56%
rename from theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
index bdc107910edc8ddfb41e7757c775977086a25a26..d884c9ee1b6925bc985ad1da69a46f6589917b01 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
@@ -1,6 +1,6 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import io.fabric8.kubernetes.api.model.KubernetesResource
+import io.fabric8.kubernetes.api.model.HasMetadata
 
 /**
  * The DataVolumeLoadGeneratorReplicaPatcher takes the total load that should be generated
@@ -10,29 +10,29 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
  * The number of instances are set for the load generator and the given variable is set to the
  * load per instance.
  *
- * @property k8sResource Kubernetes resource to be patched.
  * @property maxVolume per load generator instance
  * @property container Container to be patched.
  * @property variableName Name of the environment variable to be patched.
  */
 class DataVolumeLoadGeneratorReplicaPatcher(
-    k8sResource: KubernetesResource,
     private val maxVolume: Int,
-    container: String,
-    variableName: String
-) : AbstractPatcher(k8sResource) {
+    private val container: String,
+    private val variableName: String
+) : Patcher {
 
-    private val replicaPatcher = ReplicaPatcher(k8sResource)
-    private val envVarPatcher = EnvVarPatcher(k8sResource, container, variableName)
+    override fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> {
+        return resources.flatMap { patchSingeResource(it, value)}
+    }
 
-    override fun <T> patch(value: T) {
+    fun patchSingeResource(k8sResource: HasMetadata, value: String): List<HasMetadata> {
+        var resource = k8sResource
         // calculate number of load generator instances and load per instance
-        val load = Integer.parseInt(value.toString())
+        val load = Integer.parseInt(value)
         val loadGenInstances = (load + maxVolume - 1) / maxVolume
         val loadPerInstance = load / loadGenInstances
 
         // Patch instance values and load value of generators
-        replicaPatcher.patch(loadGenInstances.toString())
-        envVarPatcher.patch(loadPerInstance.toString())
+        val resourceList = ReplicaPatcher().patch(listOf(resource), loadGenInstances.toString())
+        return EnvVarPatcher(this.container, this.variableName).patch(resourceList, loadPerInstance.toString())
     }
 }
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcher.kt
similarity index 77%
rename from theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcher.kt
index 416aec74a3af9b74594f5e6cd018682bf91cbf63..33d6c8d9b6f5f82a49e7cd414e4b273708c0e68a 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcher.kt
@@ -1,30 +1,31 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.Container
 import io.fabric8.kubernetes.api.model.EnvVar
-import io.fabric8.kubernetes.api.model.KubernetesResource
+import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
 
 /**
  * The EnvVarPatcher allows to modify the value of an environment variable
  *
- * @property k8sResource Kubernetes resource to be patched.
  * @property container Container to be patched.
  * @property variableName Name of the environment variable to be patched.
  */
 class EnvVarPatcher(
-    private val k8sResource: KubernetesResource,
     private val container: String,
     private val variableName: String
-) : AbstractPatcher(k8sResource) {
+) : AbstractPatcher() {
 
-    override fun <String> patch(value: String) {
-        if (k8sResource is Deployment) {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
             this.setEnv(
-                k8sResource, this.container,
-                mapOf(this.variableName to value) as Map<kotlin.String, kotlin.String>
+                resource, this.container,
+                mapOf(this.variableName to value)
             )
+            return resource
         }
+        return resource
     }
 
     /**
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7f54416501bc742499a958566a179b7fad320318
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcher.kt
@@ -0,0 +1,37 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+import io.fabric8.kubernetes.client.utils.Serialization
+
+/**
+ * The Image patcher allows to change the image of a container.
+ *
+ * @param container Container to be patched.
+ */
+class ImagePatcher(
+    private val container: String) :
+    AbstractPatcher() {
+
+    override fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> {
+        return resources
+            .map { Serialization.clone(it) }
+            .map { patchSingleResource(it, value as kotlin.String) }
+    }
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            (resource).spec.template.spec.containers.filter { it.name == container }.forEach {
+                it.image = value
+            }
+            return resource
+        } else if (resource is StatefulSet) {
+            (resource).spec.template.spec.containers.filter { it.name == container }.forEach {
+                it.image = value
+            }
+            return resource
+        }
+        return resource
+    }
+}
diff --git a/theodolite/src/main/kotlin/theodolite/util/InvalidPatcherConfigurationException.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/InvalidPatcherConfigurationException.kt
similarity index 53%
rename from theodolite/src/main/kotlin/theodolite/util/InvalidPatcherConfigurationException.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/InvalidPatcherConfigurationException.kt
index d02948ad341207051c4653ba9400ac0ffe5b03aa..88ad707ec48b0c2c2b3a62cc46f004ced64dbb69 100644
--- a/theodolite/src/main/kotlin/theodolite/util/InvalidPatcherConfigurationException.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/InvalidPatcherConfigurationException.kt
@@ -1,3 +1,5 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.patcher
+
+import rocks.theodolite.kubernetes.DeploymentFailedException
 
 class InvalidPatcherConfigurationException(message: String, e: Exception? = null) : DeploymentFailedException(message,e)
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8bb5be97e780479884e6cb8e551c03340b04f8e6
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcher.kt
@@ -0,0 +1,50 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.ConfigMap
+import io.fabric8.kubernetes.api.model.GenericKubernetesResource
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.Service
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+
+class LabelPatcher(
+    val variableName: String) :
+    AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        when (resource) {
+            is Deployment -> {
+                if (resource.metadata.labels == null) {
+                    resource.metadata.labels = mutableMapOf()
+                }
+                resource.metadata.labels[this.variableName] = value
+            }
+            is StatefulSet -> {
+                if (resource.metadata.labels == null) {
+                    resource.metadata.labels = mutableMapOf()
+                }
+                resource.metadata.labels[this.variableName] = value
+            }
+            is Service -> {
+                if (resource.metadata.labels == null) {
+                    resource.metadata.labels = mutableMapOf()
+                }
+                resource.metadata.labels[this.variableName] = value
+
+            }
+            is ConfigMap -> {
+                if (resource.metadata.labels == null) {
+                    resource.metadata.labels = mutableMapOf()
+                }
+                resource.metadata.labels[this.variableName] = value
+            }
+            is GenericKubernetesResource -> {
+                if (resource.metadata.labels == null) {
+                    resource.metadata.labels = mutableMapOf()
+                }
+                resource.metadata.labels[this.variableName] = value
+            }
+        }
+        return resource
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..725c9cf8a6a87c23119812c0a5d5ad3280a42e3c
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcher.kt
@@ -0,0 +1,33 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+
+/**
+ * This patcher is able to set the `spec.selector.matchLabels` for a `Deployment` or `StatefulSet` Kubernetes resource.
+ *
+ * @property variableName The matchLabel which should be set
+ */
+class MatchLabelPatcher(
+    val variableName: String) :
+    AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        when (resource) {
+            is Deployment -> {
+                if (resource.spec.selector.matchLabels == null) {
+                    resource.spec.selector.matchLabels = mutableMapOf()
+                }
+                resource.spec.selector.matchLabels[this.variableName] = value
+            }
+            is StatefulSet -> {
+                if (resource.spec.selector.matchLabels == null) {
+                    resource.spec.selector.matchLabels = mutableMapOf()
+                }
+                resource.spec.selector.matchLabels[this.variableName] = value
+            }
+        }
+        return resource
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a6416a7e77841fa869de7ce2c248882fb486572c
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcher.kt
@@ -0,0 +1,35 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.ConfigMap
+import io.fabric8.kubernetes.api.model.GenericKubernetesResource
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.Service
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+
+class NamePatcher : AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        when (resource) {
+            is Deployment -> {
+                resource.metadata.name = value
+            }
+            is StatefulSet -> {
+                resource.metadata.name = value
+            }
+            is Service -> {
+                resource.metadata.name = value
+            }
+            is ConfigMap -> {
+                resource.metadata.name = value
+            }
+            is io.fabric8.kubernetes.api.model.networking.v1.Ingress -> {
+                resource.metadata.name = value
+            }
+            is GenericKubernetesResource -> {
+                resource.metadata.name = value
+            }
+        }
+        return resource
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c3b5ba1a07afa41dd604f2335baf6b58e362f293
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcher.kt
@@ -0,0 +1,22 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+
+/**
+ * The Node selector patcher make it possible to set the NodeSelector of a Kubernetes deployment.
+ *
+ * @param variableName The `label-key` of the node for which the `label-value` is to be patched.
+ */
+class NodeSelectorPatcher(
+    private val variableName: String) :
+    AbstractPatcher() {
+
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            resource.spec.template.spec.nodeSelector = mapOf(variableName to value)
+        }
+        return resource
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e3b0105768ec339758fd89233a09da233145d641
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
@@ -0,0 +1,23 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import kotlin.math.pow
+
+class NumNestedGroupsLoadGeneratorReplicaPatcher(
+    private val numSensors: String,
+    private val loadGenMaxRecords: String,
+) : AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            val approxNumSensors = numSensors.toDouble().pow(Integer.parseInt(value).toDouble())
+            val loadGenInstances =
+                (approxNumSensors + loadGenMaxRecords.toDouble() - 1) / loadGenMaxRecords.toDouble()
+            resource.spec.replicas = loadGenInstances.toInt()
+
+        }
+        return resource
+    }
+}
+
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6bb2750bb1ca923aa05022884ef7054772a987c6
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
@@ -0,0 +1,21 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+
+
+class NumSensorsLoadGeneratorReplicaPatcher(
+    private val loadGenMaxRecords: String,
+) : AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            val loadGenInstances =
+                (Integer.parseInt(value) + loadGenMaxRecords.toInt() - 1) / loadGenMaxRecords.toInt()
+            resource.spec.replicas = loadGenInstances
+
+        }
+        return resource
+    }
+
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatchHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatchHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6873d9ec84cd02b85b2342bbd37d429c706a47ab
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatchHandler.kt
@@ -0,0 +1,20 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+class PatchHandler {
+    companion object {
+        private fun getResourcesToPatch(resources: MutableMap<String, List<HasMetadata>>, patcherDefinition: PatcherDefinition): List<HasMetadata> {
+            return resources[patcherDefinition.resource]
+                ?: throw InvalidPatcherConfigurationException("Could not find resource ${patcherDefinition.resource}")
+
+        }
+        fun patchResource(
+            resources: MutableMap<String, List<HasMetadata>>,
+            patcherDefinition: PatcherDefinition,
+            value: String,
+        ): List<HasMetadata> {
+            val resToPatch = getResourcesToPatch(resources, patcherDefinition)
+            return PatcherFactory.createPatcher(patcherDefinition).patch(resToPatch,value)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/Patcher.kt
similarity index 68%
rename from theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/Patcher.kt
index 84b886cb4f06b3e667eb8b8aeaa622e1ee54852e..310b370b97d065fc1ea0c3f7edd81577816ff69c 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/Patcher.kt
@@ -1,5 +1,6 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
+import io.fabric8.kubernetes.api.model.HasMetadata
 import io.quarkus.runtime.annotations.RegisterForReflection
 
 /**
@@ -13,8 +14,7 @@ interface Patcher {
      * The patch method modifies a value in the definition of a
      * Kubernetes resource.
      *
-     * @param T The type of value
      * @param value The value to be used.
      */
-    fun <T> patch(value: T)
+    fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata>
 }
diff --git a/theodolite/src/main/kotlin/theodolite/util/PatcherDefinition.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinition.kt
similarity index 93%
rename from theodolite/src/main/kotlin/theodolite/util/PatcherDefinition.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinition.kt
index fd2ac209a52e0d516ffa9ec07e465fa076ae665a..653ed9e03caf86c661e6a52ed59501b478eea7b5 100644
--- a/theodolite/src/main/kotlin/theodolite/util/PatcherDefinition.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinition.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.patcher
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import com.fasterxml.jackson.databind.annotation.JsonSerialize
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactory.kt
similarity index 83%
rename from theodolite/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactory.kt
index 6a1f993e2ac327ec242a8a5bafc3e6cc43475710..be9dcd11b08edf58462f0a1e71c7c3ab548fa66a 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactory.kt
@@ -1,7 +1,6 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import theodolite.util.PatcherDefinition
-import theodolite.util.TypeName
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
 
 /**
  * The PatcherDefinition Factory creates a [PatcherDefinition]s.
@@ -20,7 +19,7 @@ class PatcherDefinitionFactory {
      * @return A list of PatcherDefinitions which corresponds to the
      *     value of the requiredType.
      */
-    fun createPatcherDefinition(requiredType: String, patcherTypes: List<TypeName>): List<PatcherDefinition> {
+    fun createPatcherDefinition(requiredType: String, patcherTypes: List<KubernetesBenchmark.TypeName>): List<PatcherDefinition> {
         return patcherTypes.firstOrNull { type -> type.typeName == requiredType }
             ?.patchers ?: throw IllegalArgumentException("typeName $requiredType not found.")
     }
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a4dcf68d2b4ec12facb26755e9f63e298725e195
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherFactory.kt
@@ -0,0 +1,89 @@
+package rocks.theodolite.kubernetes.patcher
+
+/**
+ * The Patcher factory creates [Patcher]s
+ *
+ * @constructor Creates an empty PatcherFactory.
+ */
+class PatcherFactory {
+
+    companion object {
+        /**
+         * Create patcher based on the given [PatcherDefinition] and
+         * the list of KubernetesResources.
+         *
+         * @param patcherDefinition The [PatcherDefinition] for which are
+         *     [Patcher] should be created.
+         * @param k8sResources List of all available Kubernetes resources.
+         *     This is a list of pairs<String, KubernetesResource>:
+         *     The frist corresponds to the filename where the resource is defined.
+         *     The second corresponds to the concrete [KubernetesResource] that should be patched.
+         * @return The created [Patcher].
+         * @throws IllegalArgumentException if no patcher can be created.
+         */
+        fun createPatcher(
+            patcherDefinition: PatcherDefinition,
+        ): Patcher {
+
+            return try {
+                when (patcherDefinition.type) {
+                    "ReplicaPatcher" -> ReplicaPatcher(
+                    )
+                    "NumNestedGroupsLoadGeneratorReplicaPatcher" -> NumNestedGroupsLoadGeneratorReplicaPatcher(
+                        loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!!,
+                        numSensors = patcherDefinition.properties["numSensors"]!!
+                    )
+                    "NumSensorsLoadGeneratorReplicaPatcher" -> NumSensorsLoadGeneratorReplicaPatcher(
+                        loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!!
+                    )
+                    "DataVolumeLoadGeneratorReplicaPatcher" -> DataVolumeLoadGeneratorReplicaPatcher(
+                        maxVolume = patcherDefinition.properties["maxVolume"]!!.toInt(),
+                        container = patcherDefinition.properties["container"]!!,
+                        variableName = patcherDefinition.properties["variableName"]!!
+                    )
+                    "EnvVarPatcher" -> EnvVarPatcher(
+                        container = patcherDefinition.properties["container"]!!,
+                        variableName = patcherDefinition.properties["variableName"]!!
+                    )
+                    "NodeSelectorPatcher" -> NodeSelectorPatcher(
+                        variableName = patcherDefinition.properties["variableName"]!!
+                    )
+                    "ResourceLimitPatcher" -> ResourceLimitPatcher(
+                        container = patcherDefinition.properties["container"]!!,
+                        limitedResource = patcherDefinition.properties["limitedResource"]!!
+                    )
+                    "ResourceRequestPatcher" -> ResourceRequestPatcher(
+                        container = patcherDefinition.properties["container"]!!,
+                        requestedResource = patcherDefinition.properties["requestedResource"]!!
+                    )
+                    "SchedulerNamePatcher" -> SchedulerNamePatcher()
+                    "LabelPatcher" -> LabelPatcher(
+                        variableName = patcherDefinition.properties["variableName"]!!
+                    )
+                    "MatchLabelPatcher" -> MatchLabelPatcher(
+                        variableName = patcherDefinition.properties["variableName"]!!
+                    )
+                    "TemplateLabelPatcher" -> TemplateLabelPatcher(
+                        variableName = patcherDefinition.properties["variableName"]!!
+                    )
+                    "ImagePatcher" -> ImagePatcher(
+                        container = patcherDefinition.properties["container"]!!
+                    )
+                    "NamePatcher" -> NamePatcher()
+                    "ServiceSelectorPatcher" -> ServiceSelectorPatcher(
+                        variableName = patcherDefinition.properties["label"]!!
+                    )
+                    "rocks.theodolite.kubernetes.patcher.VolumesConfigMapPatcher" -> VolumesConfigMapPatcher(
+                        volumeName = patcherDefinition.properties["volumeName"]!!
+                    )
+                    else -> throw InvalidPatcherConfigurationException("Patcher type ${patcherDefinition.type} not found.")
+                }
+            } catch (e: NullPointerException) {
+                throw InvalidPatcherConfigurationException(
+                    "Could not create patcher with type ${patcherDefinition.type}" +
+                            " Probably a required patcher argument was not specified.", e
+                )
+            }
+        }
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8637b1299e878c4424e7fcaf4eac3bc901428541
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcher.kt
@@ -0,0 +1,18 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+
+/**
+ * The Replica [Patcher] modifies the number of replicas for the given Kubernetes deployment.
+ *
+ */
+class ReplicaPatcher : AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            resource.spec.replicas = Integer.parseInt(value)
+        }
+        return resource
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcher.kt
similarity index 62%
rename from theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcher.kt
index 9dcdffa0407dd4fdaf2d9b0a898bcdf6cebe5a8b..7450e2edfa20f570742fe0336d0d27c76ec83aa2 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcher.kt
@@ -1,12 +1,8 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import io.fabric8.kubernetes.api.model.Container
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.Quantity
-import io.fabric8.kubernetes.api.model.ResourceRequirements
+import io.fabric8.kubernetes.api.model.*
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.StatefulSet
-import theodolite.util.InvalidPatcherConfigurationException
 
 /**
  * The Resource limit [Patcher] set resource limits for deployments and statefulSets.
@@ -16,30 +12,31 @@ import theodolite.util.InvalidPatcherConfigurationException
  * @param limitedResource The resource to be limited (e.g. **cpu or memory**)
  */
 class ResourceLimitPatcher(
-    private val k8sResource: KubernetesResource,
     private val container: String,
     private val limitedResource: String
-) : AbstractPatcher(k8sResource) {
+) : AbstractPatcher() {
 
-    override fun <String> patch(value: String) {
-        when (k8sResource) {
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        when (resource) {
             is Deployment -> {
-                k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach {
-                    setLimits(it, value as kotlin.String)
+                resource.spec.template.spec.containers.filter { it.name == container }.forEach {
+                    setLimits(it, value)
                 }
             }
             is StatefulSet -> {
-                k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach {
-                    setLimits(it, value as kotlin.String)
+                resource.spec.template.spec.containers.filter { it.name == container }.forEach {
+                    setLimits(it, value)
                 }
             }
             else -> {
-                throw InvalidPatcherConfigurationException("ResourceLimitPatcher not applicable for $k8sResource")
+                throw InvalidPatcherConfigurationException("ResourceLimitPatcher is not applicable for $resource")
             }
         }
+        return resource
     }
 
-    private fun setLimits(container: Container, value: String) {
+
+        private fun setLimits(container: Container, value: String) {
         when {
             container.resources == null -> {
                 val resource = ResourceRequirements()
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcher.kt
similarity index 62%
rename from theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcher.kt
index 24cdde40f7f78bd67d115b2dc44f47e180f51ee2..bdcdc9527e8fa4dad9f85917be7d5c1c2fe67c2e 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcher.kt
@@ -1,44 +1,39 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import io.fabric8.kubernetes.api.model.Container
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.Quantity
-import io.fabric8.kubernetes.api.model.ResourceRequirements
+import io.fabric8.kubernetes.api.model.*
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.StatefulSet
-import theodolite.util.InvalidPatcherConfigurationException
 
 /**
  * The Resource request [Patcher] set resource limits for deployments and statefulSets.
  *
- * @param k8sResource Kubernetes resource to be patched.
  * @param container Container to be patched.
  * @param requestedResource The resource to be requested (e.g. **cpu or memory**)
  */
 class ResourceRequestPatcher(
-    private val k8sResource: KubernetesResource,
     private val container: String,
     private val requestedResource: String
-) : AbstractPatcher(k8sResource) {
+) : AbstractPatcher() {
 
-    override fun <String> patch(value: String) {
-        when (k8sResource) {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        when (resource) {
             is Deployment -> {
-                k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach {
-                    setRequests(it, value as kotlin.String)
+                resource.spec.template.spec.containers.filter { it.name == container }.forEach {
+                    setRequests(it, value)
                 }
             }
             is StatefulSet -> {
-                k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach {
-                    setRequests(it, value as kotlin.String)
+                resource.spec.template.spec.containers.filter { it.name == container }.forEach {
+                    setRequests(it, value)
                 }
             }
             else -> {
-                throw InvalidPatcherConfigurationException("ResourceRequestPatcher not applicable for $k8sResource")
+                throw InvalidPatcherConfigurationException("ResourceRequestPatcher is not applicable for $resource")
             }
         }
+        return resource
     }
-
     private fun setRequests(container: Container, value: String) {
         when {
             container.resources == null -> {
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c5ac16cdfe25f6b2fd2e4d0a2fb27000f885ffe7
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcher.kt
@@ -0,0 +1,20 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+
+/**
+ * The Scheduler name [Patcher] make it possible to set the scheduler which should
+ * be used to deploy the given deployment.
+ * @param k8sResource Kubernetes resource to be patched.
+ */
+class SchedulerNamePatcher : AbstractPatcher() {
+
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            resource.spec.template.spec.schedulerName = value
+        }
+        return resource
+    }
+}
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ServiceSelectorPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ServiceSelectorPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b38ae4108748f85e7ac60f3ee3aa8c5d28281432
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ServiceSelectorPatcher.kt
@@ -0,0 +1,19 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.Service
+
+class ServiceSelectorPatcher(
+    private var variableName: String
+    ) : AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Service) {
+            if (resource.spec.selector == null) {
+                resource.spec.selector = mutableMapOf()
+            }
+            resource.spec.selector[this.variableName] = value
+        }
+        return resource
+    }
+    }
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..534809cf8c36fb2065cbe3c0823294b346ac05f6
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcher.kt
@@ -0,0 +1,34 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+
+/**
+ * This patcher is able to set the field `spec.template.metadata.labels` for a `Deployment` or `StatefulSet` Kubernetes resource.
+ *
+ * @property variableName The label which should be set
+ */
+class TemplateLabelPatcher(
+    val variableName: String) :
+    AbstractPatcher() {
+
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        when (resource) {
+            is Deployment -> {
+                if (resource.spec.template.metadata.labels == null) {
+                    resource.spec.template.metadata.labels = mutableMapOf()
+                }
+                resource.spec.template.metadata.labels[this.variableName] = value
+            }
+            is StatefulSet -> {
+                if (resource.spec.template.metadata.labels == null) {
+                    resource.spec.template.metadata.labels = mutableMapOf()
+                }
+                resource.spec.template.metadata.labels[this.variableName] = value
+            }
+        }
+        return resource
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..54a459a19b35e74839de647761e8ac22f839ca2d
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcher.kt
@@ -0,0 +1,44 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.HasMetadata
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.fabric8.kubernetes.api.model.apps.StatefulSet
+
+class VolumesConfigMapPatcher(private var volumeName: String
+) : AbstractPatcher() {
+
+    override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
+        if (resource is Deployment) {
+            if (resource.spec.template.spec.volumes == null) {
+                resource.spec.template.spec.volumes = mutableListOf()
+            }
+            val volumeMounts = resource.spec.template.spec.volumes
+
+            for (mount in volumeMounts) {
+                try {
+                    if (mount.configMap.name == volumeName) {
+                        mount.configMap.name = value
+                    }
+                } catch (_: NullPointerException) {
+                }
+            }
+        }
+        if (resource is StatefulSet) {
+            if (resource.spec.template.spec.volumes == null) {
+                resource.spec.template.spec.volumes = mutableListOf()
+            }
+            val volumeMounts = resource.spec.template.spec.volumes
+
+            for (mount in volumeMounts) {
+                try {
+                    if (mount.configMap.name == volumeName) {
+                        mount.configMap.name = value
+                    }
+                } catch (_: NullPointerException) {
+                }
+            }
+        }
+
+        return resource
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
similarity index 76%
rename from theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
index b3cc174d2945bf13bc1cc29d4e60d8c9bfbaf7eb..96c5a43b85c0db5600d813f9e799903927a53ec3 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
@@ -1,10 +1,8 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.util.EvaluationFailedException
-import theodolite.util.IOHandler
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.IOHandler
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
 import java.text.Normalizer
 import java.time.Duration
 import java.time.Instant
@@ -16,8 +14,8 @@ import java.util.regex.Pattern
  * @param slo Slo that is used for the analysis.
  */
 class AnalysisExecutor(
-    private val slo: BenchmarkExecution.Slo,
-    private val executionId: Int
+        private val slo: Slo,
+        private val executionId: Int
 ) {
 
     private val fetcher = MetricFetcher(
@@ -29,17 +27,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 ->
@@ -50,9 +48,9 @@ class AnalysisExecutor(
                     )
                 }
 
-            prometheusData.forEach { data ->
+            prometheusData.forEach{ data ->
                 ioHandler.writeToCSVFile(
-                    fileURL = "${fileURL}_${repetitionCounter++}",
+                    fileURL = "${fileURL}_${slo.name}_${repetitionCounter++}",
                     data = data.getResultAsList(),
                     columns = listOf("labels", "timestamp", "value")
                 )
@@ -61,13 +59,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/util/EvaluationFailedException.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/EvaluationFailedException.kt
similarity index 52%
rename from theodolite/src/main/kotlin/theodolite/util/EvaluationFailedException.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/EvaluationFailedException.kt
index ebdf5a37b4e82c8d4b1870d065f5e77133154735..564ec926aeba501c55675ba3d25cfa8ebf50b68b 100644
--- a/theodolite/src/main/kotlin/theodolite/util/EvaluationFailedException.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/EvaluationFailedException.kt
@@ -1,3 +1,5 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.slo
+
+import rocks.theodolite.kubernetes.ExecutionFailedException
 
 class EvaluationFailedException(message: String, e: Exception? = null) : ExecutionFailedException(message,e)
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt
similarity index 94%
rename from theodolite/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt
index 7587e8326df98f3c45c016bfd3b2d7db8077e6d1..01b21c845a614ba42581c182d975da5ad645b474 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt
@@ -1,8 +1,8 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
 import khttp.post
 import mu.KotlinLogging
-import theodolite.util.PrometheusResponse
+import rocks.theodolite.kubernetes.util.PrometheusResponse
 import java.net.ConnectException
 
 /**
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt
index b6a1857cba513f663876f88d7a7d69ad02c0bc40..962564475d0ad0b56bad8cf99daf12329950eaf3 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/MetricFetcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt
@@ -1,10 +1,10 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
 import com.google.gson.Gson
 import khttp.get
 import khttp.responses.Response
 import mu.KotlinLogging
-import theodolite.util.PrometheusResponse
+import rocks.theodolite.kubernetes.util.PrometheusResponse
 import java.net.ConnectException
 import java.time.Duration
 import java.time.Instant
diff --git a/theodolite/src/main/kotlin/theodolite/util/PrometheusResponse.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/PrometheusResponse.kt
similarity index 98%
rename from theodolite/src/main/kotlin/theodolite/util/PrometheusResponse.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/PrometheusResponse.kt
index 9b0b0dd4e0a5a48072ca576e874cb850c5f8df3b..5222a78bde342fea4a94c69bf1e42e132d0bc706 100644
--- a/theodolite/src/main/kotlin/theodolite/util/PrometheusResponse.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/PrometheusResponse.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.util
 
 import io.quarkus.runtime.annotations.RegisterForReflection
 import java.util.*
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/SloChecker.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloChecker.kt
similarity index 81%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloChecker.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloChecker.kt
index 82f903f5be868731d58ebefd6279d5d438bd5eab..f4ac163547421d5f0f07d2511c2e3eeeebdb35b0 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloChecker.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloChecker.kt
@@ -1,6 +1,6 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
-import theodolite.util.PrometheusResponse
+import rocks.theodolite.kubernetes.util.PrometheusResponse
 
 /**
  * A SloChecker can be used to evaluate data from Prometheus.
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
similarity index 95%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
index f57cebfcb13d0e86919ec15a0a479d1258e318a6..810675f159169f31314289d08a59fcc15bf8a243 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
@@ -1,6 +1,7 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
+
+import rocks.theodolite.core.strategies.Metric
 
-import theodolite.util.LoadDimension
 
 /**
  * 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/evaluation/SloConfigHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
similarity index 86%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloConfigHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
index 089f40dc6b5ef7d8ac4b063cae68e5e9621d1f50..ed18e4a0b4027ce4284cc83ff4c9520738ec2ba7 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloConfigHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
@@ -1,7 +1,7 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.util.InvalidPatcherConfigurationException
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
+import rocks.theodolite.kubernetes.patcher.InvalidPatcherConfigurationException
 import javax.enterprise.context.ApplicationScoped
 
 private const val DEFAULT_CONSUMER_LAG_METRIC_BASE = "kafka_consumergroup_lag"
@@ -11,7 +11,7 @@ private const val DEFAULT_DROPPED_RECORDS_QUERY = "sum by(job) (kafka_streams_st
 @ApplicationScoped
 class SloConfigHandler {
     companion object {
-        fun getQueryString(slo: BenchmarkExecution.Slo): String {
+        fun getQueryString(slo: Slo): String {
             return when (slo.sloType.lowercase()) {
                 SloTypes.GENERIC.value -> slo.properties["promQLQuery"] ?: throw IllegalArgumentException("promQLQuery expected")
                 SloTypes.LAG_TREND.value, SloTypes.LAG_TREND_RATIO.value -> slo.properties["promQLQuery"] ?:
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..047f8a657de8aba6f032d36e8b84d7046d5e0209
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloFactory.kt
@@ -0,0 +1,24 @@
+package rocks.theodolite.kubernetes.slo
+
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
+
+class SloFactory {
+
+    fun createSlos(execution: BenchmarkExecution, benchmark: KubernetesBenchmark): List<Slo> {
+        var benchmarkSlos = benchmark.slos
+        var executionSlos = execution.slos
+
+        for(executionSlo in executionSlos) {
+            for(i in 0 until benchmarkSlos.size) {
+                if(executionSlo.name == benchmarkSlos[i].name && executionSlo.properties != null) {
+                    for (executionProperty in executionSlo.properties!!) {
+                        benchmarkSlos[i].properties[executionProperty.key] = executionProperty.value
+                    }
+                }
+            }
+        }
+        return benchmarkSlos
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/SloJson.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloJson.kt
similarity index 78%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloJson.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloJson.kt
index 205389276f2c1adef6cba6c745baf99744c8d2dd..653ad6b5f998014a0f5b9e8b7397bcd3ce51f729 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloJson.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloJson.kt
@@ -1,7 +1,7 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
 import com.google.gson.Gson
-import theodolite.util.PromResult
+import rocks.theodolite.kubernetes.util.PromResult
 
 class SloJson constructor(
     val results: List<List<PromResult>>,
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/SloTypes.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloTypes.kt
similarity index 91%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloTypes.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloTypes.kt
index 812b50de779d2f3abfd5788b8aee145edc959e6c..07cbcd634ec7b46bd0e66a52f62989660575765f 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloTypes.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloTypes.kt
@@ -1,4 +1,4 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
 enum class SloTypes(val value: String) {
     GENERIC("generic"),
diff --git a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt
similarity index 73%
rename from theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt
index 1bbf3e01f461a19dbe588aedd41be63b84c86162..8cf3959b95374183a989a0217d754aea7eab716a 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt
@@ -1,14 +1,18 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes.standalone
 
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import mu.KotlinLogging
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.util.YamlParserFromFile
-import theodolite.util.EvaluationFailedException
-import theodolite.util.ExecutionFailedException
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.TheodoliteExecutor
+import rocks.theodolite.kubernetes.util.YamlParserFromFile
+import rocks.theodolite.kubernetes.slo.EvaluationFailedException
+import rocks.theodolite.kubernetes.ExecutionFailedException
+import rocks.theodolite.kubernetes.Shutdown
 import kotlin.concurrent.thread
 import kotlin.system.exitProcess
 
+
 private val logger = KotlinLogging.logger {}
 
 
@@ -27,7 +31,7 @@ private val logger = KotlinLogging.logger {}
  *
  * @constructor Create empty Theodolite yaml executor
  */
-class TheodoliteStandalone {
+class TheodoliteStandalone (private val client: NamespacedKubernetesClient) {
     private val parser = YamlParserFromFile()
 
     fun start() {
@@ -48,11 +52,11 @@ class TheodoliteStandalone {
 
         // Add shutdown hook
         // Use thread{} with start = false, else the thread will start right away
-        val shutdown = thread(start = false) { Shutdown(benchmarkExecution, benchmark).run() }
+        val shutdown = thread(start = false) { Shutdown(benchmarkExecution, benchmark, client).run() }
         Runtime.getRuntime().addShutdownHook(shutdown)
 
         try {
-            TheodoliteExecutor(benchmarkExecution, benchmark).run()
+            TheodoliteExecutor(benchmarkExecution, benchmark, client).setupAndRunExecution()
         } catch (e: EvaluationFailedException) {
             logger.error { "Evaluation failed with error: ${e.message}" }
         }catch (e: ExecutionFailedException) {
diff --git a/theodolite/src/main/kotlin/theodolite/util/ConfigurationOverride.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/ConfigurationOverride.kt
similarity index 81%
rename from theodolite/src/main/kotlin/theodolite/util/ConfigurationOverride.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/ConfigurationOverride.kt
index 537b44721bb344c2cd7af71d29dc4fa3da5a7a33..4b054d61c15c13b2058fd4848dd69fc4633610c8 100644
--- a/theodolite/src/main/kotlin/theodolite/util/ConfigurationOverride.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/ConfigurationOverride.kt
@@ -1,7 +1,8 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.util
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
 
 /**
  * Representation of a configuration override.
diff --git a/theodolite/src/main/kotlin/theodolite/util/Parser.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt
similarity index 89%
rename from theodolite/src/main/kotlin/theodolite/util/Parser.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt
index e435b1cbbf18b9f860ceda69f5f7ec66e64c9375..65cd6a39303d3f0f0814c7197bbe15b4919be5d7 100644
--- a/theodolite/src/main/kotlin/theodolite/util/Parser.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/Parser.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.util
 
 /**
  * Interface for parsers.
diff --git a/theodolite/src/main/kotlin/theodolite/util/YamlParserFromFile.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/util/YamlParserFromFile.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt
index 58ca925e6aeeaca4f2f35c97c027ee2d24188e50..f6a1179a880631dea7471b68b34c0823400aaadc 100644
--- a/theodolite/src/main/kotlin/theodolite/util/YamlParserFromFile.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromFile.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.util
 
 import org.yaml.snakeyaml.Yaml
 import org.yaml.snakeyaml.constructor.Constructor
diff --git a/theodolite/src/main/kotlin/theodolite/util/YamlParserFromString.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromString.kt
similarity index 90%
rename from theodolite/src/main/kotlin/theodolite/util/YamlParserFromString.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromString.kt
index 99c81f1ed674b2aa21f6aec7b3e0dff1b8c86840..288414422963ad3de8f6b853b949b4af7939bf6a 100644
--- a/theodolite/src/main/kotlin/theodolite/util/YamlParserFromString.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/util/YamlParserFromString.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.util
 
 import org.yaml.snakeyaml.Yaml
 import org.yaml.snakeyaml.constructor.Constructor
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt
deleted file mode 100644
index cf2fac7337d79c1c5daf2b0fac070200cf27f9a5..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package theodolite.benchmark
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.ConfigurationOverride
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-
-/**
- * A Benchmark contains:
- * - The [Resource]s that can be scaled for the benchmark.
- * - The [LoadDimension]s that can be scaled the benchmark.
- * - additional [ConfigurationOverride]s.
- */
-@RegisterForReflection
-interface Benchmark {
-
-    fun setupInfrastructure()
-    fun teardownInfrastructure()
-
-    /**
-     * Builds a Deployment that can be deployed.
-     * @return a BenchmarkDeployment.
-     */
-    fun buildDeployment(
-        load: LoadDimension,
-        res: Resource,
-        configurationOverrides: List<ConfigurationOverride?>,
-        loadGenerationDelay: Long,
-        afterTeardownDelay: Long
-    ): BenchmarkDeployment
-}
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
deleted file mode 100644
index 6857b9bf8918593dbe5085f40eb28fd8bd809d85..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-package theodolite.benchmark
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize
-import io.fabric8.kubernetes.api.model.HasMetadata
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.client.DefaultKubernetesClient
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient
-import io.quarkus.runtime.annotations.RegisterForReflection
-import mu.KotlinLogging
-import theodolite.k8s.K8sManager
-import theodolite.patcher.PatcherFactory
-import theodolite.util.*
-
-
-private val logger = KotlinLogging.logger {}
-
-private var DEFAULT_NAMESPACE = "default"
-private var DEFAULT_THEODOLITE_APP_RESOURCES = "./benchmark-resources"
-
-/**
- * Represents a benchmark in Kubernetes. An example for this is the BenchmarkType.yaml
- * Contains a of:
- * - [name] of the benchmark,
- * - [appResource] list of the resources that have to be deployed for the benchmark,
- * - [loadGenResource] resource that generates the load,
- * - [resourceTypes] types of scaling resources,
- * - [loadTypes] types of loads that can be scaled for the benchmark,
- * - [kafkaConfig] for the [theodolite.k8s.TopicManager],
- * - [namespace] for the client,
- * - [path] under which the resource yamls can be found.
- *
- *  This class is used for the parsing(in the [theodolite.execution.TheodoliteStandalone]) and
- *  for the deserializing in the [theodolite.execution.operator.TheodoliteOperator].
- * @constructor construct an empty Benchmark.
- */
-@JsonDeserialize
-@RegisterForReflection
-class KubernetesBenchmark : KubernetesResource, Benchmark {
-    lateinit var name: String
-    lateinit var resourceTypes: List<TypeName>
-    lateinit var loadTypes: List<TypeName>
-    var kafkaConfig: KafkaConfig? = null
-    lateinit var infrastructure: Resources
-    lateinit var sut: Resources
-    lateinit var loadGenerator: Resources
-    private var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
-
-    @Transient
-    private var client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace)
-
-    /**
-     * Loads [KubernetesResource]s.
-     * It first loads them via the [YamlParserFromFile] to check for their concrete type and afterwards initializes them using
-     * the [K8sResourceLoader]
-     */
-    @Deprecated("Use `loadResourceSet` from `ResourceSets`")
-    fun loadKubernetesResources(resourceSet: List<ResourceSets>): Collection<Pair<String, HasMetadata>> {
-        return loadResources(resourceSet)
-    }
-
-    private fun loadResources(resourceSet: List<ResourceSets>): Collection<Pair<String, HasMetadata>> {
-        return resourceSet.flatMap { it.loadResourceSet(this.client) }
-    }
-
-    override fun setupInfrastructure() {
-        this.infrastructure.beforeActions.forEach { it.exec(client = client) }
-        val kubernetesManager = K8sManager(this.client)
-        loadResources(this.infrastructure.resources)
-            .map { it.second }
-            .forEach { kubernetesManager.deploy(it) }
-    }
-
-    override fun teardownInfrastructure() {
-        val kubernetesManager = K8sManager(this.client)
-        loadResources(this.infrastructure.resources)
-            .map { it.second }
-            .forEach { kubernetesManager.remove(it) }
-        this.infrastructure.afterActions.forEach { it.exec(client = client) }
-    }
-
-    /**
-     * 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.
-     * @param configurationOverrides
-     * @return a [BenchmarkDeployment]
-     */
-    override fun buildDeployment(
-        load: LoadDimension,
-        res: Resource,
-        configurationOverrides: List<ConfigurationOverride?>,
-        loadGenerationDelay: Long,
-        afterTeardownDelay: Long
-    ): BenchmarkDeployment {
-        logger.info { "Using $namespace as namespace." }
-
-        val appResources = loadResources(this.sut.resources)
-        val loadGenResources = loadResources(this.loadGenerator.resources)
-
-        val patcherFactory = PatcherFactory()
-
-        // patch the load dimension the resources
-        load.getType().forEach { patcherDefinition ->
-            patcherFactory.createPatcher(patcherDefinition, loadGenResources).patch(load.get().toString())
-        }
-        res.getType().forEach { patcherDefinition ->
-            patcherFactory.createPatcher(patcherDefinition, appResources).patch(res.get().toString())
-        }
-
-        // Patch the given overrides
-        configurationOverrides.forEach { override ->
-            override?.let {
-                patcherFactory.createPatcher(it.patcher, appResources + loadGenResources).patch(override.value)
-            }
-        }
-
-        val kafkaConfig = this.kafkaConfig
-
-        return KubernetesBenchmarkDeployment(
-            sutBeforeActions = sut.beforeActions,
-            sutAfterActions = sut.afterActions,
-            loadGenBeforeActions = loadGenerator.beforeActions,
-            loadGenAfterActions = loadGenerator.afterActions,
-            appResources = appResources.map { it.second },
-            loadGenResources = loadGenResources.map { it.second },
-            loadGenerationDelay = loadGenerationDelay,
-            afterTeardownDelay = afterTeardownDelay,
-            kafkaConfig = if (kafkaConfig != null) mapOf("bootstrap.servers" to kafkaConfig.bootstrapServer) else mapOf(),
-            topics = kafkaConfig?.topics ?: listOf(),
-            client = this.client
-        )
-    }
-
-    /**
-     * This function can be used to set the Kubernetes client manually. This is for example necessary for testing.
-     *
-     * @param client
-     */
-    fun setClient(client: NamespacedKubernetesClient) {
-        this.client = client
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt
deleted file mode 100644
index fccbd2c41a646a2ef85ef77c65763e7f793d1e91..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package theodolite.benchmark
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize
-import io.quarkus.runtime.annotations.RegisterForReflection
-
-@JsonDeserialize
-@RegisterForReflection
-class Resources {
-
-    lateinit var resources: List<ResourceSets>
-    lateinit var beforeActions: List<Action>
-    lateinit var afterActions: List<Action>
-
-}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
deleted file mode 100644
index 3238f447be06ce6486bb7f6ca1758700f36ba558..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package theodolite.execution
-
-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.Results
-import java.time.Duration
-import java.util.concurrent.atomic.AtomicBoolean
-
-private val logger = KotlinLogging.logger {}
-
-/**
- * The Benchmark Executor runs a single experiment.
- *
- * @property benchmark
- * @property results
- * @property executionDuration
- * @constructor Create empty Benchmark executor
- */
-abstract class BenchmarkExecutor(
-    val benchmark: Benchmark,
-    val results: Results,
-    val executionDuration: Duration,
-    val configurationOverrides: List<ConfigurationOverride?>,
-    val slos: List<BenchmarkExecution.Slo>,
-    val repetitions: Int,
-    val executionId: Int,
-    val loadGenerationDelay: Long,
-    val afterTeardownDelay: Long,
-    val executionName: String
-) {
-
-    var run: AtomicBoolean = AtomicBoolean(true)
-
-    /**
-     * 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.
-     * @return True, if the number of resources are suitable for the
-     *     given load, false otherwise.
-     */
-    abstract fun runExperiment(load: LoadDimension, res: Resource): Boolean
-
-    /**
-     * Wait while the benchmark is running and log the number of minutes executed every 1 minute.
-     *
-     */
-    fun waitAndLog() {
-        logger.info { "Execution of a new experiment started." }
-
-        var secondsRunning = 0L
-
-        while (run.get() && secondsRunning < executionDuration.toSeconds()) {
-            secondsRunning++
-            Thread.sleep(Duration.ofSeconds(1).toMillis())
-
-            if ((secondsRunning % 60) == 0L) {
-                logger.info { "Executed: ${secondsRunning / 60} minutes." }
-            }
-        }
-
-        logger.debug { "Executor shutdown gracefully." }
-
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
deleted file mode 100644
index 8596576e0a7984c32b6dabf90c6bbf06961d2bb1..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
+++ /dev/null
@@ -1,164 +0,0 @@
-package theodolite.execution
-
-import mu.KotlinLogging
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.patcher.PatcherDefinitionFactory
-import theodolite.strategies.StrategyFactory
-import theodolite.strategies.searchstrategy.CompositeStrategy
-import theodolite.util.*
-import java.io.File
-import java.time.Duration
-
-
-private val logger = KotlinLogging.logger {}
-
-/**
- * The Theodolite executor runs all the experiments defined with the given execution and benchmark configuration.
- *
- * @property config Configuration of a execution
- * @property kubernetesBenchmark Configuration of a benchmark
- * @constructor Create empty Theodolite executor
- */
-class TheodoliteExecutor(
-    private val config: BenchmarkExecution,
-    private val kubernetesBenchmark: KubernetesBenchmark
-) {
-    /**
-     * An executor object, configured with the specified benchmark, evaluation method, experiment duration
-     * and overrides which are given in the execution.
-     */
-    lateinit var executor: BenchmarkExecutor
-
-    /**
-     * 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.
-     */
-    private fun buildConfig(): Config {
-        val results = Results()
-        val strategyFactory = StrategyFactory()
-
-        val executionDuration = Duration.ofSeconds(config.execution.duration)
-
-        val resourcePatcherDefinition =
-            PatcherDefinitionFactory().createPatcherDefinition(
-                config.resources.resourceType,
-                this.kubernetesBenchmark.resourceTypes
-            )
-
-        val loadDimensionPatcherDefinition =
-            PatcherDefinitionFactory().createPatcherDefinition(
-                config.load.loadType,
-                this.kubernetesBenchmark.loadTypes
-            )
-
-        executor =
-            BenchmarkExecutorImpl(
-                benchmark = kubernetesBenchmark,
-                results = results,
-                executionDuration = executionDuration,
-                configurationOverrides = config.configOverrides,
-                slos = config.slos,
-                repetitions = config.execution.repetitions,
-                executionId = config.executionId,
-                loadGenerationDelay = config.execution.loadGenerationDelay,
-                afterTeardownDelay = config.execution.afterTeardownDelay,
-                executionName = config.name
-            )
-
-        if (config.load.loadValues != config.load.loadValues.sorted()) {
-            config.load.loadValues = config.load.loadValues.sorted()
-            logger.info {
-                "Load values are not sorted correctly, Theodolite sorts them in ascending order." +
-                        "New order is: ${config.load.loadValues}"
-            }
-        }
-
-        if (config.resources.resourceValues != config.resources.resourceValues.sorted()) {
-            config.resources.resourceValues = config.resources.resourceValues.sorted()
-            logger.info {
-                "Load values are not sorted correctly, Theodolite sorts them in ascending order." +
-                        "New order is: ${config.resources.resourceValues}"
-            }
-        }
-
-        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
-                )
-            )
-        )
-    }
-
-    fun getExecution(): BenchmarkExecution {
-        return this.config
-    }
-
-    /**
-     * Run all experiments which are specified in the corresponding
-     * execution and benchmark objects.
-     */
-    fun run() {
-        kubernetesBenchmark.setupInfrastructure()
-
-        val ioHandler = IOHandler()
-        val resultsFolder = ioHandler.getResultFolderURL()
-        this.config.executionId = getAndIncrementExecutionID(resultsFolder + "expID.txt")
-        ioHandler.writeToJSONFile(this.config, "${resultsFolder}exp${this.config.executionId}-execution-configuration")
-        ioHandler.writeToJSONFile(
-            kubernetesBenchmark,
-            "${resultsFolder}exp${this.config.executionId}-benchmark-configuration"
-        )
-
-        val config = buildConfig()
-        // execute benchmarks for each load
-        try {
-            for (load in config.loads) {
-                if (executor.run.get()) {
-                    config.compositeStrategy.findSuitableResource(load, config.resources)
-                }
-            }
-        } finally {
-            ioHandler.writeToJSONFile(
-                config.compositeStrategy.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")
-            )
-        }
-        kubernetesBenchmark.teardownInfrastructure()
-    }
-
-    private fun getAndIncrementExecutionID(fileURL: String): Int {
-        val ioHandler = IOHandler()
-        var executionID = 0
-        if (File(fileURL).exists()) {
-            executionID = ioHandler.readFileAsString(fileURL).toInt() + 1
-        }
-        ioHandler.writeStringToTextFile(fileURL, (executionID).toString())
-        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()) }
-    }
-
-}
diff --git a/theodolite/src/main/kotlin/theodolite/k8s/K8sManager.kt b/theodolite/src/main/kotlin/theodolite/k8s/K8sManager.kt
deleted file mode 100644
index 5b4880b45db76d9e68e87fda0ece5b04966439c8..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/k8s/K8sManager.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package theodolite.k8s
-
-import io.fabric8.kubernetes.api.model.ConfigMap
-import io.fabric8.kubernetes.api.model.HasMetadata
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.Service
-import io.fabric8.kubernetes.api.model.apps.Deployment
-import io.fabric8.kubernetes.api.model.apps.StatefulSet
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient
-import mu.KotlinLogging
-
-private val logger = KotlinLogging.logger {}
-
-/**
- * This class is used to deploy or remove different Kubernetes resources.
- * Supports: Deployments, Services, ConfigMaps, StatefulSets, and CustomResources.
- * @param client KubernetesClient used to deploy or remove.
- */
-class K8sManager(private val client: NamespacedKubernetesClient) {
-
-    /**
-     * Deploys different k8s resources using the client.
-     * @throws IllegalArgumentException if KubernetesResource not supported.
-     */
-    fun deploy(resource: HasMetadata) {
-        client.resource(resource).createOrReplace()
-    }
-
-    /**
-     * Removes different k8s resources using the client.
-     * @throws IllegalArgumentException if KubernetesResource not supported.
-     */
-    fun remove(resource: HasMetadata) {
-        client.resource(resource).delete()
-        when (resource) {
-            is Deployment -> {
-                ResourceByLabelHandler(client = client)
-                    .blockUntilPodsDeleted(
-                        matchLabels = resource.spec.selector.matchLabels
-                    )
-                logger.info { "Deployment '${resource.metadata.name}' deleted." }
-            }
-            is StatefulSet -> {
-                ResourceByLabelHandler(client = client)
-                    .blockUntilPodsDeleted(
-                        matchLabels = resource.spec.selector.matchLabels
-                    )
-                logger.info { "StatefulSet '$resource.metadata.name' deleted." }
-            }
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
deleted file mode 100644
index df80e9cbd2503685a7dbed35db5319920dfc42cb..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-
-/**
- * A Patcher is able to modify values of a Kubernetes resource, see [Patcher].
- *
- * An AbstractPatcher is created with up to three parameters.
- *
- * @param k8sResource The Kubernetes resource to be patched.
- * @param container *(optional)* The name of the container to be patched
- * @param variableName *(optional)* The variable name to be patched
- *
- *
- * **For example** to patch the load dimension of a load generator, the patcher should be created as follow:
- *
- * k8sResource: `uc-1-workload-generator.yaml`
- * container: `workload`
- * variableName: `NUM_SENSORS`
- *
- */
-abstract class AbstractPatcher(
-    k8sResource: KubernetesResource
-) : Patcher
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt
deleted file mode 100644
index 8f6753372076c119324dc962112928253633b6b0..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-import io.fabric8.kubernetes.api.model.apps.StatefulSet
-
-/**
- * The Image patcher allows to change the image of a container.
- *
- * @param k8sResource Kubernetes resource to be patched.
- * @param container Container to be patched.
- */
-class ImagePatcher(private val k8sResource: KubernetesResource, private val container: String) :
-    AbstractPatcher(k8sResource) {
-
-    override fun <String> patch(imagePath: String) {
-        if (k8sResource is Deployment) {
-            k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach {
-                it.image = imagePath as kotlin.String
-            }
-        } else if (k8sResource is StatefulSet) {
-            k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach {
-                it.image = imagePath as kotlin.String
-            }
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt
deleted file mode 100644
index 2f8c703afa9e826a79f0785abef493d2d448ac74..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.ConfigMap
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.Service
-import io.fabric8.kubernetes.api.model.apps.Deployment
-import io.fabric8.kubernetes.api.model.apps.StatefulSet
-import io.fabric8.kubernetes.client.CustomResource
-
-class LabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) :
-    AbstractPatcher(k8sResource) {
-
-    override fun <String> patch(labelValue: String) {
-        if (labelValue is kotlin.String) {
-            when (k8sResource) {
-                is Deployment -> {
-                    if (k8sResource.metadata.labels == null) {
-                        k8sResource.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.metadata.labels[this.variableName] = labelValue
-                }
-                is StatefulSet -> {
-                    if (k8sResource.metadata.labels == null) {
-                        k8sResource.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.metadata.labels[this.variableName] = labelValue
-                }
-                is Service -> {
-                    if (k8sResource.metadata.labels == null) {
-                        k8sResource.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.metadata.labels[this.variableName] = labelValue
-                }
-                is ConfigMap -> {
-                    if (k8sResource.metadata.labels == null) {
-                        k8sResource.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.metadata.labels[this.variableName] = labelValue
-                }
-                is CustomResource<*, *> -> {
-                    if (k8sResource.metadata.labels == null) {
-                        k8sResource.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.metadata.labels[this.variableName] = labelValue
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt
deleted file mode 100644
index 30ff73b5da3b551119ad085adbc982180e4fc066..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-import io.fabric8.kubernetes.api.model.apps.StatefulSet
-
-/**
- * This patcher is able to set the `spec.selector.matchLabels` for a `Deployment` or `StatefulSet` Kubernetes resource.
- *
- * @property k8sResource The Kubernetes manifests to patch
- * @property variableName The matchLabel which should be set
- */
-class MatchLabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) :
-    AbstractPatcher(k8sResource) {
-
-    override fun <String> patch(labelValue: String) {
-        if (labelValue is kotlin.String) {
-            when (k8sResource) {
-                is Deployment -> {
-                    if (k8sResource.spec.selector.matchLabels == null) {
-                        k8sResource.spec.selector.matchLabels = mutableMapOf()
-                    }
-                    k8sResource.spec.selector.matchLabels[this.variableName] = labelValue
-                }
-                is StatefulSet -> {
-                    if (k8sResource.spec.selector.matchLabels == null) {
-                        k8sResource.spec.selector.matchLabels = mutableMapOf()
-                    }
-                    k8sResource.spec.selector.matchLabels[this.variableName] = labelValue
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt
deleted file mode 100644
index 0e8cd553a6c6a9ed6fa2c8cc1b84e4cfebe79d73..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-
-/**
- * The Node selector patcher make it possible to set the NodeSelector of a Kubernetes deployment.
- *
- * @param k8sResource Kubernetes resource to be patched.
- * @param variableName The `label-key` of the node for which the `label-value` is to be patched.
- */
-class NodeSelectorPatcher(private val k8sResource: KubernetesResource, private val variableName: String) :
-    AbstractPatcher(k8sResource) {
-    override fun <String> patch(value: String) {
-        if (k8sResource is Deployment) {
-            k8sResource.spec.template.spec.nodeSelector = mapOf(variableName to value as kotlin.String)
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
deleted file mode 100644
index c617917e6894c3a30779dd4257a96365ded35481..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-import kotlin.math.pow
-
-class NumNestedGroupsLoadGeneratorReplicaPatcher(
-    private val k8sResource: KubernetesResource,
-    private val numSensors: String,
-    private val loadGenMaxRecords: String
-) :
-    AbstractPatcher(k8sResource) {
-    override fun <String> patch(value: String) {
-        if (k8sResource is Deployment) {
-            if (value is kotlin.String) {
-                val approxNumSensors = numSensors.toDouble().pow(Integer.parseInt(value).toDouble())
-                val loadGenInstances =
-                    (approxNumSensors + loadGenMaxRecords.toDouble() - 1) / loadGenMaxRecords.toDouble()
-                this.k8sResource.spec.replicas = loadGenInstances.toInt()
-            }
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
deleted file mode 100644
index 86bb37db3cb9fd0d3bca1690d5eb4e622329a9bc..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-
-
-class NumSensorsLoadGeneratorReplicaPatcher(
-    private val k8sResource: KubernetesResource,
-    private val loadGenMaxRecords: String
-) :
-    AbstractPatcher(k8sResource) {
-    override fun <String> patch(value: String) {
-        if (k8sResource is Deployment) {
-            if (value is kotlin.String) {
-                val loadGenInstances =
-                    (Integer.parseInt(value) + loadGenMaxRecords.toInt() - 1) / loadGenMaxRecords.toInt()
-                this.k8sResource.spec.replicas = loadGenInstances
-            }
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt b/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt
deleted file mode 100644
index e92de4dba7de298c9df76600f2c6785f5878103e..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import theodolite.util.InvalidPatcherConfigurationException
-import theodolite.util.PatcherDefinition
-
-/**
- * The Patcher factory creates [Patcher]s
- *
- * @constructor Creates an empty PatcherFactory.
- */
-class PatcherFactory {
-    /**
-     * Create patcher based on the given [PatcherDefinition] and
-     * the list of KubernetesResources.
-     *
-     * @param patcherDefinition The [PatcherDefinition] for which are
-     *     [Patcher] should be created.
-     * @param k8sResources List of all available Kubernetes resources.
-     *     This is a list of pairs<String, KubernetesResource>:
-     *     The frist corresponds to the filename where the resource is defined.
-     *     The second corresponds to the concrete [KubernetesResource] that should be patched.
-     * @return The created [Patcher].
-     * @throws IllegalArgumentException if no patcher can be created.
-     */
-    fun createPatcher(
-        patcherDefinition: PatcherDefinition,
-        k8sResources: Collection<Pair<String, KubernetesResource>>
-    ): Patcher {
-        val resource =
-            k8sResources.filter { it.first == patcherDefinition.resource }
-                .map { resource -> resource.second }
-                .firstOrNull()
-                ?: throw InvalidPatcherConfigurationException("Could not find resource ${patcherDefinition.resource}")
-
-        return try {
-            when (patcherDefinition.type) {
-                "ReplicaPatcher" -> ReplicaPatcher(
-                    k8sResource = resource
-                )
-                "NumNestedGroupsLoadGeneratorReplicaPatcher" -> NumNestedGroupsLoadGeneratorReplicaPatcher(
-                    k8sResource = resource,
-                    loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!!,
-                    numSensors = patcherDefinition.properties["numSensors"]!!
-                )
-                "NumSensorsLoadGeneratorReplicaPatcher" -> NumSensorsLoadGeneratorReplicaPatcher(
-                    k8sResource = resource,
-                    loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!!
-                )
-                "DataVolumeLoadGeneratorReplicaPatcher" -> DataVolumeLoadGeneratorReplicaPatcher(
-                    k8sResource = resource,
-                    maxVolume = patcherDefinition.properties["maxVolume"]!!.toInt(),
-                    container = patcherDefinition.properties["container"]!!,
-                    variableName = patcherDefinition.properties["variableName"]!!
-                )
-                "EnvVarPatcher" -> EnvVarPatcher(
-                    k8sResource = resource,
-                    container = patcherDefinition.properties["container"]!!,
-                    variableName = patcherDefinition.properties["variableName"]!!
-                )
-                "NodeSelectorPatcher" -> NodeSelectorPatcher(
-                    k8sResource = resource,
-                    variableName = patcherDefinition.properties["variableName"]!!
-                )
-                "ResourceLimitPatcher" -> ResourceLimitPatcher(
-                    k8sResource = resource,
-                    container = patcherDefinition.properties["container"]!!,
-                    limitedResource = patcherDefinition.properties["limitedResource"]!!
-                )
-                "ResourceRequestPatcher" -> ResourceRequestPatcher(
-                    k8sResource = resource,
-                    container = patcherDefinition.properties["container"]!!,
-                    requestedResource = patcherDefinition.properties["requestedResource"]!!
-                )
-                "SchedulerNamePatcher" -> SchedulerNamePatcher(
-                    k8sResource = resource
-                )
-                "LabelPatcher" -> LabelPatcher(
-                    k8sResource = resource,
-                    variableName = patcherDefinition.properties["variableName"]!!
-                )
-                "MatchLabelPatcher" -> MatchLabelPatcher(
-                    k8sResource = resource,
-                    variableName = patcherDefinition.properties["variableName"]!!
-                )
-                "TemplateLabelPatcher" -> TemplateLabelPatcher(
-                    k8sResource = resource,
-                    variableName = patcherDefinition.properties["variableName"]!!
-                )
-                "ImagePatcher" -> ImagePatcher(
-                    k8sResource = resource,
-                    container = patcherDefinition.properties["container"]!!
-                )
-                else -> throw InvalidPatcherConfigurationException("Patcher type ${patcherDefinition.type} not found.")
-            }
-        } catch (e: NullPointerException) {
-            throw InvalidPatcherConfigurationException(
-                "Could not create patcher with type ${patcherDefinition.type}" +
-                        " Probably a required patcher argument was not specified.", e
-            )
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
deleted file mode 100644
index 4cc35f2ed74f9e366c266c3f98f1b3d36d4ba1b8..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-
-/**
- * The Replica [Patcher] modifies the number of replicas for the given Kubernetes deployment.
- *
- * @param k8sResource  Kubernetes resource to be patched.
- */
-class ReplicaPatcher(private val k8sResource: KubernetesResource) : AbstractPatcher(k8sResource) {
-    override fun <String> patch(value: String) {
-        if (k8sResource is Deployment) {
-            if (value is kotlin.String) {
-                this.k8sResource.spec.replicas = Integer.parseInt(value)
-            }
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
deleted file mode 100644
index 348f0c50090a34c91221d3e099c3532375a578da..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-
-/**
- * The Scheduler name [Patcher] make it possible to set the scheduler which should
- * be used to deploy the given deployment.
- * @param k8sResource Kubernetes resource to be patched.
- */
-class SchedulerNamePatcher(private val k8sResource: KubernetesResource) : Patcher {
-    override fun <String> patch(value: String) {
-        if (k8sResource is Deployment) {
-            k8sResource.spec.template.spec.schedulerName = value as kotlin.String
-        }
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt
deleted file mode 100644
index a524e5c40f90ccf98dc95003cc33dcfceb6f8598..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package theodolite.patcher
-
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.api.model.apps.Deployment
-import io.fabric8.kubernetes.api.model.apps.StatefulSet
-
-/**
- * This patcher is able to set the field `spec.template.metadata.labels` for a `Deployment` or `StatefulSet` Kubernetes resource.
- *
- * @property k8sResource The Kubernetes manifests to patch
- * @property variableName The label which should be set
- */
-class TemplateLabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) :
-    AbstractPatcher(k8sResource) {
-
-    override fun <String> patch(labelValue: String) {
-        if (labelValue is kotlin.String) {
-            when (k8sResource) {
-                is Deployment -> {
-                    if (k8sResource.spec.template.metadata.labels == null) {
-                        k8sResource.spec.template.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.spec.template.metadata.labels[this.variableName] = labelValue
-                }
-                is StatefulSet -> {
-                    if (k8sResource.spec.template.metadata.labels == null) {
-                        k8sResource.spec.template.metadata.labels = mutableMapOf()
-                    }
-                    k8sResource.spec.template.metadata.labels[this.variableName] = labelValue
-                }
-            }
-        }
-    }
-}
\ 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
deleted file mode 100644
index 829370e8ce1c181c1a4cb9fdd8ccf0ecefd48d3d..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package theodolite.strategies
-
-import theodolite.execution.BenchmarkExecutor
-import theodolite.strategies.restriction.LowerBoundRestriction
-import theodolite.strategies.restriction.RestrictionStrategy
-import theodolite.strategies.searchstrategy.BinarySearch
-import theodolite.strategies.searchstrategy.FullSearch
-import theodolite.strategies.searchstrategy.LinearSearch
-import theodolite.strategies.searchstrategy.SearchStrategy
-import theodolite.util.Results
-
-/**
- * Factory for creating [SearchStrategy] and [RestrictionStrategy] strategies.
- */
-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'.
-     *
-     * @throws IllegalArgumentException if the [SearchStrategy] was not one of the allowed options.
-     */
-    fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyString: String): SearchStrategy {
-        return when (searchStrategyString) {
-            "FullSearch" -> FullSearch(executor)
-            "LinearSearch" -> LinearSearch(executor)
-            "BinarySearch" -> BinarySearch(executor)
-            else -> throw IllegalArgumentException("Search Strategy $searchStrategyString not found")
-        }
-    }
-
-    /**
-     * Create a [RestrictionStrategy].
-     *
-     * @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'.
-     *
-     * @throws IllegalArgumentException if param searchStrategyString was not one of the allowed options.
-     */
-    fun createRestrictionStrategy(results: Results, restrictionStrings: List<String>): Set<RestrictionStrategy> {
-        return restrictionStrings
-            .map { restriction ->
-                when (restriction) {
-                    "LowerBound" -> LowerBoundRestriction(results)
-                    else -> throw IllegalArgumentException("Restriction Strategy $restrictionStrings not found")
-                }
-            }.toSet()
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt b/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
deleted file mode 100644
index 13bfedfe055f2bd428137f89b2986f3967ec797c..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-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.
- *
- * @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)
-        if (lowerBound == null) {
-            lowerBound = resources[0]
-        }
-        return resources.filter { x -> x.get() >= lowerBound.get() }
-    }
-
-}
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
deleted file mode 100644
index 1ab7302d7898daad729b1c94c32d97138b5cdcf4..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-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
- * results of all previously performed benchmarks.
- *
- * @param results the [Results] object
- */
-@RegisterForReflection
-abstract class RestrictionStrategy(val results: Results) {
-    /**
-     * Apply the restriction of the given resource list for the given load based on the results object.
-     *
-     * @param load [LoadDimension] for which a subset of resources are required.
-     * @param resources List of [Resource]s to be restricted.
-     * @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>
-}
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
deleted file mode 100644
index 28e8194c699cd074026c8cb7e6f3ce4ec347023b..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-package theodolite.strategies.searchstrategy
-
-import mu.KotlinLogging
-import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-
-private val logger = KotlinLogging.logger {}
-
-/**
- *  Binary-search-like implementation for determining the smallest suitable number of instances.
- *
- * @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)
-        if (result == -1) {
-            return null
-        }
-        return resources[result]
-    }
-
-    /**
-     * Apply binary search.
-     *
-     * @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)
-     */
-    private fun binarySearch(load: LoadDimension, resources: List<Resource>, lower: Int, upper: Int): Int {
-        if (lower > upper) {
-            throw IllegalArgumentException()
-        }
-        // special case:  length == 1 or 2
-        if (lower == upper) {
-            val res = resources[lower]
-            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
-            if (this.benchmarkExecutor.runExperiment(load, resources[lower])) return lower
-            else {
-                if (lower + 1 == resources.size) return -1
-                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) / 2
-            val res = resources[mid]
-            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
-            if (this.benchmarkExecutor.runExperiment(load, resources[mid])) {
-                if (mid == lower) {
-                    return lower
-                }
-                return binarySearch(load, resources, lower, mid - 1)
-            } else {
-                return binarySearch(load, resources, mid + 1, upper)
-            }
-        }
-    }
-}
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
deleted file mode 100644
index 83c4abbdf44f1a1c2f3a27714d796580feedee49..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package theodolite.strategies.searchstrategy
-
-import mu.KotlinLogging
-import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-
-private val logger = KotlinLogging.logger {}
-
-/**
- * [SearchStrategy] that executes experiment for provides resources in a linear-search-like fashion, but **without
- * stopping** once a suitable resource amount is found.
- *
- * @see LinearSearch for a SearchStrategy that stops once a suitable resource amount is found.
- *
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
- */
-class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
-
-    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
-        var minimalSuitableResources: Resource? = null
-        for (res in resources) {
-            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
-            val result = this.benchmarkExecutor.runExperiment(load, res)
-            if (result && minimalSuitableResources == null) {
-                minimalSuitableResources = res
-            }
-        }
-        return minimalSuitableResources
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
deleted file mode 100644
index 786a3baf159e94841c1f76c696f030718e8f768f..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-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.
- */
-
-@RegisterForReflection
-abstract class GuessStrategy {
-    /**
-     * Computing the resource demand 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.
-     *
-     * @return Returns the resource demand to start the initial guess search strategy with or null
-     */
-    abstract fun firstGuess(resources: List<Resource>, lastLowestResource: Resource?): Resource?
-}
\ 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
deleted file mode 100644
index d97fb62cc9d37dd50122199e5d089c491784e511..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-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 {}
-
-/**
- *  Search strategy implementation for determining the smallest suitable resource demand.
- *  Starting with a resource amount provided by a guess strategy.
- *
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
- * @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) {
-
-    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
-        }
-
-
-        var lastLowestResource : Resource? = 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
-        }
-        lastLowestResource = this.guessStrategy.firstGuess(resources, lastLowestResource)
-
-        if (lastLowestResource != null) {
-            val resourcesToCheck: List<Resource>
-            val startIndex: Int = resources.indexOf(lastLowestResource)
-
-            logger.info { "Running experiment with load '${load.get()}' and resources '${lastLowestResource.get()}'" }
-
-            // If the first experiment passes, starting downward linear search
-            // otherwise starting upward linear search
-            if (this.benchmarkExecutor.runExperiment(load, lastLowestResource)) {
-
-                resourcesToCheck = resources.subList(0, startIndex).reversed()
-                if (resourcesToCheck.isEmpty()) return lastLowestResource
-
-                var currentMin: Resource = lastLowestResource
-                for (res in resourcesToCheck) {
-
-                    logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
-                    if (this.benchmarkExecutor.runExperiment(load, res)) {
-                        currentMin = res
-                    }
-                }
-                return currentMin
-            }
-            else {
-                if (resources.size <= startIndex + 1) {
-                    logger.info{ "No more resources left to check." }
-                    return null
-                }
-                resourcesToCheck = resources.subList(startIndex + 1, resources.size)
-
-                for (res in resourcesToCheck) {
-
-                    logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
-                    if (this.benchmarkExecutor.runExperiment(load, res)) return res
-                }
-            }
-        }
-        else {
-            logger.info { "InitialGuessSearchStrategy called without lastLowestResource value, which is needed as a " +
-                    "starting point!" }
-        }
-        return null
-    }
-}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
deleted file mode 100644
index 85deaf6fa75437199bfc560404eb5b40bb4a986a..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-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.
- *
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
- */
-class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
-
-    override fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource? {
-        for (res in resources) {
-
-            logger.info { "Running experiment with load '${load.get()}' and resources '${res.get()}'" }
-            if (this.benchmarkExecutor.runExperiment(load, res)) return res
-        }
-        return null
-    }
-}
diff --git a/theodolite/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/SearchStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
deleted file mode 100644
index 97c723f2cfe459081cbb327f6860e48319c8f4f1..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package theodolite.strategies.searchstrategy
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.execution.BenchmarkExecutor
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-import theodolite.util.Results
-
-/**
- *  Base class for the implementation for SearchStrategies. SearchStrategies determine the smallest suitable number of instances.
- *
- * @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) {
-    /**
-     * Find 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.
-     *
-     * @return suitable resource for the specified load, or null if no suitable resource exists.
-     */
-    abstract fun findSuitableResource(load: LoadDimension, resources: List<Resource>): Resource?
-}
diff --git a/theodolite/src/main/kotlin/theodolite/util/Config.kt b/theodolite/src/main/kotlin/theodolite/util/Config.kt
deleted file mode 100644
index afbf784e9d6d72939615e367b54891ecd95a3608..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/util/Config.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package theodolite.util
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.strategies.searchstrategy.CompositeStrategy
-
-/**
- * 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
- */
-@RegisterForReflection
-data class Config(
-    val loads: List<LoadDimension>,
-    val resources: List<Resource>,
-    val compositeStrategy: CompositeStrategy
-)
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
deleted file mode 100644
index 2221c2e64f6dbc1776122f20793aa8d04d621d9d..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/util/Results.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-package theodolite.util
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-
-/**
- * Central class that saves the state of an execution of Theodolite. For an execution, it is used to save the result of
- * individual experiments. Further, it is used by the RestrictionStrategy to
- * perform the [theodolite.strategies.restriction.RestrictionStrategy].
- */
-@RegisterForReflection
-class Results {
-    private val results: MutableMap<Pair<LoadDimension, Resource>, Boolean> = mutableMapOf()
-
-    /**
-     * Set the result for an experiment.
-     *
-     * @param experiment A pair that identifies the experiment by the [LoadDimension] and [Resource].
-     * @param successful the result of the experiment. Successful == true and Unsuccessful == false.
-     */
-    fun setResult(experiment: Pair<LoadDimension, Resource>, successful: Boolean) {
-        this.results[experiment] = successful
-    }
-
-    /**
-     * Get the result for an experiment.
-     *
-     * @param experiment A pair that identifies the experiment by the [LoadDimension] 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? {
-        return this.results[experiment]
-    }
-
-    /**
-     * Get the smallest suitable number of instances for a specified [LoadDimension].
-     *
-     * @param load the [LoadDimension]
-     *
-     * @return the smallest suitable number of resources. If the experiment was not executed yet,
-     * a @see Resource with the constant Int.MAX_VALUE as value is returned.
-     * If no experiments have been marked as either successful or unsuccessful
-     * yet, a Resource with the constant value Int.MIN_VALUE is returned.
-     */
-    fun getMinRequiredInstances(load: LoadDimension?): Resource {
-        if (this.results.isEmpty()) {
-            return Resource(Int.MIN_VALUE, emptyList())
-        }
-
-        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
-                }
-            }
-        }
-        return minRequiredInstances
-    }
-
-    /**
-     * Get the largest [LoadDimension] that has been reported executed successfully (or unsuccessfully) so far, for a
-     * [LoadDimension] and is smaller than the given [LoadDimension].
-     *
-     * @param load the [LoadDimension]
-     *
-     * @return the largest [LoadDimension] or null, if there is none for this [LoadDimension]
-     */
-    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
-                }
-            }
-        }
-        return maxBenchmarkedLoad
-    }
-
-    /**
-     * Checks whether the results are empty.
-     *
-     * @return true if [results] is empty.
-     */
-    fun isEmpty(): Boolean{
-        return results.isEmpty()
-    }
-}
diff --git a/theodolite/src/main/kotlin/theodolite/util/TypeName.kt b/theodolite/src/main/kotlin/theodolite/util/TypeName.kt
deleted file mode 100644
index f20fc7c9ce6757be75d9317e76c23a68b09914bd..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/util/TypeName.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package theodolite.util
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize
-import io.quarkus.runtime.annotations.RegisterForReflection
-
-/**
- * The TypeName encapsulates a list of [PatcherDefinition] along with a typeName that specifies for what the [PatcherDefinition] should be used.
- */
-@RegisterForReflection
-@JsonDeserialize
-class TypeName {
-    lateinit var typeName: String
-    lateinit var patchers: List<PatcherDefinition>
-}
diff --git a/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/IOHandlerTest.kt
similarity index 96%
rename from theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/IOHandlerTest.kt
index 3b31f389bdeb35e6016a56a98abb1e13bf83ae18..65e84d7dd37eb5b68f77bc2d47d212db2f720a90 100644
--- a/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/IOHandlerTest.kt
@@ -1,4 +1,4 @@
-package theodolite.util
+package rocks.theodolite.core
 
 import com.google.gson.GsonBuilder
 import io.quarkus.test.junit.QuarkusTest
@@ -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/rocks/theodolite/core/ResultsTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/ResultsTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2dbeb44b90f780975af884028335a7e398c7cfdc
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/ResultsTest.kt
@@ -0,0 +1,91 @@
+package rocks.theodolite.core
+
+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.Test
+import rocks.theodolite.core.strategies.Metric
+
+@QuarkusTest
+internal class ResultsTest {
+
+    @Test
+    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.getOptYDimensionValue(20000)
+
+        assertNotNull(minRequiredInstances)
+        assertEquals(2, minRequiredInstances)
+    }
+
+    @Test
+    fun testGetMaxBenchmarkedLoadWhenAllSuccessfulDemand() {
+        val results = Results(Metric.from("demand"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(10000, 2), true)
+
+        val test1 = results.getMaxBenchmarkedXDimensionValue(100000)
+
+        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)
+    }
+
+    @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 testGetMaxBenchmarkedLoadWhenAllSuccessfulCapacity() {
+        val results = Results(Metric.from("capacity"))
+        results.setResult(Pair(10000, 1), true)
+        results.setResult(Pair(10000, 2), true)
+
+        val test1 = results.getMaxBenchmarkedXDimensionValue(5)
+
+        assertNotNull(test1)
+        assertEquals(2, test1)
+    }
+
+    @Test
+    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.getMaxBenchmarkedXDimensionValue(5)
+
+        assertNotNull(test2)
+        assertEquals(2, test2)
+    }
+}
diff --git a/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestrictionTest.kt
similarity index 53%
rename from theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestrictionTest.kt
index b368647e314a4d803b444268c8218aefbee00ad4..79fadb4867a155ee7b4dc86e4bb165947a4f15a4 100644
--- a/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestrictionTest.kt
@@ -1,25 +1,21 @@
-package theodolite.strategies.restriction
+package rocks.theodolite.core.strategies.restrictionstrategy
 
 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.util.Results
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.strategies.restrictionstrategy.LowerBoundRestriction
+import rocks.theodolite.core.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 +24,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 +41,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/InitialGuessSearchStrategyTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategyTest.kt
similarity index 52%
rename from theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategyTest.kt
index 1af6f548b219697009c688ace712a9f7f5620bd0..820dc7564aac2497a2884ca004f15110bc5465f7 100644
--- a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategyTest.kt
@@ -1,15 +1,15 @@
-package theodolite
+package rocks.theodolite.core.strategies.searchstrategy
 
 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.searchstrategy.InitialGuessSearchStrategy
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-import theodolite.util.Results
+import rocks.theodolite.core.strategies.Metric
 import mu.KotlinLogging
-import theodolite.strategies.searchstrategy.PrevResourceMinGuess
+import rocks.theodolite.kubernetes.TestBenchmarkDeploymentBuilder
+import rocks.theodolite.kubernetes.TestExperimentRunnerImpl
+import rocks.theodolite.core.strategies.guessstrategy.PrevInstanceOptGuess
+import rocks.theodolite.core.Results
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
 
 private val logger = KotlinLogging.logger {}
 
@@ -27,23 +27,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 benchmark = TestBenchmark()
-        val guessStrategy = PrevResourceMinGuess()
-        val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val guessStrategy = PrevInstanceOptGuess()
+        val sloChecker = Slo()
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, 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 +65,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 benchmark = TestBenchmark()
-        val guessStrategy = PrevResourceMinGuess()
-        val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val guessStrategy = PrevInstanceOptGuess()
+        val sloChecker = Slo()
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, 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 +103,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 benchmark = TestBenchmark()
-        val guessStrategy = PrevResourceMinGuess()
-        val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..6).toList()
+        val results = Results(Metric.from("demand"))
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val guessStrategy = PrevInstanceOptGuess()
+        val sloChecker = Slo()
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, 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/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearchTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearchTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..bae944801fcacf40431559a0e7ddeb78923d2173
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearchTest.kt
@@ -0,0 +1,148 @@
+package rocks.theodolite.core.strategies.searchstrategy
+
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
+import rocks.theodolite.kubernetes.TestBenchmarkDeploymentBuilder
+import rocks.theodolite.kubernetes.TestExperimentRunnerImpl
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.strategies.restrictionstrategy.LowerBoundRestriction
+import rocks.theodolite.core.Results
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
+
+@QuarkusTest
+class RestrictionSearchTest {
+
+
+    @Test
+    fun restrictionSearchTestLinearSearch() {
+        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 benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val sloChecker = Slo()
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
+        val linearSearch = LinearSearch(benchmarkExecutor)
+        val lowerBoundRestriction = LowerBoundRestriction(results)
+        val strategy =
+            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 benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val sloChecker = Slo()
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
+        val fullSearch = FullSearch(benchmarkExecutor)
+        val lowerBoundRestriction = LowerBoundRestriction(results)
+        val strategy =
+                RestrictionSearch(benchmarkExecutor, fullSearch, 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 restrictionSearchTestBinarySearch() {
+        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 benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val sloChecker = Slo()
+        val benchmarkExecutorImpl =
+            TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 0)
+        val binarySearch = BinarySearch(benchmarkExecutorImpl)
+        val lowerBoundRestriction = LowerBoundRestriction(results)
+        val strategy = RestrictionSearch(benchmarkExecutorImpl, binarySearch, 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 restrictionSearchTestBinarySearch2() {
+        val mockResults = arrayOf(
+            arrayOf(true, true, true, true, true, true, true, true),
+            arrayOf(false, false, true, true, true, true, true, true),
+            arrayOf(false, false, true, true, true, true, true, true),
+            arrayOf(false, false, false, true, true, true, true, true),
+            arrayOf(false, false, false, false, true, true, true, true),
+            arrayOf(false, false, false, false, false, false, true, true),
+            arrayOf(false, false, false, false, false, false, false, true)
+        )
+        val mockLoads: List<Int> = (0..6).toList()
+        val mockResources: List<Int> = (0..7).toList()
+        val results = Results(Metric.from("demand"))
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
+        val sloChecker = Slo()
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 0)
+        val binarySearch = BinarySearch(benchmarkExecutor)
+        val lowerBoundRestriction = LowerBoundRestriction(results)
+        val strategy =
+            RestrictionSearch(benchmarkExecutor, binarySearch, setOf(lowerBoundRestriction))
+
+        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))
+        }
+
+        assertEquals(actual, expected)
+    }
+}
diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt
similarity index 77%
rename from theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt
index 47f0e52f45e46e3cda093ff1b9722071f22ef7e8..008bc302f1ba9a246b7bd898aec712f305c5b288 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.api.model.Pod
 import io.fabric8.kubernetes.api.model.PodBuilder
@@ -8,9 +8,9 @@ import io.fabric8.kubernetes.client.utils.Utils
 import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.*
 import org.junit.jupiter.api.Assertions.assertEquals
-import theodolite.execution.operator.TheodoliteController
-import theodolite.execution.operator.TheodoliteOperator
-import theodolite.util.ActionCommandFailedException
+import rocks.theodolite.kubernetes.operator.TheodoliteController
+import rocks.theodolite.kubernetes.operator.TheodoliteOperator
+
 
 @QuarkusTest
 class ActionCommandTest {
@@ -20,11 +20,10 @@ class ActionCommandTest {
     @BeforeEach
     fun setUp() {
         server.before()
-        val operator = TheodoliteOperator()
+        val operator = TheodoliteOperator(server.client)
         this.controller = operator.getController(
-            client = server.client,
-            executionStateHandler = operator.getExecutionStateHandler(client = server.client),
-            benchmarkStateChecker = operator.getBenchmarkStateChecker(client = server.client)
+            executionStateHandler = operator.getExecutionStateHandler(),
+            benchmarkStateChecker = operator.getBenchmarkStateChecker()
         )
 
         val pod: Pod = PodBuilder().withNewMetadata()
@@ -100,12 +99,12 @@ class ActionCommandTest {
     @Test
     fun testActionSuccess() {
         val action = Action()
-        action.selector = ActionSelector()
-        action.selector.pod = PodSelector()
-        action.selector.pod.matchLabels = mapOf("app" to "pod")
-        action.exec = Command()
-        action.exec.command = arrayOf("ls")
-        action.exec.timeoutSeconds = 10L
+        action.execCommand = ExecCommand()
+        action.execCommand!!.selector = ExecActionSelector()
+        action.execCommand!!.selector.pod = PodSelector()
+        action.execCommand!!.selector.pod.matchLabels = mutableMapOf("app" to "pod")
+        action.execCommand!!.command = arrayOf("ls")
+        action.execCommand!!.timeoutSeconds = 10L
 
         action.exec(server.client)
         assertEquals(
@@ -116,12 +115,12 @@ class ActionCommandTest {
     @Test
     fun testActionFailed() {
         val action = Action()
-        action.selector = ActionSelector()
-        action.selector.pod = PodSelector()
-        action.selector.pod.matchLabels = mapOf("app" to "pod")
-        action.exec = Command()
-        action.exec.command = arrayOf("error-command")
-        action.exec.timeoutSeconds = 10L
+        action.execCommand = ExecCommand()
+        action.execCommand!!.selector = ExecActionSelector()
+        action.execCommand!!.selector.pod = PodSelector()
+        action.execCommand!!.selector.pod.matchLabels = mapOf("app" to "pod")
+        action.execCommand!!.command = arrayOf("error-command")
+        action.execCommand!!.timeoutSeconds = 10L
 
         assertThrows<ActionCommandFailedException> { run { action.exec(server.client) } }
     }
diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt
similarity index 95%
rename from theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt
index 33a4572e368655744185312ff2352b1294d7bef6..87058706c1a315c98ba098e6c5835f3a57343112 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ConfigMapResourceSetTest.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import io.fabric8.kubernetes.api.model.*
@@ -19,16 +19,11 @@ import org.junit.jupiter.api.Assertions.assertTrue
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
-import org.mockito.kotlin.mock
 import registerResource
-import theodolite.TestBenchmark
-import theodolite.execution.operator.BenchmarkCRDummy
-import theodolite.execution.operator.ExecutionClient
-import theodolite.execution.operator.ExecutionEventHandler
-import theodolite.execution.operator.ExecutionStateHandler
-import theodolite.model.crd.BenchmarkCRD
-import theodolite.model.crd.ExecutionCRD
-import theodolite.util.DeploymentFailedException
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRDummy
+import rocks.theodolite.kubernetes.operator.ExecutionClient
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
 import java.io.FileInputStream
 
 // TODO move somewhere else
diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ErrorChannelMessage.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ErrorChannelMessage.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/benchmark/ErrorChannelMessage.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ErrorChannelMessage.kt
index df57a2529653a39ccbde14b4a91d30352224457e..4181b7cbb90fd0c6bd2db78753560092d7ea60ca 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/ErrorChannelMessage.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ErrorChannelMessage.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import io.fabric8.mockwebserver.internal.WebSocketMessage
 import java.nio.charset.StandardCharsets
diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt
similarity index 97%
rename from theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt
index 6a31875d00c8f578dcc475c3de21e130c595f673..1c5f32159713e7ace6857caf0f97b43c90cb36e0 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/FileSystemResourceSetTest.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.api.model.*
 import io.fabric8.kubernetes.api.model.apps.Deployment
@@ -13,9 +13,8 @@ import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Assertions.assertTrue
 import org.junit.jupiter.api.io.TempDir
 import registerResource
-import theodolite.model.crd.BenchmarkCRD
-import theodolite.model.crd.ExecutionCRD
-import theodolite.util.DeploymentFailedException
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
 import java.io.FileInputStream
 import java.nio.file.Files
 import java.nio.file.Path
diff --git a/theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt
similarity index 99%
rename from theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt
index ee80d55caf995642f6fff04cfeeb66bc08ab93d3..90dd01626a7c18e0b6f8d6018aae54297e758464 100644
--- a/theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/K8sManagerTest.kt
@@ -1,4 +1,4 @@
-package theodolite.k8s
+package rocks.theodolite.kubernetes
 
 import io.fabric8.kubernetes.api.model.*
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ResourceSetsTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ResourceSetsTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f0a6c120ca6c3397e8d41cd9f42b536b3e053caf
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ResourceSetsTest.kt
@@ -0,0 +1,132 @@
+package rocks.theodolite.kubernetes
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
+import io.fabric8.kubernetes.api.model.ConfigMap
+import io.fabric8.kubernetes.api.model.ConfigMapBuilder
+import io.fabric8.kubernetes.api.model.HasMetadata
+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.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import org.junit.jupiter.api.io.TempDir
+import java.nio.file.Files
+import java.nio.file.Path
+
+@QuarkusTest
+@WithKubernetesTestServer
+internal class ResourceSetsTest {
+
+    @KubernetesTestServer
+    private lateinit var server: KubernetesServer
+
+    @TempDir
+    @JvmField
+    final var tempDir: Path? = null
+
+    private val objectMapper: ObjectMapper = ObjectMapper(YAMLFactory())
+
+    @BeforeEach
+    fun setUp() {
+        server.before()
+    }
+
+    @AfterEach
+    fun tearDown() {
+        server.after()
+    }
+
+    private fun deployAndGetResource(vararg resources: HasMetadata): ConfigMapResourceSet {
+        val configMap = ConfigMapBuilder()
+            .withNewMetadata().withName(resources[0].metadata.name).endMetadata()
+            .let {
+                resources.foldIndexed(it) { i, b, r ->
+                    b.addToData("resource_$i.yaml", objectMapper.writeValueAsString(r))
+                }
+            }
+            .build()
+
+        server.client.configMaps().createOrReplace(configMap)
+
+        val resourceSet = ConfigMapResourceSet()
+        resourceSet.name = resources[0].metadata.name
+
+        return resourceSet
+    }
+
+    private fun copyTestResourceFile(fileName: String, tempDir: Path) {
+        val stream = javaClass.getResourceAsStream("/k8s-resource-files/$fileName")
+            ?: throw IllegalArgumentException("File does not exist")
+        val target = tempDir.resolve(fileName)
+        Files.copy(stream, target)
+    }
+
+    @Test
+    fun testLoadConfigMap() {
+        val resource = ConfigMapBuilder()
+            .withNewMetadata()
+            .withName("test-configmap")
+            .endMetadata()
+            .build()
+        deployAndGetResource(resource)
+
+        val yamlString =
+            """
+            configMap:    
+                name: test-configmap
+                files:
+            """
+
+        val resourcesSet: ResourceSets = objectMapper.readValue(yamlString, ResourceSets::class.java)
+        assertTrue(resourcesSet.fileSystem == null)
+        assertTrue(resourcesSet.configMap != null)
+
+        val configMap = resourcesSet.loadResourceSet(server.client)
+        assertEquals(1, configMap.size)
+        assertTrue(configMap.toList().first().second is ConfigMap)
+        assertTrue(configMap.toList().first().second.toString().contains(other = resource.metadata.name))
+
+        assertEquals(configMap.elementAt(0).second, resource)
+    }
+
+    @Test
+    fun testLoadFileSystem(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-deployment.yaml", tempDir)
+
+        val resourceSet = FileSystemResourceSet()
+        resourceSet.path = tempDir.toString()
+        resourceSet.files = listOf("test-deployment.yaml")
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
+
+        val yamlString =
+            """
+            fileSystem:    
+                path: ${resourceSet.path}
+                files:
+                    - test-deployment.yaml
+            """
+
+        val resourcesSet: ResourceSets = objectMapper.readValue(yamlString, ResourceSets::class.java)
+        assertTrue(resourcesSet.fileSystem != null)
+        assertTrue(resourcesSet.configMap == null)
+
+        val fileSystem = resourcesSet.loadResourceSet(server.client)
+        assertEquals(fileSystem.size, 1)
+        assertTrue(fileSystem.elementAt(0).second is HasMetadata)
+    }
+
+    @Test
+    fun testEmptyResourceSets() {
+        val resourceSet = ResourceSets()
+
+        assertThrows<DeploymentFailedException> {
+            resourceSet.loadResourceSet(server.client)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/TestBenchmarkDeployment.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeployment.kt
similarity index 56%
rename from theodolite/src/test/kotlin/theodolite/TestBenchmarkDeployment.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeployment.kt
index 68b08c294128368ee1b65549aa85c877bd4bf313..92bc2fd26a8c5e9d77b0729731b3e65833b3dd08 100644
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmarkDeployment.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeployment.kt
@@ -1,6 +1,6 @@
-package theodolite
+package rocks.theodolite.kubernetes
 
-import theodolite.benchmark.BenchmarkDeployment
+import rocks.theodolite.kubernetes.BenchmarkDeployment
 
 class TestBenchmarkDeployment : BenchmarkDeployment {
     override fun setup() {}
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeploymentBuilder.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeploymentBuilder.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cc7c9d6ae9a5fe158f7ba9243f23442acde001ee
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeploymentBuilder.kt
@@ -0,0 +1,21 @@
+package rocks.theodolite.kubernetes
+
+
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
+
+class TestBenchmarkDeploymentBuilder(): BenchmarkDeploymentBuilder {
+
+    override fun buildDeployment(
+            load: Int,
+            loadPatcherDefinitions: List<PatcherDefinition>,
+            resource: Int,
+            resourcePatcherDefinitions: List<PatcherDefinition>,
+            configurationOverrides: List<ConfigurationOverride?>,
+            loadGenerationDelay: Long,
+            afterTeardownDelay: Long,
+            waitForResourcesEnabled: Boolean
+    ): BenchmarkDeployment {
+        return TestBenchmarkDeployment()
+    }
+}
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestExperimentRunnerImpl.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestExperimentRunnerImpl.kt
new file mode 100644
index 0000000000000000000000000000000000000000..896beed83e0c9436c3aadc83b1e395df06b1f5b2
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestExperimentRunnerImpl.kt
@@ -0,0 +1,24 @@
+package rocks.theodolite.kubernetes
+
+import rocks.theodolite.core.Results
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
+import rocks.theodolite.core.ExperimentRunner
+
+class TestExperimentRunnerImpl(
+        results: Results,
+        private val mockResults: Array<Array<Boolean>>,
+        private val benchmarkDeploymentBuilder: TestBenchmarkDeploymentBuilder,
+        private val slo: List<Slo>,
+        private val executionId: Int,
+        private val loadGenerationDelay: Long,
+        private val afterTeardownDelay: Long
+) : ExperimentRunner(
+        results
+) {
+
+    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/BenchmarkCRDummy.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkCRDummy.kt
similarity index 75%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkCRDummy.kt
index cbddbfbfc5d6f838677c6d04b0a0c79f59d8bc66..2bd52d55bb3acd3e37d53d22a1a434d53c1fff95 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/BenchmarkCRDummy.kt
@@ -1,9 +1,6 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.model.crd
 
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.benchmark.Resources
-import theodolite.model.crd.BenchmarkCRD
-import theodolite.util.KafkaConfig
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
 
 class BenchmarkCRDummy(name: String) {
 
@@ -20,15 +17,16 @@ class BenchmarkCRDummy(name: String) {
         kafkaConfig.bootstrapServer = ""
         kafkaConfig.topics = emptyList()
 
+
         benchmarkCR.spec = benchmark
         benchmarkCR.metadata.name = name
         benchmarkCR.kind = "Benchmark"
         benchmarkCR.apiVersion = "v1"
+        benchmark.waitForResourcesEnabled = false
 
-
-        benchmark.infrastructure = Resources()
-        benchmark.sut = Resources()
-        benchmark.loadGenerator = Resources()
+        benchmark.infrastructure = KubernetesBenchmark.Resources()
+        benchmark.sut = KubernetesBenchmark.Resources()
+        benchmark.loadGenerator = KubernetesBenchmark.Resources()
 
         benchmark.infrastructure.resources = emptyList()
         benchmark.sut.resources = emptyList()
@@ -43,6 +41,7 @@ class BenchmarkCRDummy(name: String) {
 
         benchmark.resourceTypes = emptyList()
         benchmark.loadTypes = emptyList()
+        benchmark.slos = mutableListOf()
         benchmark.kafkaConfig = kafkaConfig
         benchmark.name = benchmarkCR.metadata.name
     }
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/CRDExecutionTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/CRDExecutionTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a7de76acfe7aac9b92628e87b9911599a13ab438
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/CRDExecutionTest.kt
@@ -0,0 +1,86 @@
+package rocks.theodolite.kubernetes.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.kotlin.mock
+import rocks.theodolite.kubernetes.operator.ExecutionEventHandler
+import rocks.theodolite.kubernetes.operator.ExecutionStateHandler
+import rocks.theodolite.kubernetes.operator.TheodoliteController
+import rocks.theodolite.kubernetes.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/execution/operator/ExecutionCRDummy.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionCRDummy.kt
similarity index 78%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionCRDummy.kt
index 9274e283b48a6fd9b30d5ce0aff3cb8b995e0ce5..871471ee941f5cf2d254fb2bd70556f161d8d4de 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionCRDummy.kt
@@ -1,9 +1,6 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.model.crd
 
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.ExecutionStatus
-import theodolite.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
 
 class ExecutionCRDummy(name: String, benchmark: String) {
 
@@ -36,16 +33,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/util/ExecutionStateComparatorTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStateComparatorTest.kt
similarity index 86%
rename from theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStateComparatorTest.kt
index ae80312afd2c128f0f542306a8ffda7f3f53876b..14186ef408acd3233ce866102497bc56af1cdfda 100644
--- a/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStateComparatorTest.kt
@@ -1,10 +1,8 @@
-package theodolite.util
+package rocks.theodolite.kubernetes.model.crd
 
 import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Test
-import theodolite.execution.operator.ExecutionCRDummy
-import theodolite.model.crd.ExecutionState
 
 
 @QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/model/crd/ExecutionStatusTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStatusTest.kt
similarity index 99%
rename from theodolite/src/test/kotlin/theodolite/model/crd/ExecutionStatusTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStatusTest.kt
index 157bc1c03cc40375c928677189f549052e1e134d..4c9326ac2e99dd7dd9707d4db25cb2e9e360ddf9 100644
--- a/theodolite/src/test/kotlin/theodolite/model/crd/ExecutionStatusTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/ExecutionStatusTest.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.databind.exc.InvalidFormatException
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt
similarity index 84%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt
index 528cfac8066c28bf6382fb97cddf280b3c1de622..465233a5d47e0c3963371a1fd0cc891aac74a42a 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import com.google.gson.Gson
 import io.fabric8.kubernetes.api.model.ConfigMapBuilder
@@ -13,8 +13,13 @@ import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.Assertions.*
-import theodolite.benchmark.*
-import theodolite.model.crd.BenchmarkState
+import rocks.theodolite.kubernetes.model.crd.BenchmarkState
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRDummy
+import rocks.theodolite.kubernetes.ConfigMapResourceSet
+import rocks.theodolite.kubernetes.ExecActionSelector
+import rocks.theodolite.kubernetes.PodSelector
+import rocks.theodolite.kubernetes.ResourceSets
 
 internal class BenchmarkStateCheckerTest {
     private val server = KubernetesServer(false, false)
@@ -26,17 +31,17 @@ internal class BenchmarkStateCheckerTest {
     fun setUp() {
         server.before()
         serverCrud.before()
-        val operator = TheodoliteOperator()
+        val operator = TheodoliteOperator(serverCrud.client)
         checker = BenchmarkStateChecker(
             client = server.client,
-            benchmarkCRDClient = operator.getBenchmarkClient(server.client),
-            benchmarkStateHandler = operator.getBenchmarkStateHandler(server.client)
+            benchmarkCRDClient = operator.getBenchmarkClient(),
+            benchmarkStateHandler = operator.getBenchmarkStateHandler()
         )
 
         checkerCrud = BenchmarkStateChecker(
             client = serverCrud.client,
-            benchmarkCRDClient = operator.getBenchmarkClient(serverCrud.client),
-            benchmarkStateHandler = operator.getBenchmarkStateHandler(serverCrud.client)
+            benchmarkCRDClient = operator.getBenchmarkClient(),
+            benchmarkStateHandler = operator.getBenchmarkStateHandler()
         )
 
         val pod: Pod = PodBuilder().withNewMetadata()
@@ -105,9 +110,9 @@ internal class BenchmarkStateCheckerTest {
             .build()
     }
 
-    private fun getActionSelector(label: Pair<String, String>): ActionSelector {
+    private fun getActionSelector(label: Pair<String, String>): ExecActionSelector {
         val podSelector = PodSelector()
-        val actionSelector = ActionSelector()
+        val actionSelector = ExecActionSelector()
         actionSelector.pod = podSelector
 
         // pod with matching labels are deployed
@@ -162,16 +167,17 @@ internal class BenchmarkStateCheckerTest {
 
     @Test
     fun checkResources() {
-        val benchmark = BenchmarkCRDummy(
+        val benchmarkCR = BenchmarkCRDummy(
             name = "test-benchmark"
         )
-        benchmark.getCR().spec.setClient(serverCrud.client)
-        val resourceSet = Resources()
+        val benchmark = benchmarkCR.getCR().spec
+
+        val resourceSet = KubernetesBenchmark.Resources()
         resourceSet.resources = listOf(createAndDeployConfigmapResourceSet())
-        benchmark.getCR().spec.infrastructure = resourceSet
-        benchmark.getCR().spec.loadGenerator = resourceSet
-        benchmark.getCR().spec.sut = resourceSet
+        benchmark.infrastructure = resourceSet
+        benchmark.loadGenerator = resourceSet
+        benchmark.sut = resourceSet
 
-        assertEquals(BenchmarkState.READY,checkerCrud.checkResources(benchmark.getCR().spec))
+        assertEquals(BenchmarkState.READY,checkerCrud.checkResources(benchmark))
     }
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ControllerTest.kt
similarity index 91%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ControllerTest.kt
index 7d40f7e45d6aa2c93206a1bad22754fe93b0c100..3120d7420065cfe254d1ed76735ddc8b35d2bc21 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ControllerTest.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import com.google.gson.Gson
 import com.google.gson.GsonBuilder
@@ -10,11 +10,10 @@ import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.DisplayName
 import org.junit.jupiter.api.Test
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.model.crd.BenchmarkCRD
-import theodolite.model.crd.BenchmarkState
-import theodolite.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.model.crd.*
+
 
 @QuarkusTest
 class ControllerTest {
@@ -32,11 +31,10 @@ class ControllerTest {
     @BeforeEach
     fun setUp() {
         server.before()
-        val operator = TheodoliteOperator()
+        val operator = TheodoliteOperator(server.client)
         this.controller = operator.getController(
-            client = server.client,
-            executionStateHandler = operator.getExecutionStateHandler(client = server.client),
-            benchmarkStateChecker = operator.getBenchmarkStateChecker(client = server.client)
+            executionStateHandler = operator.getExecutionStateHandler(),
+            benchmarkStateChecker = operator.getBenchmarkStateChecker()
         )
 
         // benchmark
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt
similarity index 98%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt
index c08e0565375de84a228a28b6d68a0b713af97d0f..e794ae1638bd6c7f265b3b7ffb08c2494ba76a37 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTest.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.api.model.KubernetesResourceList
 import io.fabric8.kubernetes.client.dsl.MixedOperation
@@ -16,8 +16,8 @@ import org.junit.jupiter.params.ParameterizedTest
 import org.junit.jupiter.params.provider.Arguments
 import org.junit.jupiter.params.provider.MethodSource
 import org.mockito.kotlin.*
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 import java.io.FileInputStream
 import java.util.stream.Stream
 
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTestWithInformer.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt
similarity index 98%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTestWithInformer.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt
index adddc705616935e5440c1c601615ce9a065df4c4..63a669fe67c66b644b6acbabedc5d79afff8ee31 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTestWithInformer.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerTestWithInformer.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.client.dsl.Resource
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
@@ -11,8 +11,8 @@ import org.junit.jupiter.params.ParameterizedTest
 import org.junit.jupiter.params.provider.Arguments
 import org.junit.jupiter.params.provider.MethodSource
 import org.mockito.kotlin.*
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 import java.io.FileInputStream
 import java.util.concurrent.CountDownLatch
 import java.util.stream.Stream
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerWrapper.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerWrapper.kt
similarity index 63%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerWrapper.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerWrapper.kt
index 5dbc515a7799dd51e6395153f13d80650587d7fa..43ff721bd0f964065243188465849354bc7f8b23 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerWrapper.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/ExecutionEventHandlerWrapper.kt
@@ -1,13 +1,14 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.client.informers.ResourceEventHandler
-import theodolite.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.operator.ExecutionEventHandler
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
 
 class ExecutionEventHandlerWrapper(
-    private val executionEventHandler: ExecutionEventHandler,
-    private val afterOnAddCallback: () -> Unit,
-    private val afterOnUpdateCallback: () -> Unit,
-    private val afterOnDeleteCallback: () -> Unit
+        private val executionEventHandler: ExecutionEventHandler,
+        private val afterOnAddCallback: () -> Unit,
+        private val afterOnUpdateCallback: () -> Unit,
+        private val afterOnDeleteCallback: () -> Unit
 ) : ResourceEventHandler<ExecutionCRD> {
 
     override fun onAdd(execution: ExecutionCRD) {
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt
similarity index 90%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt
index ba65356b65b6ac23ca56c268bb003815917cf162..ebef641d1e0a699ab5e220b0846be654fbefc672 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/StateHandlerTest.kt
@@ -1,4 +1,4 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.operator
 
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
 import io.quarkus.test.junit.QuarkusTest
@@ -10,9 +10,9 @@ import org.junit.jupiter.api.Assertions.assertTrue
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.DisplayName
 import org.junit.jupiter.api.Test
-import theodolite.k8s.K8sManager
-import theodolite.model.crd.ExecutionCRD
-import theodolite.model.crd.ExecutionState
+import rocks.theodolite.kubernetes.K8sManager
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRD
+import rocks.theodolite.kubernetes.model.crd.ExecutionState
 
 @QuarkusTest
 @WithKubernetesTestServer
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cb92423305fd3f724753225d95150d5198f1d306
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcherTest.kt
@@ -0,0 +1,98 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.*
+import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder
+import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.Test
+
+@QuarkusTest
+abstract class AbstractPatcherTest {
+
+    lateinit var resource: List<HasMetadata>
+    lateinit var patcher: Patcher
+    lateinit var value: String
+
+    fun createDeployment(): HasMetadata {
+        return DeploymentBuilder()
+            .withNewMetadata()
+                .withName("dummy")
+            .endMetadata()
+            .withNewSpec()
+                .withNewSelector()
+                    .withMatchLabels<String, String>(mapOf("labelName" to "labelValue"))
+                .endSelector()
+                    .withNewTemplate()
+                        .withNewMetadata()
+                            .withLabels<String, String>(mapOf("labelName" to "labelValue"))
+                        .endMetadata()
+                        .withNewSpec()
+                        .withContainers(
+                                ContainerBuilder()
+                                    .withName("container")
+                                    .withImage("test-image")
+                                    .build())
+                            .addNewVolume()
+                                .withName("test-volume")
+                                .withNewConfigMap()
+                                    .withName("test-configmap")
+                                .endConfigMap()
+                            .endVolume()
+                        .endSpec()
+                .endTemplate()
+            .endSpec()
+            .build()
+    }
+
+    fun createStateFulSet(): HasMetadata {
+        return StatefulSetBuilder()
+            .withNewMetadata()
+                .withName("dummy")
+            .endMetadata()
+            .withNewSpec()
+                .withNewSelector()
+                    .withMatchLabels<String, String>(mapOf("labelName" to "labelValue"))
+                .endSelector()
+                .withNewTemplate()
+                    .withNewMetadata()
+                        .withLabels<String, String>(mapOf("labelName" to "labelValue"))
+                    .endMetadata()
+                    .withNewSpec()
+                    .addNewVolume()
+                        .withName("test-volume")
+                            .withNewConfigMap()
+                                .withName("test-configmap")
+                            .endConfigMap()
+                        .endVolume()
+                    .endSpec()
+                .endTemplate()
+            .endSpec()
+            .build()
+    }
+
+    fun createService(): HasMetadata {
+        return ServiceBuilder()
+            .withNewMetadata()
+            .withName("dummy")
+            .endMetadata()
+            .build()
+    }
+
+    fun createConfigMap(): HasMetadata {
+        return ConfigMapBuilder()
+            .withNewMetadata()
+                .withName("dummy")
+            .endMetadata()
+            .withData<String, String>(mapOf("application.properties" to "propA = valueA"))
+            .build()
+    }
+
+    fun patch() {
+        resource = patcher.patch(resource, value)
+    }
+
+    @Test
+    abstract fun validate()
+
+
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifierTest.kt
similarity index 82%
rename from theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifierTest.kt
index 1db1122e1caa5a783159ecaba849b99963e3c2a9..6172454008266c987b335999b7d8bbe67bb0fc02 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifierTest.kt
@@ -1,13 +1,13 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.Assertions
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.execution.operator.BenchmarkCRDummy
-import theodolite.execution.operator.ExecutionCRDummy
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.model.crd.BenchmarkCRDummy
+import rocks.theodolite.kubernetes.model.crd.ExecutionCRDummy
 
 @QuarkusTest
 class ConfigOverrideModifierTest {
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6c9be1b9a59f963c8996e520b55e16caf24cbf6c
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
@@ -0,0 +1,28 @@
+package theodolite.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import rocks.theodolite.kubernetes.patcher.AbstractPatcherTest
+
+import rocks.theodolite.kubernetes.patcher.VolumesConfigMapPatcher
+
+@QuarkusTest
+internal class DataVolumeLoadGeneratorReplicaPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = VolumesConfigMapPatcher((resource.first() as Deployment).spec.template.spec.volumes[0].configMap.name)
+        value = "new-configMapName"
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assert((it as Deployment).spec.template.spec.volumes[0].configMap.name == value)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..83cd056ac1b56b13fb8f211a2d926f1272c9fb0e
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcherTest.kt
@@ -0,0 +1,34 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.EnvVarBuilder
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.BeforeEach
+
+@QuarkusTest
+internal class EnvVarPatcherTest : AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = EnvVarPatcher(variableName = "testEnv", container = "container")
+        value = "testValue"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        val envVar = EnvVarBuilder().withName("testEnv").withValue("testValue").build()
+        resource.forEach {
+        assertTrue((it as Deployment).spec.template.spec.containers[0].env.contains(envVar))
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7b3f803a4e13039b7bb40aec6259f7d9a4fdbb57
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcherTest.kt
@@ -0,0 +1,32 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class ImagePatcherTest: AbstractPatcherTest(){
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = ImagePatcher(container = "container")
+        value = "testValue"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.template.spec.containers[0].image  == value)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..652dda47cef34a7a95e54c36cbe9af9c897b84a1
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
@@ -0,0 +1,37 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class LabelPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = LabelPatcher("labelName")
+        value = "labelValue"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).metadata.labels.containsKey("labelName"))
+            assertTrue(it.metadata.labels.get("labelName")=="labelValue")
+        }
+    }
+
+    @Test
+    fun getVariableName() {
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a5711a762ab65fc39edf731c21d085d0936a5a93
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcherTest.kt
@@ -0,0 +1,37 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class MatchLabelPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = MatchLabelPatcher("labelName")
+        value = "labelValue"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.selector.matchLabels.containsKey("labelName"))
+            assertTrue(it.spec.selector.matchLabels.get("labelName")=="labelValue")
+        }
+    }
+
+    @Test
+    fun getVariableName() {
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cb1308cb73dc127661b2c2741fdc3e0460fcfde4
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
@@ -0,0 +1,32 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class NamePatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = NamePatcher()
+        value = "newName"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            println(it.toString())
+            assertTrue(it.toString().contains("name=$value"))
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ca8f83518a5bcd96837de96b1879c0de2e9a5773
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcherTest.kt
@@ -0,0 +1,35 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class NodeSelectorPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = NodeSelectorPatcher("nodeName")
+        value = "nodeValue"
+
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.template.spec.nodeSelector.containsKey("nodeName"))
+            assertTrue(it.spec.template.spec.nodeSelector["nodeName"] == value)
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8940e288fae79f10e5dcd728121a2dbbf0aaa180
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
@@ -0,0 +1,32 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class NumNestedGroupsLoadGeneratorReplicaPatcherTest : AbstractPatcherTest(){
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = NumNestedGroupsLoadGeneratorReplicaPatcher("10", "500")
+        value = "2"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.replicas == 1)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e3bb6ffff4938bcaeb4a0db6487bd4741da75850
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
@@ -0,0 +1,32 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class NumSensorsLoadGeneratorReplicaPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = NumSensorsLoadGeneratorReplicaPatcher("10")
+        value = "2"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.replicas == 1)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactoryTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..010fa1e25fb89619c8954b1bafa52c5389d0a2f3
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactoryTest.kt
@@ -0,0 +1,22 @@
+package rocks.theodolite.kubernetes.patcher
+
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+internal class PatcherDefinitionFactoryTest {
+
+    @BeforeEach
+    fun setUp() {
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    fun createPatcherDefinition() {
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..852002a07cfb756086afbc6d0573fc548f945683
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcherTest.kt
@@ -0,0 +1,32 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class ReplicaPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = ReplicaPatcher()
+        value = "5"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.replicas == 5)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
similarity index 83%
rename from theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
index 2769f2fef607a03d820b0821969db98894944cb3..b0af74d1e207ee10fac548f27267356711943dd0 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
@@ -1,5 +1,6 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
+import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
 import io.quarkus.test.junit.QuarkusTest
 import io.quarkus.test.kubernetes.client.KubernetesTestServer
@@ -7,8 +8,6 @@ import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
 import org.junit.jupiter.api.Assertions.assertTrue
 import org.junit.jupiter.api.Disabled
 import org.junit.jupiter.api.Test
-import theodolite.patcher.PatcherFactory
-import theodolite.util.PatcherDefinition
 
 /**
  * Resource patcher test
@@ -25,8 +24,6 @@ import theodolite.util.PatcherDefinition
 @Disabled
 class ResourceLimitPatcherTest {
 
-    val patcherFactory = PatcherFactory()
-
     @KubernetesTestServer
     private lateinit var server: KubernetesServer
 
@@ -51,15 +48,8 @@ class ResourceLimitPatcherTest {
             "container" to "uc-application"
         )
 
-        patcherFactory.createPatcher(
-            patcherDefinition = defCPU,
-            k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource))
-        ).patch(value = cpuValue)
-
-        patcherFactory.createPatcher(
-            patcherDefinition = defMEM,
-            k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource))
-        ).patch(value = memValue)
+        PatchHandler.patchResource(mutableMapOf(Pair("cpu-memory-deployment.yaml", listOf(k8sResource as HasMetadata))), defCPU, cpuValue)
+        PatchHandler.patchResource(mutableMapOf(Pair("cpu-memory-deployment.yaml", listOf(k8sResource as HasMetadata))), defMEM, memValue)
 
         k8sResource.spec.template.spec.containers.filter { it.name == defCPU.properties["container"]!! }
             .forEach {
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
similarity index 84%
rename from theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
index dba91eb65d4474d38f64d7fdd7f7ab981f8eb30f..a076e541e742e97ffa95dccff925892dd63ff17a 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
 import io.quarkus.test.junit.QuarkusTest
@@ -6,7 +6,6 @@ import io.quarkus.test.kubernetes.client.KubernetesTestServer
 import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
 import io.smallrye.common.constraint.Assert.assertTrue
 import org.junit.jupiter.api.Test
-import theodolite.util.PatcherDefinition
 
 /**
  * Resource patcher test
@@ -25,8 +24,6 @@ class ResourceRequestPatcherTest {
     @KubernetesTestServer
     private lateinit var server: KubernetesServer
 
-    val patcherFactory = PatcherFactory()
-
     fun applyTest(fileName: String) {
         val cpuValue = "50m"
         val memValue = "3Gi"
@@ -48,14 +45,8 @@ class ResourceRequestPatcherTest {
             "container" to "application"
         )
 
-        patcherFactory.createPatcher(
-            patcherDefinition = defCPU,
-            k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource))
-        ).patch(value = cpuValue)
-        patcherFactory.createPatcher(
-            patcherDefinition = defMEM,
-            k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource))
-        ).patch(value = memValue)
+        PatchHandler.patchResource(mutableMapOf(Pair("/cpu-memory-deployment.yaml", listOf(k8sResource))), defCPU, cpuValue)
+        PatchHandler.patchResource(mutableMapOf(Pair("/cpu-memory-deployment.yaml", listOf(k8sResource))), defMEM, memValue)
 
         k8sResource.spec.template.spec.containers.filter { it.name == defCPU.properties["container"]!! }
             .forEach {
@@ -87,4 +78,4 @@ class ResourceRequestPatcherTest {
         // Case 4: In the given YAML declaration neither `Resource Request` nor `Request Limit` is defined
         applyTest("/no-resources-deployment.yaml")
     }
-}
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2b2021ec5853af4a2ef087a21bde87fb5bdc847e
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcherTest.kt
@@ -0,0 +1,32 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class SchedulerNamePatcherTest : AbstractPatcherTest(){
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = SchedulerNamePatcher()
+        value = "testScheduler"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.template.spec.schedulerName == value)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..94073b9f34d6b76d69d82e4ea40ed047a68655ff
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcherTest.kt
@@ -0,0 +1,30 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class TemplateLabelPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = TemplateLabelPatcher( "labelName")
+        value = "labelValue"
+    }
+
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            assertTrue((it as Deployment).spec.template.metadata.labels.containsKey("labelName"))
+            assertTrue(it.spec.template.metadata.labels["labelName"] =="labelValue")
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcherTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..db3fc812e426c0f74cf68d35a158f32a3ec0bc3f
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcherTest.kt
@@ -0,0 +1,33 @@
+package rocks.theodolite.kubernetes.patcher
+
+import io.fabric8.kubernetes.api.model.apps.Deployment
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.Assertions.*
+
+@QuarkusTest
+internal class VolumesConfigMapPatcherTest: AbstractPatcherTest() {
+
+    @BeforeEach
+    fun setUp() {
+        resource = listOf(createDeployment())
+        patcher = VolumesConfigMapPatcher("test-configmap")
+        value = "patchedVolumeName"
+    }
+
+    @AfterEach
+    fun tearDown() {
+    }
+
+    @Test
+    override fun validate() {
+        patch()
+        resource.forEach {
+            println((it as Deployment).spec.template.spec.volumes[0].configMap.name)
+            assertTrue((it as Deployment).spec.template.spec.volumes[0].configMap.name == value)
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloFactoryTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..de9d4c60dbad069ccb1229bebb4a4751cf96d98d
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloFactoryTest.kt
@@ -0,0 +1,69 @@
+package rocks.theodolite.kubernetes.slo
+
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.Test
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+
+@QuarkusTest
+internal class SloFactoryTest {
+
+    @Test
+    fun overwriteSloTest() {
+
+        val benchmark = KubernetesBenchmark()
+        val execution = BenchmarkExecution()
+
+        // Define Benchmark SLOs
+        val slo = KubernetesBenchmark.Slo()
+        slo.name="test"
+        slo.sloType="lag trend"
+        slo.prometheusUrl="test.de"
+        slo.offset=0
+
+        val benchmarkSloProperties = mutableMapOf<String, String>()
+        benchmarkSloProperties["threshold"] = "2000"
+        benchmarkSloProperties["externalSloUrl"] = "http://localhost:80/evaluate-slope"
+        benchmarkSloProperties["warmup"] = "60"
+
+        slo.properties=benchmarkSloProperties
+
+        benchmark.slos = mutableListOf(slo)
+
+
+        // Define Execution SLOs, benchmark SLO values for these properties should be overwritten
+        val sloConfig = BenchmarkExecution.SloConfiguration()
+        sloConfig.name = "test"
+
+        val executionSloProperties = mutableMapOf<String, String>()
+        // overwriting properties 'threshold' and 'warmup' and adding property 'extensionTest'
+        executionSloProperties["threshold"] = "3000"
+        executionSloProperties["warmup"] = "80"
+        executionSloProperties["extensionTest"] = "extended"
+
+        sloConfig.properties = executionSloProperties
+
+        // SLO has 'name' that isn't defined in the benchmark, therefore it will be ignored by the SloFactory
+        val sloConfig2 = BenchmarkExecution.SloConfiguration()
+        sloConfig2.name = "test2"
+        sloConfig2.properties = executionSloProperties
+
+        execution.slos = listOf(sloConfig, sloConfig2)
+
+        val sloFactory = SloFactory()
+        val combinedSlos = sloFactory.createSlos(execution,benchmark)
+
+        Assertions.assertEquals(1, combinedSlos.size)
+        Assertions.assertEquals("test", combinedSlos[0].name)
+        Assertions.assertEquals("lag trend", combinedSlos[0].sloType)
+        Assertions.assertEquals("test.de", combinedSlos[0].prometheusUrl)
+        Assertions.assertEquals(0, combinedSlos[0].offset)
+
+        Assertions.assertEquals(4, combinedSlos[0].properties.size)
+        Assertions.assertEquals("3000", combinedSlos[0].properties["threshold"])
+        Assertions.assertEquals("http://localhost:80/evaluate-slope", combinedSlos[0].properties["externalSloUrl"])
+        Assertions.assertEquals("80", combinedSlos[0].properties["warmup"])
+        Assertions.assertEquals("extended", combinedSlos[0].properties["extensionTest"])
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt b/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt
deleted file mode 100644
index 580d9e747bde687a91ffb1bce2e7c9dfb6f166a2..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-package theodolite
-
-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.restriction.LowerBoundRestriction
-import theodolite.strategies.searchstrategy.BinarySearch
-import theodolite.strategies.searchstrategy.CompositeStrategy
-import theodolite.strategies.searchstrategy.LinearSearch
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-import theodolite.util.Results
-
-@QuarkusTest
-class CompositeStrategyTest {
-
-    @Test
-    fun testEnd2EndLinearSearch() {
-        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<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
-        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))
-
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
-        expected.add(null)
-
-        for (load in mockLoads) {
-            actual.add(strategy.findSuitableResource(load, mockResources))
-        }
-
-        assertEquals(actual, expected)
-    }
-
-    @Test
-    fun testEnd2EndBinarySearch() {
-        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<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) }
-        val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
-        val results = Results()
-        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 actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
-        expected.add(null)
-
-        for (load in mockLoads) {
-            actual.add(strategy.findSuitableResource(load, mockResources))
-        }
-
-        assertEquals(actual, expected)
-    }
-
-    @Test
-    fun testEnd2EndBinarySearch2() {
-        val mockResults = arrayOf(
-            arrayOf(true, true, true, true, true, true, true, true),
-            arrayOf(false, false, true, true, true, true, true, true),
-            arrayOf(false, false, true, true, true, true, true, true),
-            arrayOf(false, false, false, true, true, true, true, true),
-            arrayOf(false, false, false, false, true, true, true, true),
-            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 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))
-
-        val actual: ArrayList<Resource?> = ArrayList()
-        val expected: ArrayList<Resource?> =
-            ArrayList(listOf(0, 2, 2, 3, 4, 6, 7).map { x -> Resource(x, emptyList()) })
-
-        for (load in mockLoads) {
-            actual.add(strategy.findSuitableResource(load, mockResources))
-        }
-
-        assertEquals(actual, expected)
-    }
-}
diff --git a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt b/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
deleted file mode 100644
index b08c1a18a3013e1573e4892f01698b5e509f9609..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package theodolite
-
-import theodolite.benchmark.Benchmark
-import theodolite.benchmark.BenchmarkDeployment
-import theodolite.util.ConfigurationOverride
-import theodolite.util.LoadDimension
-import theodolite.util.Resource
-
-class TestBenchmark : Benchmark {
-
-    override fun setupInfrastructure() {
-    }
-
-    override fun teardownInfrastructure() {
-    }
-
-    override fun buildDeployment(
-        load: LoadDimension,
-        res: Resource,
-        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
deleted file mode 100644
index 2efddc48cb93a0870d1716c58a7018145c16e2ff..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-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
-
-class TestBenchmarkExecutorImpl(
-    private val mockResults: Array<Array<Boolean>>,
-    benchmark: Benchmark,
-    results: Results,
-    slo: List<BenchmarkExecution.Slo>,
-    executionId: Int,
-    loadGenerationDelay: Long,
-    afterTeardownDelay: Long
-) :
-    BenchmarkExecutor(
-        benchmark,
-        results,
-        executionDuration = Duration.ofSeconds(1),
-        configurationOverrides = emptyList(),
-        slos = slo,
-        repetitions = 1,
-        executionId = executionId,
-        loadGenerationDelay = loadGenerationDelay,
-        afterTeardownDelay = afterTeardownDelay,
-        executionName = "test-execution"
-    ) {
-
-    override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
-        val result = this.mockResults[load.get()][res.get()]
-        this.results.setResult(Pair(load, res), result)
-        return result
-    }
-}
diff --git a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt b/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
deleted file mode 100644
index 9cfc2ae78e7a8846e3f0fa136699509145e5de22..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package theodolite.util
-
-import io.quarkus.test.junit.QuarkusTest
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotNull
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-
-@QuarkusTest
-internal class ResultsTest {
-
-    @Test
-    fun testMinRequiredInstancesWhenSuccessful() {
-        val results = Results()
-        results.setResult(10000, 1, true)
-        results.setResult(10000, 2, true)
-        results.setResult(20000, 1, false)
-        results.setResult(20000, 2, true)
-
-        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
-
-        assertNotNull(minRequiredInstances)
-        assertEquals(2, minRequiredInstances!!.get())
-    }
-
-    @Test
-    @Disabled
-    fun testMinRequiredInstancesWhenNotSuccessful() {
-        // This test is currently not implemented this way, but might later be the desired behavior.
-        val results = Results()
-        results.setResult(10000, 1, true)
-        results.setResult(10000, 2, true)
-        results.setResult(20000, 1, false)
-        results.setResult(20000, 2, false)
-
-        val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList()))
-
-        assertNotNull(minRequiredInstances)
-        assertEquals(2, minRequiredInstances!!.get())
-    }
-
-    private fun Results.setResult(load: Int, resources: Int, successful: Boolean) {
-        this.setResult(
-            Pair(
-                LoadDimension(load, emptyList()),
-                Resource(resources, emptyList())
-            ),
-            successful
-        )
-    }
-
-
-    @Test
-    fun testGetMaxBenchmarkedLoadWhenAllSuccessful() {
-        val results = Results()
-        results.setResult(10000, 1, true)
-        results.setResult(10000, 2, true)
-
-        val test1 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get()
-
-        assertEquals(10000, test1)
-    }
-
-    @Test
-    fun testGetMaxBenchmarkedLoadWhenLargestNotSuccessful() {
-        val results = Results()
-        results.setResult(10000, 1, true)
-        results.setResult(10000, 2, true)
-        results.setResult(20000, 1, false)
-
-        val test2 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get()
-
-        assertEquals(20000, test2)
-    }
-}
diff --git a/theodolite/src/test/resources/k8s-resource-files/test-benchmark.yaml b/theodolite/src/test/resources/k8s-resource-files/test-benchmark.yaml
index ea9ee8471d3da1dc6011348bd978696bd0fa6f36..ad26f6c658c72231887a8e3cd4c5dc17cc787641 100644
--- a/theodolite/src/test/resources/k8s-resource-files/test-benchmark.yaml
+++ b/theodolite/src/test/resources/k8s-resource-files/test-benchmark.yaml
@@ -3,6 +3,7 @@ kind: benchmark
 metadata:
   name: example-benchmark
 spec:
+  waitForResourcesEnabled: false
   sut:
     resources:
       - configMap:
@@ -33,6 +34,15 @@ spec:
           resource: "uc1-load-generator-deployment.yaml"
           properties:
             loadGenMaxRecords: "15000"
+  slos:
+    - name: "lag trend"
+      sloType: "lag trend"
+      prometheusUrl: "http://prometheus-operated:9090"
+      offset: 0
+      properties:
+        threshold: 3000
+        externalSloUrl: "http://localhost:80/evaluate-slope"
+        warmup: 60 # in seconds
   kafkaConfig:
     bootstrapServer: "theodolite-kafka-kafka-bootstrap:9092"
     topics:
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..077c4ab410e3fc78a9bb47c563c2b237b922c1ba 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,24 +5,26 @@ metadata:
 spec:
   name: test
   benchmark: "uc1-kstreams"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
     resourceType: "Instances"
     resourceValues: [1, 2, 3, 4, 5]
   slos:
-    - sloType: "lag trend"
+    - name: "lag trend"
       threshold: 2000
       prometheusUrl: "http://prometheus-operated:9090"
       externalSloUrl: "http://localhost:80/evaluate-slope"
       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..504a73fe3b325368301897cacdc922e7f6e70430 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,25 +5,23 @@ metadata:
 spec:
   name: test
   benchmark: "uc1-kstreams-update"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
     resourceType: "Instances"
     resourceValues: [1, 2, 3, 4, 5]
   slos:
-    - sloType: "lag trend"
-      prometheusUrl: "http://prometheus-operated:9090"
-      offset: 0
+    - name: "lag trend"
       properties:
         threshold: 2000
-        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..2bd0bfc4b3602c52fc3cc5cce9729777c21f4ac4 100644
--- a/theodolite/src/test/resources/k8s-resource-files/test-execution.yaml
+++ b/theodolite/src/test/resources/k8s-resource-files/test-execution.yaml
@@ -5,25 +5,23 @@ metadata:
 spec:
   name: test
   benchmark: "uc1-kstreams"
-  load:
+  loads:
     loadType: "NumSensors"
     loadValues: [25000, 50000, 75000, 100000, 125000, 150000]
   resources:
     resourceType: "Instances"
     resourceValues: [1, 2, 3, 4, 5]
   slos:
-    - sloType: "lag trend"
-      prometheusUrl: "http://prometheus-operated:9090"
-      offset: 0
+    - name: "lag trend"
       properties:
         threshold: 2000
-        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: []