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/api-reference/crds.md b/docs/api-reference/crds.md
index f0962d47400dfb85f8f9a2b695fec49cc45fe6e8..87c4e9046396456e2177098c8085aa995534735b 100644
--- a/docs/api-reference/crds.md
+++ b/docs/api-reference/crds.md
@@ -230,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>
@@ -252,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>
@@ -269,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>
 
 
 
@@ -307,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/>
@@ -317,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>
 
 
 
@@ -363,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>
@@ -385,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>
@@ -402,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>
 
 
 
@@ -440,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/>
@@ -450,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>
 
 
 
@@ -820,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>
@@ -864,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>
@@ -886,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>
@@ -903,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>
 
 
 
@@ -941,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/>
@@ -951,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>
 
 
 
@@ -997,17 +1228,87 @@ Specifies the pod.
         </tr>
     </thead>
     <tbody><tr>
-        <td><b><a href="#benchmarkspecsutbeforeactionsindexexec">exec</a></b></td>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexdelete">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="#benchmarkspecsutbeforeactionsindexselector">selector</a></b></td>
+        <td><b><a href="#benchmarkspecsutbeforeactionsindexexec">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.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].delete.selector
+<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexdelete)</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>
@@ -1019,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>
@@ -1036,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>
 
 
 
@@ -1074,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/>
@@ -1084,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>
 
 
 
@@ -1279,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>
@@ -1301,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>
@@ -1318,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>
 
 
 
@@ -1356,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/>
@@ -1366,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>
 
 
 
@@ -1412,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>
@@ -1434,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>
@@ -1451,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>
 
 
 
@@ -1489,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/>
@@ -1499,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>
 
 
 
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/Chart.yaml b/helm/Chart.yaml
index 5d707a70599b8a26ce828c94223ac20903f71848..d890cf35119294faac3590b8beacbe18c61859b1 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -8,6 +8,7 @@ maintainers:
 - name: Sören Henning
   email: soeren.henning@email.uni-kiel.de
   url: https://www.se.informatik.uni-kiel.de/en/team/soeren-henning-m-sc
+icon: https://www.theodolite.rocks/assets/logo/theodolite-stacked-transparent.svg
 
 type: application
 
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..6dd78ac131c3c5f7a6e163ae729ab3d3e396dbde 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)
     return filtered['value'].aggregate(aggr_func)
 
 def check_result(result, operator: str, threshold):
@@ -63,7 +63,7 @@ async def check_slo(request: Request):
     query_aggregation = get_aggr_func(data['metadata']['queryAggregation'])
     rep_aggregation = get_aggr_func(data['metadata']['repetitionAggregation'])
     operator = data['metadata']['operator']
-    threshold = int(data['metadata']['threshold'])
+    threshold = float(data['metadata']['threshold'])
 
     query_results = [aggr_query(r[0]["values"], warmup, query_aggregation) for r in data["results"]]
     result = pd.DataFrame(query_results).aggregate(rep_aggregation).at[0]
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/slo-checker/record-lag/app/main.py b/slo-checker/record-lag/app/main.py
index bb68580a638a40bc7ae975594b859d10784adc67..1141ac88d800d2e0204a32b9f07f1aed78f5e200 100644
--- a/slo-checker/record-lag/app/main.py
+++ b/slo-checker/record-lag/app/main.py
@@ -27,7 +27,7 @@ def calculate_slope_trend(results, warmup):
         group = result['metric'].get('consumergroup', "default")
         for value in result['values']:
             d.append({'group': group, 'timestamp': int(
-                value[0]), 'value': int(value[1]) if value[1] != 'NaN' else 0})
+                value[0]), 'value': float(value[1]) if value[1] != 'NaN' else 0})
 
     df = pd.DataFrame(d)
 
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/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/AbstractFlinkService.java b/theodolite-benchmarks/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/AbstractFlinkService.java
new file mode 100644
index 0000000000000000000000000000000000000000..f348543cd9897bc3abf1871ce828c22ea531dd4c
--- /dev/null
+++ b/theodolite-benchmarks/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/AbstractFlinkService.java
@@ -0,0 +1,114 @@
+package rocks.theodolite.benchmarks.commons.flink;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.flink.runtime.state.StateBackend;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import titan.ccp.common.configuration.ServiceConfigurations;
+
+/**
+ * A general Apache Flink-based microservice. It is configured by {@link #configureEnv()}, and
+ * extended by implementing business logic in {@link #buildPipeline()}. The configuration of the
+ * serializer needs to be implemented in {@link #configureSerializers()}.
+ */
+public abstract class AbstractFlinkService {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFlinkService.class);
+  protected final StreamExecutionEnvironment env;
+
+  protected Configuration config = ServiceConfigurations.createWithDefaults();
+
+  protected final String applicationId;
+
+  /**
+   * Abstract Service constructing the name and {@link StreamExecutionEnvironment}.
+   */
+  public AbstractFlinkService() {
+    final String applicationName = this.config.getString(ConfigurationKeys.APPLICATION_NAME);
+    final String applicationVersion = this.config.getString(ConfigurationKeys.APPLICATION_VERSION);
+    this.applicationId = applicationName + "-" + applicationVersion;
+
+    this.env = StreamExecutionEnvironment.getExecutionEnvironment();
+
+  }
+
+  /**
+   * Abstract Service constructing the name and {@link StreamExecutionEnvironment}.
+   *
+   * @param config the configuration for the service.
+   */
+  public AbstractFlinkService(final Configuration config) {
+    this.config = config;
+    final String applicationName = this.config.getString(ConfigurationKeys.APPLICATION_NAME);
+    final String applicationVersion = this.config.getString(ConfigurationKeys.APPLICATION_VERSION);
+    this.applicationId = applicationName + "-" + applicationVersion;
+    this.env = StreamExecutionEnvironment.getExecutionEnvironment();
+  }
+
+
+
+  /**
+   * Configures the service using environment variables.
+   */
+  protected void configureEnv() {
+    this.configureCheckpointing();
+    this.configureParallelism();
+    this.configureStateBackend();
+    this.configureSerializers();
+  }
+
+  protected void configureCheckpointing() {
+    final boolean checkpointing = this.config.getBoolean(ConfigurationKeys.CHECKPOINTING, true);
+    final int commitIntervalMs = this.config.getInt(ConfigurationKeys.COMMIT_INTERVAL_MS);
+    LOGGER.info("Set parallelism to: {}.", checkpointing);
+    if (checkpointing) {
+      this.env.enableCheckpointing(commitIntervalMs);
+    }
+  }
+
+  /**
+   * Configures the parallelism according to the configuration.
+   */
+  protected void configureParallelism() {
+    final Integer parallelism = this.config.getInteger(ConfigurationKeys.PARALLELISM, null);
+    if (parallelism != null) {
+      LOGGER.info("Set parallelism: {}.", parallelism);
+      this.env.setParallelism(parallelism);
+    }
+  }
+
+  /**
+   * Configures the state backend according to the configuration.
+   */
+  public void configureStateBackend() {
+    LOGGER.info("Enable state backend.");
+    final StateBackend stateBackend = StateBackends.fromConfiguration(this.config);
+    this.env.setStateBackend(stateBackend);
+  }
+
+
+  protected abstract void configureSerializers();
+
+  /**
+   * Empty placeholder. Implement this method to implement the custom logic of your microservice.
+   */
+  protected abstract void buildPipeline();
+
+  /**
+   * Starts the service.
+   */
+  public void run() {
+    this.configureEnv();
+    this.buildPipeline();
+    LOGGER.info("Execution plan: {}", this.env.getExecutionPlan());
+
+    try {
+      this.env.execute(this.applicationId);
+    } catch (final Exception e) { // NOPMD Exception thrown by Flink
+      LOGGER.error("An error occured while running this job.", e);
+    }
+  }
+
+
+}
diff --git a/theodolite-benchmarks/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/ConfigurationKeys.java b/theodolite-benchmarks/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/ConfigurationKeys.java
index 8fd8fbde288d1750fb1bab2147885d7be6245316..9eb143c3c07f879de37eafa2fbe6729bf182d45e 100644
--- a/theodolite-benchmarks/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/ConfigurationKeys.java
+++ b/theodolite-benchmarks/flink-commons/src/main/java/rocks/theodolite/benchmarks/commons/flink/ConfigurationKeys.java
@@ -5,6 +5,26 @@ package rocks.theodolite.benchmarks.commons.flink;
  */
 public final class ConfigurationKeys {
 
+  public static final String APPLICATION_NAME = "application.name";
+
+  public static final String APPLICATION_VERSION = "application.version";
+
+  public static final String CONFIGURATION_KAFKA_TOPIC = "configuration.kafka.topic";
+
+  public static final String KAFKA_BOOTSTRAP_SERVERS = "kafka.bootstrap.servers";
+
+  public static final String KAFKA_OUTPUT_TOPIC = "kafka.output.topic";
+
+  public static final String KAFKA_INPUT_TOPIC = "kafka.input.topic";
+
+  public static final String SCHEMA_REGISTRY_URL = "schema.registry.url";
+
+  public static final String WINDOW_SIZE_MS = "window.size.ms";
+
+  public static final String WINDOW_GRACE_MS = "window.grace.ms";
+
+  public static final String COMMIT_INTERVAL_MS = "commit.interval.ms";
+
   public static final String FLINK_STATE_BACKEND = "flink.state.backend";
 
   public static final String FLINK_STATE_BACKEND_PATH = "flink.state.backend.path";
@@ -12,7 +32,11 @@ public final class ConfigurationKeys {
   public static final String FLINK_STATE_BACKEND_MEMORY_SIZE = // NOPMD
       "flink.state.backend.memory.size";
 
-  public static final String FLINK_CHECKPOINTING = "checkpointing";
+  public static final String DEBUG = "debug";
+
+  public static final String CHECKPOINTING = "checkpointing";
+
+  public static final String PARALLELISM = "parallelism";
 
   private ConfigurationKeys() {}
 
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 d674effac653cb1613a1b218f381ec3c6c910673..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
@@ -1,63 +1,35 @@
 package rocks.theodolite.benchmarks.uc1.flink;
 
-import org.apache.commons.configuration2.Configuration;
 import org.apache.flink.api.common.typeinfo.Types;
 import org.apache.flink.streaming.api.datastream.DataStream;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+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.common.configuration.ServiceConfigurations;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * The History microservice implemented as a Flink job.
  */
-public final class HistoryServiceFlinkJob {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(HistoryServiceFlinkJob.class);
-
-  private final Configuration config = ServiceConfigurations.createWithDefaults();
-  private final StreamExecutionEnvironment env;
-  private final String applicationId;
+public final class HistoryServiceFlinkJob extends AbstractFlinkService {
 
   private final DatabaseAdapter<String> databaseAdapter = LogWriterFactory.forJson();
 
-  /**
-   * Create a new instance of the {@link HistoryServiceFlinkJob}.
-   */
-  public HistoryServiceFlinkJob() {
-    final String applicationName = this.config.getString(ConfigurationKeys.APPLICATION_NAME);
-    final String applicationVersion = this.config.getString(ConfigurationKeys.APPLICATION_VERSION);
-    this.applicationId = applicationName + "-" + applicationVersion;
-
-    this.env = StreamExecutionEnvironment.getExecutionEnvironment();
-
-    this.configureEnv();
-
-    this.buildPipeline();
+  @Override
+  public void configureEnv() {
+    super.configureCheckpointing();
+    super.configureParallelism();
   }
 
-  private void configureEnv() {
-    final boolean checkpointing = this.config.getBoolean(ConfigurationKeys.CHECKPOINTING, true);
-    final int commitIntervalMs = this.config.getInt(ConfigurationKeys.COMMIT_INTERVAL_MS);
-    if (checkpointing) {
-      this.env.enableCheckpointing(commitIntervalMs);
-    }
-
-    // Parallelism
-    final Integer parallelism = this.config.getInteger(ConfigurationKeys.PARALLELISM, null);
-    if (parallelism != null) {
-      LOGGER.info("Set parallelism: {}.", parallelism);
-      this.env.setParallelism(parallelism);
-    }
-
+  @Override
+  protected void configureSerializers() {
+    // No serializers needed here
   }
 
-  private void buildPipeline() {
+
+  @Override
+  protected void buildPipeline() {
     final String kafkaBroker = this.config.getString(ConfigurationKeys.KAFKA_BOOTSTRAP_SERVERS);
     final String schemaRegistryUrl = this.config.getString(ConfigurationKeys.SCHEMA_REGISTRY_URL);
     final String inputTopic = this.config.getString(ConfigurationKeys.KAFKA_INPUT_TOPIC);
@@ -79,17 +51,6 @@ public final class HistoryServiceFlinkJob {
         .returns(Types.VOID); // Will never be used
   }
 
-  /**
-   * Start running this microservice.
-   */
-  public void run() {
-    try {
-      this.env.execute(this.applicationId);
-    } catch (final Exception e) { // NOPMD Execution thrown by Flink
-      LOGGER.error("An error occured while running this job.", e);
-    }
-  }
-
   public static void main(final String[] args) {
     new HistoryServiceFlinkJob().run();
   }
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
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineFactory.java b/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineFactory.java
index 9fb1cc05a2048efb881e21c48678c93839082f3c..7935ba8d732b7574c1c170330d79b1d475dec731 100644
--- a/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineFactory.java
+++ b/theodolite-benchmarks/uc1-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc1/hazelcastjet/Uc1PipelineFactory.java
@@ -1,19 +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;
 import java.util.Properties;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 import rocks.theodolite.benchmarks.commons.hazelcastjet.PipelineFactory;
 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;
 
 public class Uc1PipelineFactory extends PipelineFactory {
 
@@ -47,7 +46,7 @@ public class Uc1PipelineFactory extends PipelineFactory {
     // 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();
@@ -57,7 +56,6 @@ public class Uc1PipelineFactory extends PipelineFactory {
     return pipe;
   }
 
-
   /**
    * Extends to a blank Hazelcast Jet Pipeline the UC1 topology defines by Theodolite.
    *
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 4e25dd2bef6a7743db96a7b1c8a8705692ac8edc..d90f2b1edb448cf29b15db39695a418cbb3389ba 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,11 +14,11 @@ 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.Properties;
 import java.util.concurrent.CompletionException;
-import com.hazelcast.logging.ILogger;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -24,11 +26,11 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+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.Uc1PipelineFactory;
-import titan.ccp.model.records.ActivePowerRecord;
 
 import static com.hazelcast.jet.pipeline.SinkBuilder.sinkBuilder;
 import static com.hazelcast.logging.Logger.getLogger;
@@ -57,7 +59,7 @@ public class Uc1PipelineTest extends JetTestSupport {
   @Before
   public void buildUc1Pipeline() {
 
-    this.logger.info("Hazelcast Logger");
+    Uc1PipelineTest.logger.info("Hazelcast Logger");
     LOGGER.info("Standard Logger");
 
 
@@ -69,9 +71,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
@@ -97,14 +99,14 @@ public class Uc1PipelineTest extends JetTestSupport {
         .<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);
   }
 
@@ -123,8 +125,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 7e67be897ce06f9f12e3fbcefb61d44a0775eea5..5a34d17a89186630afb0917e16940210b84fd5e8 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,11 +1,8 @@
 package rocks.theodolite.benchmarks.uc2.flink;
 
 import com.google.common.math.Stats;
-import org.apache.commons.configuration2.Configuration;
 import org.apache.flink.api.common.typeinfo.Types;
 import org.apache.flink.api.java.tuple.Tuple2;
-import org.apache.flink.runtime.state.StateBackend;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
 import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
 import org.apache.flink.streaming.api.windowing.time.Time;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
@@ -13,61 +10,22 @@ 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.flink.AbstractFlinkService;
 import rocks.theodolite.benchmarks.commons.flink.KafkaConnectorFactory;
-import rocks.theodolite.benchmarks.commons.flink.StateBackends;
 import rocks.theodolite.benchmarks.commons.flink.serialization.StatsSerializer;
-import titan.ccp.common.configuration.ServiceConfigurations;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
 
 
 /**
  * The History microservice implemented as a Flink job.
  */
-public final class HistoryServiceFlinkJob {
+public final class HistoryServiceFlinkJob extends AbstractFlinkService {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(HistoryServiceFlinkJob.class);
 
-  private final Configuration config = ServiceConfigurations.createWithDefaults();
-  private final StreamExecutionEnvironment env;
-  private final String applicationId;
 
-  /**
-   * Create a new instance of the {@link HistoryServiceFlinkJob}.
-   */
-  public HistoryServiceFlinkJob() {
-    final String applicationName = this.config.getString(ConfigurationKeys.APPLICATION_NAME);
-    final String applicationVersion = this.config.getString(ConfigurationKeys.APPLICATION_VERSION);
-    this.applicationId = applicationName + "-" + applicationVersion;
-
-    this.env = StreamExecutionEnvironment.getExecutionEnvironment();
-
-    this.configureEnv();
-
-    this.buildPipeline();
-  }
-
-  private void configureEnv() {
-    final boolean checkpointing = this.config.getBoolean(ConfigurationKeys.CHECKPOINTING, true);
-    final int commitIntervalMs = this.config.getInt(ConfigurationKeys.COMMIT_INTERVAL_MS);
-    if (checkpointing) {
-      this.env.enableCheckpointing(commitIntervalMs);
-    }
-
-    // Parallelism
-    final Integer parallelism = this.config.getInteger(ConfigurationKeys.PARALLELISM, null);
-    if (parallelism != null) {
-      LOGGER.info("Set parallelism: {}.", parallelism);
-      this.env.setParallelism(parallelism);
-    }
-
-    // State Backend
-    final StateBackend stateBackend = StateBackends.fromConfiguration(this.config);
-    this.env.setStateBackend(stateBackend);
-
-    this.configureSerializers();
-  }
-
-  private void configureSerializers() {
+  @Override
+  protected void configureSerializers() {
     this.env.getConfig().registerTypeWithKryoSerializer(Stats.class, new StatsSerializer());
     this.env.getConfig().getRegisteredTypesWithKryoSerializers()
         .forEach((c, s) -> LOGGER.info("Class " + c.getName() + " registered with serializer "
@@ -75,7 +33,8 @@ public final class HistoryServiceFlinkJob {
 
   }
 
-  private void buildPipeline() {
+  @Override
+  protected void buildPipeline() {
     final String kafkaBroker = this.config.getString(ConfigurationKeys.KAFKA_BOOTSTRAP_SERVERS);
     final String schemaRegistryUrl = this.config.getString(ConfigurationKeys.SCHEMA_REGISTRY_URL);
     final String inputTopic = this.config.getString(ConfigurationKeys.KAFKA_INPUT_TOPIC);
@@ -112,20 +71,6 @@ public final class HistoryServiceFlinkJob {
         .addSink(kafkaSink).name("[Kafka Producer] Topic: " + outputTopic);
   }
 
-
-  /**
-   * Start running this microservice.
-   */
-  public void run() {
-    LOGGER.info("Execution plan: {}", this.env.getExecutionPlan());
-
-    try {
-      this.env.execute(this.applicationId);
-    } catch (final Exception e) { // NOPMD Execution thrown by Flink
-      LOGGER.error("An error occured while running this job.", e);
-    }
-  }
-
   public static void main(final String[] args) {
     new HistoryServiceFlinkJob().run();
   }
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/Uc2HazelcastJetFactory.java b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2HazelcastJetFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineFactory.java b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineFactory.java
index 3948627009fcf7cf6bf24be4079e9cc22bef1e2d..b4c8fa662eab7a68a165fcbb474b6293d29202be 100644
--- a/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineFactory.java
+++ b/theodolite-benchmarks/uc2-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc2/hazelcastjet/Uc2PipelineFactory.java
@@ -12,10 +12,12 @@ import com.hazelcast.jet.pipeline.StreamSource;
 import com.hazelcast.jet.pipeline.StreamStage;
 import com.hazelcast.jet.pipeline.WindowDefinition;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
 import rocks.theodolite.benchmarks.commons.hazelcastjet.PipelineFactory;
 import rocks.theodolite.benchmarks.uc2.hazelcastjet.uc2specifics.StatsAccumulatorSupplier;
-import titan.ccp.model.records.ActivePowerRecord;
+import rocks.theodolite.benchmarks.commons.model.records.ActivePowerRecord;
+
 
 public class Uc2PipelineFactory extends PipelineFactory {
 
@@ -110,15 +112,15 @@ public class Uc2PipelineFactory extends PipelineFactory {
    * @return An AggregateOperation used by Hazelcast Jet in a streaming stage which aggregates
    *         ActivePowerRecord Objects into Stats Objects.
    */
-  public AggregateOperation1<Map.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
         // Creates the accumulator
         .withCreate(new StatsAccumulatorSupplier())
         // Defines the accumulation
-        .<Map.Entry<String, ActivePowerRecord>>andAccumulate((accumulator, item) -> {
+        .<Entry<String, ActivePowerRecord>>andAccumulate((accumulator, item) -> {
           accumulator.add(item.getValue().getValueInW());
         })
         // Defines the combination of spread out instances
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 4a9a2a591522a4172141f666ec23ca16a3fc7660..00e3019bfba84625981107b4229c337a8ceeff83 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
@@ -21,7 +21,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.
@@ -41,10 +41,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();
@@ -78,14 +78,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 4cf7ed080882e42bf488a8e6490c3eab463882b4..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
@@ -4,12 +4,9 @@ import com.google.common.math.Stats;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import org.apache.commons.configuration2.Configuration;
 import org.apache.flink.api.common.typeinfo.Types;
 import org.apache.flink.api.java.functions.KeySelector;
 import org.apache.flink.api.java.tuple.Tuple2;
-import org.apache.flink.runtime.state.StateBackend;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
 import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
 import org.apache.flink.streaming.api.windowing.time.Time;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
@@ -17,64 +14,24 @@ 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.flink.AbstractFlinkService;
 import rocks.theodolite.benchmarks.commons.flink.KafkaConnectorFactory;
-import rocks.theodolite.benchmarks.commons.flink.StateBackends;
 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.common.configuration.ServiceConfigurations;
-import titan.ccp.model.records.ActivePowerRecord;
 
 /**
  * The History microservice implemented as a Flink job.
  */
-public final class HistoryServiceFlinkJob {
+public final class HistoryServiceFlinkJob extends AbstractFlinkService {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(HistoryServiceFlinkJob.class);
 
-  private final Configuration config = ServiceConfigurations.createWithDefaults();
-  private final StreamExecutionEnvironment env;
-  private final String applicationId;
-
-  /**
-   * Create a new instance of the {@link HistoryServiceFlinkJob}.
-   */
-  public HistoryServiceFlinkJob() {
-    final String applicationName = this.config.getString(ConfigurationKeys.APPLICATION_NAME);
-    final String applicationVersion = this.config.getString(ConfigurationKeys.APPLICATION_VERSION);
-    this.applicationId = applicationName + "-" + applicationVersion;
-
-    this.env = StreamExecutionEnvironment.getExecutionEnvironment();
-
-    this.configureEnv();
-
-    this.buildPipeline();
-  }
-
-  private void configureEnv() {
-    final boolean checkpointing = this.config.getBoolean(ConfigurationKeys.CHECKPOINTING, true);
-    final int commitIntervalMs = this.config.getInt(ConfigurationKeys.COMMIT_INTERVAL_MS);
-    if (checkpointing) {
-      this.env.enableCheckpointing(commitIntervalMs);
-    }
-
-    // Parallelism
-    final Integer parallelism = this.config.getInteger(ConfigurationKeys.PARALLELISM, null);
-    if (parallelism != null) {
-      LOGGER.error("Set parallelism: {}.", parallelism);
-      this.env.setParallelism(parallelism);
-    }
-
-    // State Backend
-    final StateBackend stateBackend = StateBackends.fromConfiguration(this.config);
-    this.env.setStateBackend(stateBackend);
-
-    this.configureSerializers();
-  }
-
-  private void configureSerializers() {
+  @Override
+  protected void configureSerializers() {
     this.env.getConfig().registerTypeWithKryoSerializer(HourOfDayKey.class,
         new HourOfDayKeySerde());
     this.env.getConfig().registerTypeWithKryoSerializer(Stats.class, new StatsSerializer());
@@ -86,7 +43,8 @@ public final class HistoryServiceFlinkJob {
     }
   }
 
-  private void buildPipeline() {
+  @Override
+  protected void buildPipeline() {
     // Configurations
     final String kafkaBroker = this.config.getString(ConfigurationKeys.KAFKA_BOOTSTRAP_SERVERS);
     final String schemaRegistryUrl = this.config.getString(ConfigurationKeys.SCHEMA_REGISTRY_URL);
@@ -135,21 +93,6 @@ public final class HistoryServiceFlinkJob {
         .addSink(kafkaSink).name("[Kafka Producer] Topic: " + outputTopic);
   }
 
-  /**
-   * Start running this microservice.
-   */
-  public void run() {
-    // Execution plan
-    LOGGER.info("Execution Plan: {}", this.env.getExecutionPlan());
-
-    // Execute Job
-    try {
-      this.env.execute(this.applicationId);
-    } catch (final Exception e) { // NOPMD Execution thrown by Flink
-      LOGGER.error("An error occured while running this job.", e);
-    }
-  }
-
   public static void main(final String[] args) {
     new HistoryServiceFlinkJob().run();
   }
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
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineFactory.java b/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineFactory.java
index eeea4f2b7987bdda7fe8f7e4623c71a271233cd9..2b5e479c5bb7a140d9a8dfab781494de93308d4e 100644
--- a/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineFactory.java
+++ b/theodolite-benchmarks/uc3-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc3/hazelcastjet/Uc3PipelineFactory.java
@@ -11,14 +11,15 @@ import com.hazelcast.jet.pipeline.WindowDefinition;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.util.Map;
+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.commons.hazelcastjet.PipelineFactory;
 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;
 
 
 public class Uc3PipelineFactory extends PipelineFactory {
@@ -114,7 +115,7 @@ public class Uc3PipelineFactory extends PipelineFactory {
           return Map.entry(newKey, record.getValue());
         })
         // group by new keys
-        .groupingKey(Map.Entry::getKey)
+        .groupingKey(Entry::getKey)
         // Sliding/Hopping Window
         .window(WindowDefinition.sliding(TimeUnit.DAYS.toMillis(windowSizeInDays),
             TimeUnit.DAYS.toMillis(hoppingSizeInDays)))
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 e4f8d9b8c622346ace13b168e524326ed1961f0f..f54c9d719a469cb8f645825b20ec4f71e7d2fb79 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,11 +14,11 @@ 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.Properties;
 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;
@@ -27,9 +27,9 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+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.
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 726a7f590aaa5be4ccb6e817076da5ede21cf272..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
@@ -2,15 +2,12 @@ package rocks.theodolite.benchmarks.uc4.flink; // NOPMD Imports required
 
 import java.time.Duration;
 import java.util.Set;
-import org.apache.commons.configuration2.Configuration;
 import org.apache.flink.api.common.eventtime.WatermarkStrategy;
 import org.apache.flink.api.common.typeinfo.TypeInformation;
 import org.apache.flink.api.common.typeinfo.Types;
 import org.apache.flink.api.java.functions.KeySelector;
 import org.apache.flink.api.java.tuple.Tuple2;
-import org.apache.flink.runtime.state.StateBackend;
 import org.apache.flink.streaming.api.datastream.DataStream;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
 import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
 import org.apache.flink.streaming.api.windowing.time.Time;
 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
@@ -19,76 +16,30 @@ 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.StateBackends;
 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.configuration.ServiceConfigurations;
-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.
  */
-public final class AggregationServiceFlinkJob {
+public final class AggregationServiceFlinkJob extends AbstractFlinkService {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(AggregationServiceFlinkJob.class);
 
-  private final Configuration config = ServiceConfigurations.createWithDefaults();
-  private final StreamExecutionEnvironment env;
-  private final String applicationId;
-
-  /**
-   * Create a new {@link AggregationServiceFlinkJob}.
-   */
-  public AggregationServiceFlinkJob() {
-    final String applicationName = this.config.getString(ConfigurationKeys.APPLICATION_NAME);
-    final String applicationVersion = this.config.getString(ConfigurationKeys.APPLICATION_VERSION);
-    this.applicationId = applicationName + "-" + applicationVersion;
-
-    // Execution environment configuration
-    // org.apache.flink.configuration.Configuration conf = new
-    // org.apache.flink.configuration.Configuration();
-    // conf.setBoolean(ConfigConstants.LOCAL_START_WEBSERVER, true);
-    // final StreamExecutionEnvironment env =
-    // StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(conf);
-    this.env = StreamExecutionEnvironment.getExecutionEnvironment();
-
-    this.configureEnv();
-
-    this.buildPipeline();
-  }
-
-  private void configureEnv() {
-    final boolean checkpointing = this.config.getBoolean(ConfigurationKeys.CHECKPOINTING, true);
-    final int commitIntervalMs = this.config.getInt(ConfigurationKeys.COMMIT_INTERVAL_MS);
-    if (checkpointing) {
-      this.env.enableCheckpointing(commitIntervalMs);
-    }
-
-    // Parallelism
-    final Integer parallelism = this.config.getInteger(ConfigurationKeys.PARALLELISM, null);
-    if (parallelism != null) {
-      LOGGER.info("Set parallelism: {}.", parallelism);
-      this.env.setParallelism(parallelism);
-    }
-
-    // State Backend
-    final StateBackend stateBackend = StateBackends.fromConfiguration(this.config);
-    this.env.setStateBackend(stateBackend);
-
-    this.configureSerializers();
-  }
-
-  private void configureSerializers() {
+  @Override
+  protected void configureSerializers() {
     this.env.getConfig().registerTypeWithKryoSerializer(ImmutableSensorRegistry.class,
         new ImmutableSensorRegistrySerializer());
     this.env.getConfig().registerTypeWithKryoSerializer(SensorParentKey.class,
@@ -108,7 +59,8 @@ public final class AggregationServiceFlinkJob {
             s.getSerializer().getClass().getName()));
   }
 
-  private void buildPipeline() {
+  @Override
+  protected void buildPipeline() {
     // Get configurations
     final String kafkaBroker = this.config.getString(ConfigurationKeys.KAFKA_BOOTSTRAP_SERVERS);
     final String schemaRegistryUrl = this.config.getString(ConfigurationKeys.SCHEMA_REGISTRY_URL);
@@ -204,21 +156,6 @@ public final class AggregationServiceFlinkJob {
         .addSink(kafkaAggregationSink).name("[Kafka Producer] Topic: " + outputTopic);
   }
 
-  /**
-   * Start running this microservice.
-   */
-  public void run() {
-    // Execution plan
-    LOGGER.info("Execution plan: {}", this.env.getExecutionPlan());
-
-    // Execute Job
-    try {
-      this.env.execute(this.applicationId);
-    } catch (final Exception e) { // NOPMD Execution thrown by Flink
-      LOGGER.error("An error occured while running this job.", e);
-    }
-  }
-
   public static void main(final String[] args) {
     new AggregationServiceFlinkJob().run();
   }
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
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineFactory.java b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineFactory.java
index 166f27588c09cc8821d98f5e9fae8e7d12bfa743..c6a73f50d66f6e11014838f7602f1a4c2dde42e8 100644
--- a/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineFactory.java
+++ b/theodolite-benchmarks/uc4-hazelcastjet/src/main/java/rocks/theodolite/benchmarks/uc4/hazelcastjet/Uc4PipelineFactory.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;
@@ -28,10 +27,10 @@ import rocks.theodolite.benchmarks.uc4.hazelcastjet.uc4specifics.AggregatedActiv
 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;
+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;
 
 
 public class Uc4PipelineFactory extends PipelineFactory {
@@ -91,17 +90,17 @@ public class Uc4PipelineFactory extends PipelineFactory {
   public Pipeline buildPipeline() {
 
     // Sources for this use case
-    final StreamSource<Map.Entry<Event, String>> configSource =
+    final StreamSource<Entry<Event, String>> configSource =
         KafkaSources.kafka(kafkaConfigPropsForPipeline, kafkaConfigurationTopic);
 
-    final StreamSource<Map.Entry<String, ActivePowerRecord>> inputSource =
+    final StreamSource<Entry<String, ActivePowerRecord>> inputSource =
         KafkaSources.kafka(kafkaReadPropsForPipeline, kafkaInputTopic);
 
-    final StreamSource<Map.Entry<String, AggregatedActivePowerRecord>> aggregationSource =
+    final StreamSource<Entry<String, AggregatedActivePowerRecord>> aggregationSource =
         KafkaSources.kafka(kafkaFeedbackPropsForPipeline, kafkaFeedbackTopic);
 
     // Extend UC4 topology to pipeline
-    final StreamStage<Map.Entry<String, AggregatedActivePowerRecord>> uc4Aggregation =
+    final StreamStage<Entry<String, AggregatedActivePowerRecord>> uc4Aggregation =
         this.extendUc4Topology(inputSource, aggregationSource, configSource);
 
     // Add Sink2: Write back to kafka feedback/aggregation topic
@@ -125,9 +124,9 @@ public class Uc4PipelineFactory extends PipelineFactory {
    *
    * <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>
@@ -164,18 +163,18 @@ public class Uc4PipelineFactory extends PipelineFactory {
         .flatMapStateful(HashMap::new, new ConfigFlatMap())
         .writeTo(Sinks.mapWithUpdating(
             SENSOR_PARENT_MAP_NAME, // The addressed IMAP
-            Map.Entry::getKey, // The key to look for
+            Entry::getKey, // The key to look for
             (oldValue, newEntry) -> newEntry.getValue()));
 
     //////////////////////////////////
     // (1) Sensor Input Stream
-    final StreamStage<Map.Entry<String, ActivePowerRecord>> inputStream = pipe
+    final StreamStage<Entry<String, ActivePowerRecord>> inputStream = pipe
         .readFrom(inputSource)
         .withNativeTimestamps(0);
 
     //////////////////////////////////
     // (1) Aggregation Stream
-    final StreamStage<Map.Entry<String, ActivePowerRecord>> aggregations = pipe
+    final StreamStage<Entry<String, ActivePowerRecord>> aggregations = pipe
         .readFrom(aggregationSource)
         .withNativeTimestamps(0)
         .map(entry -> { // Map Aggregated to ActivePowerRecord
@@ -187,39 +186,29 @@ public class Uc4PipelineFactory extends PipelineFactory {
 
     //////////////////////////////////
     // (2) UC4 Merge Input with aggregation stream
-    final StreamStageWithKey<Map.Entry<String, ActivePowerRecord>, String>
+    final StreamStageWithKey<Entry<String, ActivePowerRecord>, String>
         mergedInputAndAggregations = inputStream
         .merge(aggregations)
-        .groupingKey(Map.Entry::getKey);
+        .groupingKey(Entry::getKey);
 
     //////////////////////////////////
     // (3) UC4 Join Configuration and Merges Input/Aggregation Stream
     // [sensorKey , (value,Set<Groups>)]
-    final StreamStage<Map.Entry<String, ValueGroup>> joinedStage = mergedInputAndAggregations
+    final StreamStage<Entry<String, ValueGroup>> joinedStage = mergedInputAndAggregations
         .<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);
             });
 
     //////////////////////////////////
     // (4) UC4 Duplicate as flatmap joined Stream
     // [(sensorKey, Group) , value]
-    final StreamStage<Map.Entry<SensorGroupKey, ActivePowerRecord>> dupliAsFlatmappedStage =
-        joinedStage.flatMap(entry -> {
+    final StreamStage<Entry<SensorGroupKey, ActivePowerRecord>> dupliAsFlatmappedStage = joinedStage
+        .flatMap(entry -> {
 
           // Supplied data
           final String keyGroupId = entry.getKey();
@@ -229,7 +218,7 @@ public class Uc4PipelineFactory extends PipelineFactory {
           // Transformed Data
           final String[] groupList = groups.toArray(String[]::new);
           final SensorGroupKey[] newKeyList = new SensorGroupKey[groupList.length];
-          final List<Map.Entry<SensorGroupKey, ActivePowerRecord>> newEntryList = new ArrayList<>();
+          final List<Entry<SensorGroupKey, ActivePowerRecord>> newEntryList = new ArrayList<>();
           for (int i = 0; i < groupList.length; i++) {
             newKeyList[i] = new SensorGroupKey(keyGroupId, groupList[i]);
             newEntryList.add(Util.entry(newKeyList[i], record));
@@ -242,15 +231,15 @@ public class Uc4PipelineFactory extends PipelineFactory {
     //////////////////////////////////
     // (5) UC4 Last Value Map
     // Table with tumbling window differentiation [ (sensorKey,Group) , value ],Time
-    final StageWithWindow<Map.Entry<SensorGroupKey, ActivePowerRecord>>
+    final StageWithWindow<Entry<SensorGroupKey, ActivePowerRecord>>
         windowedLastValues = dupliAsFlatmappedStage
         .window(WindowDefinition.tumbling(windowSize));
 
-    final AggregateOperation1<Map.Entry<SensorGroupKey, ActivePowerRecord>,
+    final AggregateOperation1<Entry<SensorGroupKey, ActivePowerRecord>,
         AggregatedActivePowerRecordAccumulator, AggregatedActivePowerRecord> aggrOp =
         AggregateOperation
             .withCreate(AggregatedActivePowerRecordAccumulator::new)
-            .<Map.Entry<SensorGroupKey, ActivePowerRecord>>andAccumulate((acc, rec) -> {
+            .<Entry<SensorGroupKey, ActivePowerRecord>>andAccumulate((acc, rec) -> {
               acc.setId(rec.getKey().getGroup());
               acc.addInputs(rec.getValue());
             })
@@ -277,14 +266,14 @@ public class Uc4PipelineFactory extends PipelineFactory {
    * FlatMap function used to process the configuration input for UC4.
    */
   private static class ConfigFlatMap implements
-      BiFunctionEx<Map<String, Set<String>>, Map.Entry<Event, SensorRegistry>, Traverser<Map.Entry<String, Set<String>>>> { // NOCS
+      BiFunctionEx<Map<String, Set<String>>, Entry<Event, SensorRegistry>, Traverser<Entry<String, Set<String>>>> { // NOCS
 
     private static final long serialVersionUID = -6769931374907428699L;
 
     @Override
-    public Traverser<Map.Entry<String, Set<String>>> applyEx(
+    public Traverser<Entry<String, Set<String>>> applyEx(
         final Map<String, Set<String>> flatMapStage,
-        final Map.Entry<Event, SensorRegistry> eventItem) {
+        final Entry<Event, SensorRegistry> eventItem) {
       // Transform new Input
       final ChildParentsTransformer transformer = new ChildParentsTransformer("default-name");
       final Map<String, Set<String>> mapFromRegistry =
@@ -303,7 +292,7 @@ public class Uc4PipelineFactory extends PipelineFactory {
       }
 
       // Create a updates list to pass onto the next pipeline stage-
-      final List<Map.Entry<String, Set<String>>> updatesList = new ArrayList<>(updates.entrySet());
+      final List<Entry<String, Set<String>>> updatesList = new ArrayList<>(updates.entrySet());
 
       // Return traverser with updates list.
       return Traversers.traverseIterable(updatesList)
@@ -311,4 +300,5 @@ public class Uc4PipelineFactory extends PipelineFactory {
     }
 
   }
+
 }
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 fcc42aed623873e61434b2aa003698ebd5dc062f..29535ddb1bce6daf8a972a208b4393f224063d89 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
@@ -25,26 +25,25 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 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.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 {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(Uc4PipelineTest.class);
 
-
-  // Test Machinery
   JetInstance testInstance = null;
   Pipeline testPipeline = null;
   StreamStage<Entry<String, AggregatedActivePowerRecord>> uc4Topology = null;
@@ -60,7 +59,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);
@@ -80,7 +79,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,
@@ -105,7 +104,7 @@ public class Uc4PipelineTest extends JetTestSupport {
 
           // Topology:
           // level2Group -> level1Group -> testSensor
-          
+
           // Create Registry
           final MutableSensorRegistry testRegistry = new MutableSensorRegistry(testLevel2GroupName);
           // Add Sensors
@@ -147,7 +146,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");
 
@@ -174,11 +173,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;
               }
 
@@ -197,9 +196,10 @@ public class Uc4PipelineTest extends JetTestSupport {
           LOGGER.info("Average calculation correct =: " + avOk);
 
           Assert.assertTrue("Assertion did not complete!", allOkay);
+
         }));
 
-    try{
+    try {
 
       final JobConfig jobConfig = new JobConfig()
           .registerSerializer(ValueGroup.class, ValueGroupSerializer.class)
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/build.gradle b/theodolite/build.gradle
index 7e10245b8605ba926ac171e260bc145378a0d8d8..2ca866416674985194135def55b782102505f3c7 100644
--- a/theodolite/build.gradle
+++ b/theodolite/build.gradle
@@ -31,7 +31,8 @@ dependencies {
 
     testImplementation 'io.quarkus:quarkus-junit5'
     testImplementation 'io.quarkus:quarkus-test-kubernetes-client'
-    testImplementation 'io.rest-assured:rest-assured'
+    //testImplementation 'io.rest-assured:rest-assured'
+    testImplementation 'com.github.tomakehurst:wiremock-jre8:2.33.2'
     testImplementation 'org.junit-pioneer:junit-pioneer:1.5.0'
     testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
 }
diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml
index d73ec0105c7f97d0e425307fc4f21fd84d1e9b46..cfc9d3bd6a196cd5740463d41beb64276f4ffa57 100644
--- a/theodolite/crd/crd-benchmark.yaml
+++ b/theodolite/crd/crd-benchmark.yaml
@@ -74,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.
@@ -105,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.
@@ -142,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
@@ -181,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.
@@ -216,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.
@@ -252,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
@@ -295,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.
@@ -326,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.
@@ -363,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
diff --git a/theodolite/src/main/kotlin/theodolite/util/Config.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/Config.kt
similarity index 68%
rename from theodolite/src/main/kotlin/theodolite/util/Config.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/Config.kt
index 675caea5fbd3b8e8c699019e10f43c36b9fbaebe..c429d6b3f456c345c7ab2adb1ccd95635603ef4f 100644
--- a/theodolite/src/main/kotlin/theodolite/util/Config.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/Config.kt
@@ -1,8 +1,8 @@
-package theodolite.util
+package rocks.theodolite.core
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.strategies.Metric
-import theodolite.strategies.searchstrategy.SearchStrategy
+import rocks.theodolite.core.strategies.Metric
+import rocks.theodolite.core.strategies.searchstrategy.SearchStrategy
 
 /**
  * Config class that represents a configuration of a theodolite run.
@@ -15,9 +15,7 @@ import theodolite.strategies.searchstrategy.SearchStrategy
 @RegisterForReflection
 data class Config(
         val loads: List<Int>,
-        val loadPatcherDefinitions : List<PatcherDefinition>,
         val resources: List<Int>,
-        val resourcePatcherDefinitions : List<PatcherDefinition>,
         val searchStrategy: SearchStrategy,
         val metric: Metric
 )
diff --git a/theodolite/src/main/kotlin/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/theodolite/util/Results.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/Results.kt
similarity index 98%
rename from theodolite/src/main/kotlin/theodolite/util/Results.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/Results.kt
index 418ac50f285996affd7db1c15fc44a22f1677d29..16e6b517e1f570fd17a1b9688aff4f41ec8c9884 100644
--- a/theodolite/src/main/kotlin/theodolite/util/Results.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/Results.kt
@@ -1,7 +1,7 @@
-package theodolite.util
+package rocks.theodolite.core
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.strategies.Metric
+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
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/Metric.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/Metric.kt
similarity index 87%
rename from theodolite/src/main/kotlin/theodolite/strategies/Metric.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/Metric.kt
index 05383ca913a460641a6e632211787a2aec17e9d0..db161d10c61fae512e28ba059e604835d22aeb96 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/Metric.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/Metric.kt
@@ -1,4 +1,4 @@
-package theodolite.strategies
+package rocks.theodolite.core.strategies
 
 enum class Metric(val value: String) {
     DEMAND("demand"),
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/StrategyFactory.kt
similarity index 67%
rename from theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/StrategyFactory.kt
index 505681716966016548416bf40cefc2c9ad15d805..d2925c798e29705f3333130e8c9f09e32d7ec31c 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/StrategyFactory.kt
@@ -1,11 +1,11 @@
-package theodolite.strategies
+package rocks.theodolite.core.strategies
 
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.execution.BenchmarkExecutor
-import theodolite.strategies.restriction.LowerBoundRestriction
-import theodolite.strategies.restriction.RestrictionStrategy
-import theodolite.strategies.searchstrategy.*
-import theodolite.util.Results
+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.
@@ -22,28 +22,24 @@ class StrategyFactory {
      *
      * @throws IllegalArgumentException if the [SearchStrategy] was not one of the allowed options.
      */
-    fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyObject: BenchmarkExecution.Strategy,
-                             results: Results): SearchStrategy {
+    fun createSearchStrategy(executor: ExperimentRunner, name: String, searchStrategy: String, restrictions: List<String>,
+                             guessStrategy: String, results: Results): SearchStrategy {
 
-        var strategy : SearchStrategy = when (searchStrategyObject.name) {
+        var strategy : SearchStrategy = when (name) {
             "FullSearch" -> FullSearch(executor)
             "LinearSearch" -> LinearSearch(executor)
             "BinarySearch" -> BinarySearch(executor)
-            "RestrictionSearch" -> when (searchStrategyObject.searchStrategy){
-                "FullSearch" -> composeSearchRestrictionStrategy(executor, FullSearch(executor), results,
-                        searchStrategyObject.restrictions)
-                "LinearSearch" -> composeSearchRestrictionStrategy(executor, LinearSearch(executor), results,
-                        searchStrategyObject.restrictions)
-                "BinarySearch" -> composeSearchRestrictionStrategy(executor, BinarySearch(executor), results,
-                        searchStrategyObject.restrictions)
-                else -> throw IllegalArgumentException(
-                        "Search Strategy ${searchStrategyObject.searchStrategy} for RestrictionSearch not found")
+            "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 (searchStrategyObject.guessStrategy){
-                "PrevResourceMinGuess" -> InitialGuessSearchStrategy(executor,PrevInstanceOptGuess(), results)
-                else -> throw IllegalArgumentException("Guess Strategy ${searchStrategyObject.guessStrategy} not found")
+            "InitialGuessSearch" -> when (guessStrategy){
+                "PrevResourceMinGuess" -> InitialGuessSearchStrategy(executor, PrevInstanceOptGuess(), results)
+                else -> throw IllegalArgumentException("Guess Strategy $guessStrategy not found")
             }
-            else -> throw IllegalArgumentException("Search Strategy $searchStrategyObject not found")
+            else -> throw IllegalArgumentException("Search Strategy not found")
         }
 
         return strategy
@@ -78,7 +74,7 @@ class StrategyFactory {
      * @param results The [Results] saves the state of the Theodolite benchmark run.
      * @param restrictions The [RestrictionStrategy]'s to use.
      */
-    private fun composeSearchRestrictionStrategy(executor: BenchmarkExecutor, searchStrategy: SearchStrategy,
+    private fun composeSearchRestrictionStrategy(executor: ExperimentRunner, searchStrategy: SearchStrategy,
                                                  results: Results, restrictions: List<String>): SearchStrategy {
         if(restrictions.isNotEmpty()){
             return RestrictionSearch(executor,searchStrategy,createRestrictionStrategy(results, restrictions))
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/GuessStrategy.kt
similarity index 93%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/GuessStrategy.kt
index f243b8e4076d0cf0d2ef23bdd6b02b5da2d34152..6ab5c1b6d10da318c4b5b3f24d6cc521ff247e79 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/GuessStrategy.kt
@@ -1,4 +1,4 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.guessstrategy
 
 import io.quarkus.runtime.annotations.RegisterForReflection
 
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevInstanceOptGuess.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/PrevInstanceOptGuess.kt
similarity index 94%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevInstanceOptGuess.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/PrevInstanceOptGuess.kt
index c919b475995a6a5366371336041d9633f0aa1993..3b2d7b1b0e6c4133b939742a83afc55fabb7b101 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevInstanceOptGuess.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/guessstrategy/PrevInstanceOptGuess.kt
@@ -1,4 +1,4 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.guessstrategy
 
 
 /**
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestriction.kt
similarity index 90%
rename from theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestriction.kt
index 1203d7293e3790aac2af653c9ceccd0c2ef544bd..2e5a51018fd742abbb18edb1d788a6644e94d2f1 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/LowerBoundRestriction.kt
@@ -1,6 +1,6 @@
-package theodolite.strategies.restriction
+package rocks.theodolite.core.strategies.restrictionstrategy
 
-import theodolite.util.Results
+import rocks.theodolite.core.Results
 
 /**
  * The [LowerBoundRestriction] sets the lower bound of the resources to be examined in the experiment to the value
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/RestrictionStrategy.kt
similarity index 91%
rename from theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/RestrictionStrategy.kt
index 1ac9d201c734c84db4ec8837c8a242f2be8531b9..16532c32e2c9c64ac69d1c5ed32f6ec0d3345747 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/restrictionstrategy/RestrictionStrategy.kt
@@ -1,7 +1,7 @@
-package theodolite.strategies.restriction
+package rocks.theodolite.core.strategies.restrictionstrategy
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.Results
+import rocks.theodolite.core.Results
 
 /**
  * A 'Restriction Strategy' restricts a list of resources or loads depending on the metric based on the current
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/BinarySearch.kt
similarity index 86%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/BinarySearch.kt
index 6e56c3b36c6e2889e4714c890a424e4f6765386e..7c339c449e85a0fa73484d60a455016931cee473 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/BinarySearch.kt
@@ -1,16 +1,16 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.searchstrategy
 
 import mu.KotlinLogging
-import theodolite.execution.BenchmarkExecutor
+import rocks.theodolite.core.ExperimentRunner
 
 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.
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
  */
-class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
+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) {
@@ -43,7 +43,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
         if (lower == upper) {
             val res = resources[lower]
             logger.info { "Running experiment with load '$load' and resource '$res'" }
-            if (this.benchmarkExecutor.runExperiment(load, res)) return lower
+            if (this.experimentRunner.runExperiment(load, res)) return lower
             else {
                 if (lower + 1 == resources.size) return -1
                 return lower + 1
@@ -54,7 +54,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
             val mid = (upper + lower) / 2
             val res = resources[mid]
             logger.info { "Running experiment with load '$load' and resource '$res'" }
-            if (this.benchmarkExecutor.runExperiment(load, res)) {
+            if (this.experimentRunner.runExperiment(load, res)) {
                 // case length = 2
                 if (mid == lower) {
                     return lower
@@ -83,7 +83,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
         if (lower == upper) {
             val load = loads[lower]
             logger.info { "Running experiment with load '$load' and resource '$resource'" }
-            if (this.benchmarkExecutor.runExperiment(load, resource)) return lower
+            if (this.experimentRunner.runExperiment(load, resource)) return lower
             else {
                 if (lower + 1 == loads.size) return -1
                 return lower - 1
@@ -94,7 +94,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
             val mid = (upper + lower + 1) / 2 //round to next int
             val load = loads[mid]
             logger.info { "Running experiment with load '$load' and resource '$resource'" }
-            if (this.benchmarkExecutor.runExperiment(load, resource)) {
+            if (this.experimentRunner.runExperiment(load, resource)) {
                 // length = 2, so since we round down mid is equal to lower
                 if (mid == upper) {
                     return upper
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/FullSearch.kt
similarity index 73%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/FullSearch.kt
index 6af6aa1602d18a089b9450f6e1eb84bca8edafa3..7cd1dfe08cfef7ea42f0a663bbc80eb63f8ca9fe 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/FullSearch.kt
@@ -1,7 +1,7 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.searchstrategy
 
 import mu.KotlinLogging
-import theodolite.execution.BenchmarkExecutor
+import rocks.theodolite.core.ExperimentRunner
 
 private val logger = KotlinLogging.logger {}
 
@@ -12,15 +12,15 @@ private val logger = KotlinLogging.logger {}
  *
  * @see LinearSearch for a SearchStrategy that stops once the desired resource (demand) or load (capacity) is found.
  *
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
  */
-class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
+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.benchmarkExecutor.runExperiment(load, res)
+            val result = this.experimentRunner.runExperiment(load, res)
             if (result && minimalSuitableResources == null) {
                 minimalSuitableResources = res
             }
@@ -32,7 +32,7 @@ class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmar
         var maxSuitableLoad: Int? = null
         for (load in loads) {
             logger.info { "Running experiment with resources '$resource' and load '$load'" }
-            if (this.benchmarkExecutor.runExperiment(load, resource)) maxSuitableLoad = load
+            if (this.experimentRunner.runExperiment(load, resource)) maxSuitableLoad = load
         }
         return maxSuitableLoad
     }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategy.kt
similarity index 83%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategy.kt
index 447d810942be74f0cdbee865e3f0bb5d58e61603..8d257bb329729cab033e10195e7a9df3260aeeb3 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategy.kt
@@ -1,8 +1,9 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.searchstrategy
 
 import mu.KotlinLogging
-import theodolite.execution.BenchmarkExecutor
-import theodolite.util.Results
+import rocks.theodolite.core.strategies.guessstrategy.GuessStrategy
+import rocks.theodolite.core.ExperimentRunner
+import rocks.theodolite.core.Results
 
 private val logger = KotlinLogging.logger {}
 
@@ -10,15 +11,15 @@ 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 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(
-        benchmarkExecutor: BenchmarkExecutor,
+        experimentRunner: ExperimentRunner,
         private val guessStrategy: GuessStrategy,
         private var results: Results
-) : SearchStrategy(benchmarkExecutor) {
+) : SearchStrategy(experimentRunner) {
 
     override fun findSuitableResource(load: Int, resources: List<Int>): Int? {
 
@@ -39,7 +40,7 @@ class InitialGuessSearchStrategy(
 
             // If the first experiment passes, starting downward linear search
             // otherwise starting upward linear search
-            if (this.benchmarkExecutor.runExperiment(load, lastLowestResource)) {
+            if (this.experimentRunner.runExperiment(load, lastLowestResource)) {
 
                 resourcesToCheck = resources.subList(0, startIndex).reversed()
                 if (resourcesToCheck.isEmpty()) return lastLowestResource
@@ -48,7 +49,7 @@ class InitialGuessSearchStrategy(
                 for (res in resourcesToCheck) {
 
                     logger.info { "Running experiment with load '$load' and resources '$res'" }
-                    if (this.benchmarkExecutor.runExperiment(load, res)) {
+                    if (this.experimentRunner.runExperiment(load, res)) {
                         currentMin = res
                     }
                 }
@@ -64,7 +65,7 @@ class InitialGuessSearchStrategy(
                 for (res in resourcesToCheck) {
 
                     logger.info { "Running experiment with load '$load' and resources '$res'" }
-                    if (this.benchmarkExecutor.runExperiment(load, res)) return res
+                    if (this.experimentRunner.runExperiment(load, res)) return res
                 }
             }
         }
@@ -93,7 +94,7 @@ class InitialGuessSearchStrategy(
 
             // If the first experiment passes, starting upwards linear search
             // otherwise starting downward linear search
-            if (!this.benchmarkExecutor.runExperiment(lastMaxLoad, resource)) {
+            if (!this.experimentRunner.runExperiment(lastMaxLoad, resource)) {
                 // downward search
 
                 loadsToCheck = loads.subList(0, startIndex).reversed()
@@ -101,7 +102,7 @@ class InitialGuessSearchStrategy(
                     for (load in loadsToCheck) {
 
                         logger.info { "Running experiment with resource '$resource' and load '$load'" }
-                        if (this.benchmarkExecutor.runExperiment(load, resource)) {
+                        if (this.experimentRunner.runExperiment(load, resource)) {
                             return load
                         }
                     }
@@ -117,7 +118,7 @@ class InitialGuessSearchStrategy(
                 var currentMax: Int = lastMaxLoad
                 for (load in loadsToCheck) {
                     logger.info { "Running experiment with resource '$resource' and load '$load'" }
-                    if (this.benchmarkExecutor.runExperiment(load, resource)) {
+                    if (this.experimentRunner.runExperiment(load, resource)) {
                         currentMax = load
                     }
                 }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/LinearSearch.kt
similarity index 65%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/LinearSearch.kt
index 1991431a970e44bf70eccf834a2ecb0221502a71..c3276f05e141d15652012952991a47a1fde30ad4 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/LinearSearch.kt
@@ -1,7 +1,7 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.searchstrategy
 
 import mu.KotlinLogging
-import theodolite.execution.BenchmarkExecutor
+import rocks.theodolite.core.ExperimentRunner
 
 private val logger = KotlinLogging.logger {}
 
@@ -9,14 +9,14 @@ private val logger = KotlinLogging.logger {}
  *  Linear-search-like implementation for determining the smallest/biggest suitable number of resources/loads,
  *  depending on the metric.
  *
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
+ * @param experimentRunner Benchmark executor which runs the individual benchmarks.
  */
-class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
+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.benchmarkExecutor.runExperiment(load, res)) return res
+            if (this.experimentRunner.runExperiment(load, res)) return res
         }
         return null
     }
@@ -25,7 +25,7 @@ class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm
         var maxSuitableLoad: Int? = null
         for (load in loads) {
             logger.info { "Running experiment with resources '$resource' and load '$load'" }
-            if (this.benchmarkExecutor.runExperiment(load, resource)) {
+            if (this.experimentRunner.runExperiment(load, resource)) {
                 maxSuitableLoad = load
             } else break
         }
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearch.kt
similarity index 75%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearch.kt
index 0a136d6ff43e6f62fc5ebe34c392816da3592bf1..703a7de8b9e084b2bb55bc9270b9d07ea6adfe83 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearch.kt
@@ -1,23 +1,23 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.searchstrategy
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.execution.BenchmarkExecutor
-import theodolite.strategies.restriction.RestrictionStrategy
+import rocks.theodolite.core.strategies.restrictionstrategy.RestrictionStrategy
+import rocks.theodolite.core.ExperimentRunner
 
 /**
  *  Strategy that combines a SearchStrategy and a set of RestrictionStrategy.
  *
- * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
+ * @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(
-    benchmarkExecutor: BenchmarkExecutor,
-    private val searchStrategy: SearchStrategy,
-    private val restrictionStrategies: Set<RestrictionStrategy>
-) : SearchStrategy(benchmarkExecutor) {
+        experimentRunner: ExperimentRunner,
+        private val searchStrategy: SearchStrategy,
+        private val restrictionStrategies: Set<RestrictionStrategy>
+) : SearchStrategy(experimentRunner) {
 
     /**
      * Restricting the possible resources and calling findSuitableResource of the given [SearchStrategy].
diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/SearchStrategy.kt
similarity index 83%
rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/SearchStrategy.kt
index 962504c7d85fa5e28d73fe0cb9d844ed2be66a99..d08581ff70c509f54a9b8e5f972bb3661cb0b8f8 100644
--- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/core/strategies/searchstrategy/SearchStrategy.kt
@@ -1,20 +1,19 @@
-package theodolite.strategies.searchstrategy
+package rocks.theodolite.core.strategies.searchstrategy
 
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.execution.BenchmarkExecutor
-import theodolite.strategies.Metric
-import theodolite.util.Results
+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 benchmarkExecutor Benchmark executor which runs the individual benchmarks.
+ * @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 benchmarkExecutor: BenchmarkExecutor) {
+abstract class SearchStrategy(val experimentRunner: ExperimentRunner) {
 
 
     /**
@@ -29,13 +28,13 @@ abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor) {
         when(metric) {
             Metric.DEMAND ->
                 for (load in loads) {
-                    if (benchmarkExecutor.run.get()) {
+                    if (experimentRunner.run.get()) {
                         this.findSuitableResource(load, resources)
                     }
                 }
             Metric.CAPACITY ->
                 for (resource in resources) {
-                    if (benchmarkExecutor.run.get()) {
+                    if (experimentRunner.run.get()) {
                         this.findSuitableLoad(resource, loads)
                     }
                 }
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 66%
rename from theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
index 790e796e0792acb2542a69db7c1f626aa7c0ee67..e1ce46ea24fc97bb7b0421b8e3507c8e989d654a 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExperimentRunnerImpl.kt
@@ -1,44 +1,36 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes
 
 import io.quarkus.runtime.annotations.RegisterForReflection
 import mu.KotlinLogging
-import theodolite.benchmark.Benchmark
-import theodolite.benchmark.Slo
-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<Slo>,
-    repetitions: Int,
-    executionId: Int,
-    loadGenerationDelay: Long,
-    afterTeardownDelay: Long,
-    executionName: String,
-    loadPatcherDefinitions: List<PatcherDefinition>,
-    resourcePatcherDefinitions: List<PatcherDefinition>
-) : BenchmarkExecutor(
-    benchmark,
-    results,
-    executionDuration,
-    configurationOverrides,
-    slos,
-    repetitions,
-    executionId,
-    loadGenerationDelay,
-    afterTeardownDelay,
-    executionName,
-    loadPatcherDefinitions,
-    resourcePatcherDefinitions
+    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
@@ -79,14 +71,15 @@ class BenchmarkExecutorImpl(
     }
 
     private fun runSingleExperiment(load: Int, resource: Int): Pair<Instant, Instant> {
-        val benchmarkDeployment = benchmark.buildDeployment(
+        val benchmarkDeployment = benchmarkDeploymentBuilder.buildDeployment(
             load,
             this.loadPatcherDefinitions,
             resource,
             this.resourcePatcherDefinitions,
             this.configurationOverrides,
             this.loadGenerationDelay,
-            this.afterTeardownDelay
+            this.afterTeardownDelay,
+            this.waitForResourcesEnabled
         )
         val from: Instant
 
@@ -136,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 78%
rename from theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/KubernetesBenchmarkDeployment.kt
index 1d7b22233c084625cf16ca7194c76c14601bbaad..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 {}
@@ -42,6 +43,8 @@ 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.
@@ -71,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 80%
rename from theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ResourceSets.kt
index 2ee8d8cf5c0e8590728bc253fd452fe8aa1d9d96..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,7 +7,13 @@ 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
@@ -20,8 +26,8 @@ class ResourceSets : KubernetesResource {
     @JsonInclude(JsonInclude.Include.NON_NULL)
     var fileSystem: FileSystemResourceSet? = null
 
-    fun loadResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, HasMetadata>> {
 
+    fun loadResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, HasMetadata>> {
         return if (this.configMap != null) {
             configMap?.getResourceSet(client = client)!!
         } else if (this.fileSystem != null) {
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/RolloutManager.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/RolloutManager.kt
similarity index 95%
rename from theodolite/src/main/kotlin/theodolite/benchmark/RolloutManager.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/RolloutManager.kt
index f282fb27971218754a0e35801342efc83837b64b..f760bb407ec2a6c4ab2ee08d3521ad72d12dd25d 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/RolloutManager.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/RolloutManager.kt
@@ -1,18 +1,15 @@
 package theodolite.benchmark
 
 import io.fabric8.kubernetes.api.model.HasMetadata
-import io.fabric8.kubernetes.api.model.Pod
 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 theodolite.k8s.K8sManager
+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>) {
diff --git a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt
similarity index 67%
rename from theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt
index cdfe68e7a93d64f2385bded31f94f77ab7b3be0e..e970c84d345031b79f8afeedf56591e071bb154f 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt
@@ -1,8 +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 rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
 
 private val logger = KotlinLogging.logger {}
 
@@ -12,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
@@ -20,17 +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(
+                    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/theodolite/execution/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteExecutor.kt
similarity index 59%
rename from theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteExecutor.kt
index 82b406264fe7a07da1759936f4f2667150a7dee1..69615522ba9bbd5ef0944528eacbf1dce318caf9 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/TheodoliteExecutor.kt
@@ -1,12 +1,18 @@
-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.patcher.PatcherDefinitionFactory
-import theodolite.strategies.Metric
-import theodolite.strategies.StrategyFactory
-import theodolite.util.*
+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
 
@@ -17,25 +23,26 @@ 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 kubernetesBenchmark Configuration of a benchmark
+ * @property benchmark Configuration of a benchmark
  * @constructor Create empty Theodolite executor
  */
 class TheodoliteExecutor(
-    private val benchmarkExecution: BenchmarkExecution,
-    private val kubernetesBenchmark: KubernetesBenchmark
+        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 executor: BenchmarkExecutor
+    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.
+     * 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))
@@ -46,20 +53,20 @@ class TheodoliteExecutor(
         val resourcePatcherDefinition =
             PatcherDefinitionFactory().createPatcherDefinition(
                 benchmarkExecution.resources.resourceType,
-                this.kubernetesBenchmark.resourceTypes
+                this.benchmark.resourceTypes
             )
 
         val loadDimensionPatcherDefinition =
             PatcherDefinitionFactory().createPatcherDefinition(
                 benchmarkExecution.loads.loadType,
-                this.kubernetesBenchmark.loadTypes
+                this.benchmark.loadTypes
             )
 
-        val slos = SloFactory().createSlos(this.benchmarkExecution, this.kubernetesBenchmark)
+        val slos = SloFactory().createSlos(this.benchmarkExecution, this.benchmark)
 
-        executor =
-            BenchmarkExecutorImpl(
-                benchmark = kubernetesBenchmark,
+        experimentRunner =
+            ExperimentRunnerImpl(
+                benchmarkDeploymentBuilder = KubernetesBenchmarkDeploymentBuilder(this.benchmark,this.client),
                 results = results,
                 executionDuration = executionDuration,
                 configurationOverrides = benchmarkExecution.configOverrides,
@@ -70,83 +77,76 @@ class TheodoliteExecutor(
                 afterTeardownDelay = benchmarkExecution.execution.afterTeardownDelay,
                 executionName = benchmarkExecution.name,
                 loadPatcherDefinitions = loadDimensionPatcherDefinition,
-                resourcePatcherDefinitions = resourcePatcherDefinition
+                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}."
+                "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}."
+                "Load values are not sorted correctly, Theodolite sorts them in ascending order." +
+                        "New order is: ${benchmarkExecution.resources.resourceValues}"
             }
         }
 
         return Config(
             loads = benchmarkExecution.loads.loadValues,
-            loadPatcherDefinitions = loadDimensionPatcherDefinition,
             resources = benchmarkExecution.resources.resourceValues,
-            resourcePatcherDefinitions = resourcePatcherDefinition,
-            searchStrategy = strategyFactory.createSearchStrategy(executor, benchmarkExecution.execution.strategy, results),
+            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)
         )
     }
 
-    fun getExecution(): BenchmarkExecution {
-        return this.benchmarkExecution
-    }
-
     /**
-     * Run all experiments which are specified in the corresponding
-     * execution and benchmark objects.
+     * 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 run() {
-        kubernetesBenchmark.setupInfrastructure()
+    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(
-            kubernetesBenchmark,
+                benchmark,
             "${resultsFolder}exp${this.benchmarkExecution.executionId}-benchmark-configuration"
         )
 
         val config = buildConfig()
 
-        //execute benchmarks for each load for the demand metric, or for each resource amount for capacity metric
-        try {
-            config.searchStrategy.applySearchStrategyByMetric(config.loads, config.resources, config.metric)
+        val executionRunner = ExecutionRunner(config.searchStrategy, config.resources, config.loads,config.metric,
+                                              this.benchmarkExecution.executionId)
 
-        } finally {
-            ioHandler.writeToJSONFile(
-                config.searchStrategy.benchmarkExecutor.results,
-                "${resultsFolder}exp${this.benchmarkExecution.executionId}-result"
-            )
-            // Create expXYZ_demand.csv file or expXYZ_capacity.csv depending on metric
-            when(config.metric) {
-                Metric.DEMAND ->
-                    ioHandler.writeToCSVFile(
-                        "${resultsFolder}exp${this.benchmarkExecution.executionId}_demand",
-                        calculateMetric(config.loads, config.searchStrategy.benchmarkExecutor.results),
-                        listOf("load","resources")
-                    )
-                Metric.CAPACITY ->
-                    ioHandler.writeToCSVFile(
-                        "${resultsFolder}exp${this.benchmarkExecution.executionId}_capacity",
-                        calculateMetric(config.resources, config.searchStrategy.benchmarkExecutor.results),
-                        listOf("resource", "loads")
-                    )
-            }
-        }
-        kubernetesBenchmark.teardownInfrastructure()
+        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 {
@@ -163,4 +163,7 @@ class TheodoliteExecutor(
         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 97%
rename from theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/BenchmarkExecution.kt
index 13c98d7013fc3c6f24066419604d42c576db2c94..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
 
 /**
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/theodolite/patcher/AbstractPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcher.kt
similarity index 95%
rename from theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcher.kt
index fbbb7fa1d2ea9fd67732ea5b84f29012c5708136..a20a26b351e730de60497ac014b3aba855ac01f5 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.client.utils.Serialization
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifier.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifier.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8945d9b647c0e79e854d509eafcfae1aa932367c
--- /dev/null
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ConfigOverrideModifier.kt
@@ -0,0 +1,35 @@
+package rocks.theodolite.kubernetes.patcher
+
+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.
+ *
+ * @property execution execution for which the config overrides should be updated
+ * @property resources list of all resources that should be updated.
+ */
+class ConfigOverrideModifier(val execution: BenchmarkExecution, val resources: List<String>) {
+
+    /**
+     * Adds a [LabelPatcher] to the configOverrides.
+     *
+     * @param labelValue value argument for the label patcher
+     * @param labelName  label name argument for the label patcher
+     */
+    fun setAdditionalLabels(
+        labelValue: String,
+        labelName: String
+    ) {
+        val additionalConfigOverrides = resources.map {
+            ConfigurationOverride().apply {
+                this.patcher = PatcherDefinition()
+                this.patcher.type = "LabelPatcher"
+                this.patcher.properties = mapOf("variableName" to labelName)
+                this.patcher.resource = it
+                this.value = labelValue
+            }
+        }
+        execution.configOverrides.addAll(additionalConfigOverrides)
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
similarity index 84%
rename from theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
index db019282fd14c8a7aaa6eba7cd3969ba42da8023..2979d06268d4b363ba2c4de35242bd45fa52f423 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 
@@ -24,15 +24,14 @@ class DataVolumeLoadGeneratorReplicaPatcher(
         return resources.flatMap { patchSingeResource(it, value)}
     }
 
-    fun patchSingeResource(k8sResource: HasMetadata, value: String): List<HasMetadata> {
-        var resource = k8sResource
+    private fun patchSingeResource(k8sResource: HasMetadata, value: String): List<HasMetadata> {
         // calculate number of load generator instances and load per instance
         val load = Integer.parseInt(value)
         val loadGenInstances = (load + maxVolume - 1) / maxVolume
         val loadPerInstance = load / loadGenInstances
 
         // Patch instance values and load value of generators
-        val resourceList = ReplicaPatcher().patch(listOf(resource), loadGenInstances.toString())
+        val resourceList = ReplicaPatcher().patch(listOf(k8sResource), 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 97%
rename from theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcher.kt
index ee95871211145e740a64e711996b85af98ee2151..33d6c8d9b6f5f82a49e7cd414e4b273708c0e68a 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.Container
 import io.fabric8.kubernetes.api.model.EnvVar
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcher.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcher.kt
index 2918c825931eb0bb4ca8ad176224e79815272b67..7f54416501bc742499a958566a179b7fad320318 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
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/theodolite/patcher/LabelPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcher.kt
similarity index 97%
rename from theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcher.kt
index 9a98f9689e28d77d3e7eea5974eff29ab4bbe0f8..8bb5be97e780479884e6cb8e551c03340b04f8e6 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.ConfigMap
 import io.fabric8.kubernetes.api.model.GenericKubernetesResource
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcher.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcher.kt
index 693d751f275d3666b5e360766eb449b8f6b639c3..725c9cf8a6a87c23119812c0a5d5ad3280a42e3c 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NamePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcher.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/patcher/NamePatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcher.kt
index 74fae390145a10d487b9c39628e67965999593e4..a6416a7e77841fa869de7ce2c248882fb486572c 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/NamePatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.ConfigMap
 import io.fabric8.kubernetes.api.model.GenericKubernetesResource
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcher.kt
similarity index 93%
rename from theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcher.kt
index b608d3b10440a19998f81776642562d337a4642a..c3b5ba1a07afa41dd604f2335baf6b58e362f293 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
similarity index 94%
rename from theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
index deee1b6efebe98f52e2d19c5cbe2e4c68174ed8f..e3b0105768ec339758fd89233a09da233145d641 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
similarity index 93%
rename from theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
index 8463d672687aa9594e2ef168d53e6d7551bc0d4a..6bb2750bb1ca923aa05022884ef7054772a987c6 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/PatchHandler.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatchHandler.kt
similarity index 63%
rename from theodolite/src/main/kotlin/theodolite/patcher/PatchHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatchHandler.kt
index 73f2f2435b42c59a1b0a294c67bbd0c726ffc209..92b1e52ba7492181b5f3b06080efe01aae6cf66b 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/PatchHandler.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatchHandler.kt
@@ -1,21 +1,15 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
-import theodolite.util.InvalidPatcherConfigurationException
-import theodolite.util.PatcherDefinition
-
 class PatchHandler {
-
     companion object {
-
-        private fun getResourcesToPatch(resources: MutableMap<String, List<HasMetadata>>, patcherDefinition: PatcherDefinition): List<HasMetadata> {
+        private fun getResourcesToPatch(resources: Map<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>>,
+            resources: Map<String, List<HasMetadata>>,
             patcherDefinition: PatcherDefinition,
             value: String,
         ): List<HasMetadata> {
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/Patcher.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/Patcher.kt
index 72fe6a1f02e7f1767176fd965740c80f1437f6c1..310b370b97d065fc1ea0c3f7edd81577816ff69c 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/Patcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.quarkus.runtime.annotations.RegisterForReflection
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/theodolite/patcher/PatcherFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherFactory.kt
similarity index 95%
rename from theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherFactory.kt
index 85848a48450637863363a366a1a1767c2c5af565..a4dcf68d2b4ec12facb26755e9f63e298725e195 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/PatcherFactory.kt
@@ -1,7 +1,4 @@
-package theodolite.patcher
-
-import theodolite.util.InvalidPatcherConfigurationException
-import theodolite.util.PatcherDefinition
+package rocks.theodolite.kubernetes.patcher
 
 /**
  * The Patcher factory creates [Patcher]s
@@ -76,7 +73,7 @@ class PatcherFactory {
                     "ServiceSelectorPatcher" -> ServiceSelectorPatcher(
                         variableName = patcherDefinition.properties["label"]!!
                     )
-                    "theodolite.patcher.VolumesConfigMapPatcher" -> VolumesConfigMapPatcher(
+                    "rocks.theodolite.kubernetes.patcher.VolumesConfigMapPatcher" -> VolumesConfigMapPatcher(
                         volumeName = patcherDefinition.properties["volumeName"]!!
                     )
                     else -> throw InvalidPatcherConfigurationException("Patcher type ${patcherDefinition.type} not found.")
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcher.kt
similarity index 91%
rename from theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcher.kt
index 837bebf9da968d9afd7da6846575c9f1f457a3e3..8637b1299e878c4424e7fcaf4eac3bc901428541 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcher.kt
similarity index 60%
rename from theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcher.kt
index 8b75d43bfc5b589c8c65a1016058a5b850ac9063..c8064c605fbd8c65d97d9fbd8ee24fd49ad893da 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcher.kt
@@ -1,9 +1,8 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 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.
@@ -30,7 +29,7 @@ class ResourceLimitPatcher(
                 }
             }
             else -> {
-                throw InvalidPatcherConfigurationException("ResourceLimitPatcher is not applicable for $resource")
+                throw InvalidPatcherConfigurationException("ResourceLimitPatcher is not applicable for $resource.")
             }
         }
         return resource
@@ -38,21 +37,21 @@ class ResourceLimitPatcher(
 
 
         private fun setLimits(container: Container, value: String) {
-        when {
-            container.resources == null -> {
-                val resource = ResourceRequirements()
-                resource.limits = mapOf(limitedResource to Quantity(value))
-                container.resources = resource
-            }
-            container.resources.limits.isEmpty() -> {
-                container.resources.limits = mapOf(limitedResource to Quantity(value))
-            }
-            else -> {
-                val values = mutableMapOf<String, Quantity>()
-                container.resources.limits.forEach { entry -> values[entry.key] = entry.value }
-                values[limitedResource] = Quantity(value)
-                container.resources.limits = values
-            }
+            when {
+                container.resources == null -> {
+                    val resource = ResourceRequirements()
+                    resource.limits = mapOf(limitedResource to Quantity(value))
+                    container.resources = resource
+                }
+                container.resources.limits.isEmpty() -> {
+                    container.resources.limits = mapOf(limitedResource to Quantity(value))
+                }
+                else -> {
+                    val values = mutableMapOf<String, Quantity>()
+                    container.resources.limits.forEach { entry -> values[entry.key] = entry.value }
+                    values[limitedResource] = Quantity(value)
+                    container.resources.limits = values
+                }
         }
     }
 }
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcher.kt
similarity index 93%
rename from theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcher.kt
index f63386e5565d053bf276ccada628c3a1676c7c68..7d9cd8b748d9e41d5506508259452032b1228015 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcher.kt
@@ -1,9 +1,8 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 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.
@@ -30,7 +29,7 @@ class ResourceRequestPatcher(
                 }
             }
             else -> {
-                throw InvalidPatcherConfigurationException("ResourceRequestPatcher is not applicable for $resource")
+                throw InvalidPatcherConfigurationException("ResourceRequestPatcher is not applicable for $resource.")
             }
         }
         return resource
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcher.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcher.kt
index fc6a2864b1cc9495336a2e4756da97b2bd498dc3..c5ac16cdfe25f6b2fd2e4d0a2fb27000f885ffe7 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ServiceSelectorPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ServiceSelectorPatcher.kt
similarity index 92%
rename from theodolite/src/main/kotlin/theodolite/patcher/ServiceSelectorPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ServiceSelectorPatcher.kt
index 3d94e283902b9879225ca4b8730730697ebe02a7..b38ae4108748f85e7ac60f3ee3aa8c5d28281432 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/ServiceSelectorPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/ServiceSelectorPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.Service
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcher.kt
similarity index 96%
rename from theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcher.kt
index 2707d98e046ce9aef01285d9febc7ab3b6d4c45d..e1c1bc3a15b8a9035bcaaa513f040aff9982e7ab 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
@@ -13,7 +13,6 @@ class TemplateLabelPatcher(
     val variableName: String) :
     AbstractPatcher() {
 
-
     override fun patchSingleResource(resource: HasMetadata, value: String): HasMetadata {
         when (resource) {
             is Deployment -> {
diff --git a/theodolite/src/main/kotlin/theodolite/patcher/VolumesConfigMapPatcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcher.kt
similarity index 97%
rename from theodolite/src/main/kotlin/theodolite/patcher/VolumesConfigMapPatcher.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcher.kt
index 17068c7e7f206b1bbed4530c2008b60d3aaf593e..54a459a19b35e74839de647761e8ac22f839ca2d 100644
--- a/theodolite/src/main/kotlin/theodolite/patcher/VolumesConfigMapPatcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcher.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.apps.Deployment
diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
similarity index 89%
rename from theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
index 7948058f0716a29712c360b5f90362dcedce2d7f..96c5a43b85c0db5600d813f9e799903927a53ec3 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
@@ -1,9 +1,8 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
-import theodolite.benchmark.Slo
-import theodolite.strategies.Metric
-import theodolite.util.EvaluationFailedException
-import theodolite.util.IOHandler
+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
@@ -49,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")
                 )
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 91%
rename from theodolite/src/main/kotlin/theodolite/evaluation/ExternalSloChecker.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt
index 7587e8326df98f3c45c016bfd3b2d7db8077e6d1..3a76fa7c0d9511b8989d3e444cbefe5c8a50b285 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
 
 /**
@@ -11,8 +11,8 @@ import java.net.ConnectException
  * @param metadata metadata passed to the external SLO checker.
  */
 class ExternalSloChecker(
-    private val externalSlopeURL: String,
-    private val metadata: Map<String, Any>
+    val externalSlopeURL: String,
+    val metadata: Map<String, Any>
 ) : SloChecker {
 
     private val RETRIES = 2
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 91%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
index 7ab6a0255f6c078f0f365289baa1eb0300a3244a..a789050a106f1b95be7c1d55043cc9d46a15ffbf 100644
--- a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt
@@ -1,6 +1,6 @@
-package theodolite.evaluation
+package rocks.theodolite.kubernetes.slo
 
-import theodolite.strategies.Metric
+import rocks.theodolite.core.strategies.Metric
 
 
 /**
@@ -41,7 +41,7 @@ class SloCheckerFactory {
      */
     fun create(
         sloType: String,
-        properties: MutableMap<String, String>,
+        properties: Map<String, String>,
         load: Int,
         resource: Int,
         metric: Metric
@@ -58,7 +58,7 @@ class SloCheckerFactory {
                     "repetitionAggregation" to (properties["repetitionAggregation"]
                         ?: throw IllegalArgumentException("repetitionAggregation expected")),
                     "operator" to (properties["operator"] ?: throw IllegalArgumentException("operator expected")),
-                    "threshold" to (properties["threshold"]?.toInt()
+                    "threshold" to (properties["threshold"]?.toDouble()
                         ?: throw IllegalArgumentException("threshold expected"))
                 )
             )
@@ -67,7 +67,7 @@ class SloCheckerFactory {
                     ?: throw IllegalArgumentException("externalSloUrl expected"),
                 metadata = mapOf(
                     "warmup" to (properties["warmup"]?.toInt() ?: throw IllegalArgumentException("warmup expected")),
-                    "threshold" to (properties["threshold"]?.toInt()
+                    "threshold" to (properties["threshold"]?.toDouble()
                         ?: throw IllegalArgumentException("threshold expected"))
                 )
             )
@@ -78,8 +78,8 @@ class SloCheckerFactory {
                 if (thresholdRatio < 0.0) {
                     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 * thresholdRatio).toInt()
+
+                val threshold = (load * thresholdRatio)
 
                 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 89%
rename from theodolite/src/main/kotlin/theodolite/evaluation/SloConfigHandler.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloConfigHandler.kt
index ee892109dc1fc03a9c270151944c6d90fbacf45e..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.Slo
-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"
diff --git a/theodolite/src/main/kotlin/theodolite/execution/SloFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloFactory.kt
similarity index 74%
rename from theodolite/src/main/kotlin/theodolite/execution/SloFactory.kt
rename to theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloFactory.kt
index b990828fa1db09532767b9f9255aa53e9c9e894a..047f8a657de8aba6f032d36e8b84d7046d5e0209 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/SloFactory.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloFactory.kt
@@ -1,8 +1,8 @@
-package theodolite.execution
+package rocks.theodolite.kubernetes.slo
 
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.benchmark.Slo
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
 
 class SloFactory {
 
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 f2b587cba90151af199da4b76a9cb8ad407f80ef..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package theodolite.benchmark
-
-import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.util.ConfigurationOverride
-import theodolite.util.PatcherDefinition
-
-/**
- * A Benchmark contains:
- * - The Resource that can be scaled for the benchmark.
- * - The Load 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: Int,
-            loadPatcherDefinitions: List<PatcherDefinition>,
-            resource: Int,
-            resourcePatcherDefinitions: List<PatcherDefinition>,
-            configurationOverrides: List<ConfigurationOverride?>,
-            loadGenerationDelay: Long,
-            afterTeardownDelay: Long
-    ): BenchmarkDeployment
-}
diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
deleted file mode 100644
index d40d91961266098702171c7c3d040db87b2c6f9f..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
+++ /dev/null
@@ -1,166 +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.PatchHandler
-import theodolite.patcher.PatcherFactory
-import theodolite.util.*
-import kotlin.properties.Delegates
-
-
-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,
- * - [infrastructure] resources that have to be deployed for the benchmark infrastructure
- * - [sut] list of the resources that have to be deployed for the benchmark,
- * - [loadGenerator] 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,
- *
- *  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
-    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
-    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) }
-        RolloutManager(waitForResourcesEnabled, this.client)
-            .rollout(loadResources(this.infrastructure.resources).map { it.second })
-    }
-
-    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 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
-    ): BenchmarkDeployment {
-        logger.info { "Using $namespace as namespace." }
-
-
-        val appResources = loadResources(this.sut.resources).toResourceMap()
-        val loadGenResources = loadResources(this.loadGenerator.resources).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())
-        }
-
-        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 = this.kafkaConfig
-
-        return KubernetesBenchmarkDeployment(
-            sutBeforeActions = sut.beforeActions,
-            sutAfterActions = sut.afterActions,
-            loadGenBeforeActions = loadGenerator.beforeActions,
-            loadGenAfterActions = 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
-
-        )
-    }
-
-    /**
-     * 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
-    }
-}
-
-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/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/benchmark/Slo.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Slo.kt
deleted file mode 100644
index c9aac4a1b68692669f0db577003856b964ade4ec..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/benchmark/Slo.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package theodolite.benchmark
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.quarkus.runtime.annotations.RegisterForReflection
-import kotlin.properties.Delegates
-
-/**
- * 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>
-}
\ 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 9ae267f42ca3f8420dbd507b0b92e92bf49a31f5..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package theodolite.execution
-
-import mu.KotlinLogging
-import theodolite.benchmark.Benchmark
-import theodolite.benchmark.Slo
-import theodolite.util.ConfigurationOverride
-import theodolite.util.PatcherDefinition
-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<Slo>,
-    val repetitions: Int,
-    val executionId: Int,
-    val loadGenerationDelay: Long,
-    val afterTeardownDelay: Long,
-    val executionName: String,
-    val loadPatcherDefinitions: List<PatcherDefinition>,
-    val resourcePatcherDefinitions: List<PatcherDefinition>
-) {
-
-    var run: AtomicBoolean = AtomicBoolean(true)
-
-    /**
-     * Run a 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
-
-    /**
-     * 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/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/ConfigOverrideModifier.kt b/theodolite/src/main/kotlin/theodolite/patcher/ConfigOverrideModifier.kt
deleted file mode 100644
index 8f77b1b95f3bf5cc9422cda55cb261048cebaeb6..0000000000000000000000000000000000000000
--- a/theodolite/src/main/kotlin/theodolite/patcher/ConfigOverrideModifier.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package theodolite.patcher
-
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.util.ConfigurationOverride
-import theodolite.util.PatcherDefinition
-
-/**
- * The ConfigOverrideModifier makes it possible to update the configuration overrides of an execution.
- *
- * @property execution execution for which the config overrides should be updated
- * @property resources list of all resources that should be updated.
- */
-class ConfigOverrideModifier(val execution: BenchmarkExecution, val resources: List<String>) {
-
-    /**
-     * Adds a [LabelPatcher] to the configOverrides.
-     *
-     * @param labelValue value argument for the label patcher
-     * @param labelName  label name argument for the label patcher
-     */
-    fun setAdditionalLabels(
-        labelValue: String,
-        labelName: String
-    ) {
-        val additionalConfigOverrides = mutableListOf<ConfigurationOverride>()
-        resources.forEach {
-            run {
-                val configurationOverride = ConfigurationOverride()
-                configurationOverride.patcher = PatcherDefinition()
-                configurationOverride.patcher.type = "LabelPatcher"
-                configurationOverride.patcher.properties = mutableMapOf("variableName" to labelName)
-                configurationOverride.patcher.resource = it
-                configurationOverride.value = labelValue
-                additionalConfigOverrides.add(configurationOverride)
-            }
-        }
-        execution.configOverrides.addAll(additionalConfigOverrides)
-    }
-}
\ No newline at end of file
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 99%
rename from theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/IOHandlerTest.kt
index cec18832ad99a01dc7977b64a19111f57f49d7f4..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
diff --git a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/ResultsTest.kt
similarity index 97%
rename from theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/ResultsTest.kt
index d453587a9aeeee1ad48cf750a614009ef6be9aff..2dbeb44b90f780975af884028335a7e398c7cfdc 100644
--- a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/ResultsTest.kt
@@ -1,10 +1,10 @@
-package theodolite.util
+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 theodolite.strategies.Metric
+import rocks.theodolite.core.strategies.Metric
 
 @QuarkusTest
 internal class ResultsTest {
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 92%
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 e659d5f542910611af96d7eb6a68140ebd43065b..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,11 +1,12 @@
-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.strategies.Metric
-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 {
 
diff --git a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategyTest.kt
similarity index 82%
rename from theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategyTest.kt
index dbe55ff36f591a45df3fd9898419befe5a5fdeb7..820dc7564aac2497a2884ca004f15110bc5465f7 100644
--- a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/InitialGuessSearchStrategyTest.kt
@@ -1,14 +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.strategies.searchstrategy.InitialGuessSearchStrategy
-import theodolite.strategies.Metric
-import theodolite.util.Results
+import rocks.theodolite.core.strategies.Metric
 import mu.KotlinLogging
-import theodolite.benchmark.Slo
-import theodolite.strategies.searchstrategy.PrevInstanceOptGuess
+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 {}
 
@@ -29,10 +30,10 @@ class InitialGuessSearchStrategyTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..6).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val guessStrategy = PrevInstanceOptGuess()
         val sloChecker = Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
         val strategy = InitialGuessSearchStrategy(benchmarkExecutor,guessStrategy, results)
 
         val actual: ArrayList<Int?> = ArrayList()
@@ -67,10 +68,10 @@ class InitialGuessSearchStrategyTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..6).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val guessStrategy = PrevInstanceOptGuess()
         val sloChecker = Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
         val strategy = InitialGuessSearchStrategy(benchmarkExecutor,guessStrategy, results)
 
         val actual: ArrayList<Int?> = ArrayList()
@@ -105,10 +106,10 @@ class InitialGuessSearchStrategyTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..6).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val guessStrategy = PrevInstanceOptGuess()
         val sloChecker = Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
         val strategy = InitialGuessSearchStrategy(benchmarkExecutor, guessStrategy, results)
 
         val actual: ArrayList<Int?> = ArrayList()
diff --git a/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearchTest.kt
similarity index 81%
rename from theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearchTest.kt
index 23fa99c6d1775f291949a9068399f5bcf6e5179a..bae944801fcacf40431559a0e7ddeb78923d2173 100644
--- a/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/core/strategies/searchstrategy/RestrictionSearchTest.kt
@@ -1,16 +1,14 @@
-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.Slo
-import theodolite.strategies.Metric
-import theodolite.strategies.restriction.LowerBoundRestriction
-import theodolite.strategies.searchstrategy.BinarySearch
-import theodolite.strategies.searchstrategy.FullSearch
-import theodolite.strategies.searchstrategy.RestrictionSearch
-import theodolite.strategies.searchstrategy.LinearSearch
-import theodolite.util.Results
+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 {
@@ -30,9 +28,9 @@ class RestrictionSearchTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..6).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val sloChecker = Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
         val linearSearch = LinearSearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
@@ -63,9 +61,9 @@ class RestrictionSearchTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..6).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val sloChecker = Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 5)
         val fullSearch = FullSearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
@@ -96,10 +94,10 @@ class RestrictionSearchTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..6).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val sloChecker = Slo()
         val benchmarkExecutorImpl =
-            TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 0)
+            TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 0)
         val binarySearch = BinarySearch(benchmarkExecutorImpl)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy = RestrictionSearch(benchmarkExecutorImpl, binarySearch, setOf(lowerBoundRestriction))
@@ -129,9 +127,9 @@ class RestrictionSearchTest {
         val mockLoads: List<Int> = (0..6).toList()
         val mockResources: List<Int> = (0..7).toList()
         val results = Results(Metric.from("demand"))
-        val benchmark = TestBenchmark()
+        val benchmarkDeploymentBuilder = TestBenchmarkDeploymentBuilder()
         val sloChecker = Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 0)
+        val benchmarkExecutor = TestExperimentRunnerImpl(results, mockResults, benchmarkDeploymentBuilder, listOf(sloChecker), 0, 0, 0)
         val binarySearch = BinarySearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
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/theodolite/benchmark/ResourceSetsTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ResourceSetsTest.kt
similarity index 98%
rename from theodolite/src/test/kotlin/theodolite/benchmark/ResourceSetsTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ResourceSetsTest.kt
index b2ce9d73447961c56b121542a4c91822e3703e95..f0a6c120ca6c3397e8d41cd9f42b536b3e053caf 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/ResourceSetsTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ResourceSetsTest.kt
@@ -1,4 +1,4 @@
-package theodolite.benchmark
+package rocks.theodolite.kubernetes
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
@@ -16,7 +16,6 @@ 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 theodolite.util.DeploymentFailedException
 import java.nio.file.Files
 import java.nio.file.Path
 
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/theodolite/TestBenchmark.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeploymentBuilder.kt
similarity index 52%
rename from theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeploymentBuilder.kt
index 335b0f8c59ac7642c30a12e494890e8f2c52ccda..cc7c9d6ae9a5fe158f7ba9243f23442acde001ee 100644
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/TestBenchmarkDeploymentBuilder.kt
@@ -1,17 +1,10 @@
-package theodolite
+package rocks.theodolite.kubernetes
 
-import theodolite.benchmark.Benchmark
-import theodolite.benchmark.BenchmarkDeployment
-import theodolite.util.ConfigurationOverride
-import theodolite.util.PatcherDefinition
 
-class TestBenchmark : Benchmark {
+import rocks.theodolite.kubernetes.util.ConfigurationOverride
+import rocks.theodolite.kubernetes.patcher.PatcherDefinition
 
-    override fun setupInfrastructure() {
-    }
-
-    override fun teardownInfrastructure() {
-    }
+class TestBenchmarkDeploymentBuilder(): BenchmarkDeploymentBuilder {
 
     override fun buildDeployment(
             load: Int,
@@ -20,7 +13,8 @@ class TestBenchmark : Benchmark {
             resourcePatcherDefinitions: List<PatcherDefinition>,
             configurationOverrides: List<ConfigurationOverride?>,
             loadGenerationDelay: Long,
-            afterTeardownDelay: 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 79%
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 152191bc271552dfb50c022c678a023ce0eb65cd..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) {
 
@@ -27,9 +24,9 @@ class BenchmarkCRDummy(name: String) {
         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()
diff --git a/theodolite/src/test/kotlin/theodolite/model/crd/CRDExecutionTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/CRDExecutionTest.kt
similarity index 88%
rename from theodolite/src/test/kotlin/theodolite/model/crd/CRDExecutionTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/CRDExecutionTest.kt
index 1150141ecc6a7147c930375af5bc965b81647e5a..a7de76acfe7aac9b92628e87b9911599a13ab438 100644
--- a/theodolite/src/test/kotlin/theodolite/model/crd/CRDExecutionTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/model/crd/CRDExecutionTest.kt
@@ -1,4 +1,4 @@
-package theodolite.model.crd
+package rocks.theodolite.kubernetes.model.crd
 
 import io.fabric8.kubernetes.api.model.KubernetesResourceList
 import io.fabric8.kubernetes.client.dsl.MixedOperation
@@ -11,15 +11,11 @@ import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.Assertions.*
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
-import org.mockito.internal.matchers.apachecommons.ReflectionEquals
-import org.apache.commons.lang3.builder.EqualsBuilder
-import org.hamcrest.MatcherAssert.assertThat
-import org.hamcrest.Matchers.instanceOf
-import org.mockito.kotlin.isA
 import org.mockito.kotlin.mock
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.execution.operator.*
-import theodolite.util.ConfigurationOverride
+import 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
 
 
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 88%
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 961c813f432d13fd2b373c74adaa00df4049a334..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) {
 
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/theodolite/patcher/AbstractPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcherTest.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/patcher/AbstractPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcherTest.kt
index 05bb9588a2de5656b9c0b39d16d2160f691bbe91..cb92423305fd3f724753225d95150d5198f1d306 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/AbstractPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/AbstractPatcherTest.kt
@@ -1,13 +1,10 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.*
-import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder
-import io.fabric8.kubernetes.api.model.apps.StatefulSet
 import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder
 import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.Test
-import theodolite.util.PatcherDefinition
 
 @QuarkusTest
 abstract class AbstractPatcherTest {
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/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
similarity index 84%
rename from theodolite/src/test/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
index e55767ea79f1925a3825aca11eb74a8641c17a90..6c9be1b9a59f963c8996e520b55e16caf24cbf6c 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt
@@ -2,11 +2,11 @@ package theodolite.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 rocks.theodolite.kubernetes.patcher.AbstractPatcherTest
 
-import org.junit.jupiter.api.Assertions.*
+import rocks.theodolite.kubernetes.patcher.VolumesConfigMapPatcher
 
 @QuarkusTest
 internal class DataVolumeLoadGeneratorReplicaPatcherTest: AbstractPatcherTest() {
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/EnvVarPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcherTest.kt
similarity index 92%
rename from theodolite/src/test/kotlin/theodolite/patcher/EnvVarPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcherTest.kt
index cc46347acf5b005ed05170fe27a40de3ca69599d..83cd056ac1b56b13fb8f211a2d926f1272c9fb0e 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/EnvVarPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/EnvVarPatcherTest.kt
@@ -1,6 +1,5 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import io.fabric8.kubernetes.api.model.EnvVar
 import io.fabric8.kubernetes.api.model.EnvVarBuilder
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ImagePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcherTest.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/patcher/ImagePatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcherTest.kt
index 6592f65934716bfd74d562c5a3fb52ddb40c8b86..7b3f803a4e13039b7bb40aec6259f7d9a4fdbb57 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/ImagePatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ImagePatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/LabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/patcher/LabelPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
index 64583e4be67282543a44d09b36e657eede2f9eac..652dda47cef34a7a95e54c36cbe9af9c897b84a1 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/LabelPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/LabelPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/MatchLabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcherTest.kt
similarity index 95%
rename from theodolite/src/test/kotlin/theodolite/patcher/MatchLabelPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcherTest.kt
index 796f2ffeb6f4c22b9d00218b91f0fbe2ee9f6567..a5711a762ab65fc39edf731c21d085d0936a5a93 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/MatchLabelPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/MatchLabelPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NamePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
similarity index 88%
rename from theodolite/src/test/kotlin/theodolite/patcher/NamePatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
index 5ae75c5b0dca038b8e351683bfd0ee2a40d217eb..cb1308cb73dc127661b2c2741fdc3e0460fcfde4 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/NamePatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NamePatcherTest.kt
@@ -1,6 +1,5 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
-import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.quarkus.test.junit.QuarkusTest
 import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.BeforeEach
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NodeSelectorPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcherTest.kt
similarity index 93%
rename from theodolite/src/test/kotlin/theodolite/patcher/NodeSelectorPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcherTest.kt
index a042faf8484eb0ce7e1e21a6069be2beeff0b693..ca8f83518a5bcd96837de96b1879c0de2e9a5773 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/NodeSelectorPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NodeSelectorPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
@@ -7,7 +7,6 @@ import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 
 import org.junit.jupiter.api.Assertions.*
-import org.mockito.kotlin.reset
 
 @QuarkusTest
 internal class NodeSelectorPatcherTest: AbstractPatcherTest() {
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
index 6b2a639285b134c0efcaaf5b296f18779f4f8322..8940e288fae79f10e5dcd728121a2dbbf0aaa180 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
index 50d122e60104ad0239824e5b4471ade8b3ff7bfb..e3bb6ffff4938bcaeb4a0db6487bd4741da75850 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/PatcherDefinitionFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactoryTest.kt
similarity index 88%
rename from theodolite/src/test/kotlin/theodolite/patcher/PatcherDefinitionFactoryTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactoryTest.kt
index 4696e646726f9ed6ad3e4c5cda1631ded42930e4..010fa1e25fb89619c8954b1bafa52c5389d0a2f3 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/PatcherDefinitionFactoryTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/PatcherDefinitionFactoryTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.BeforeEach
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ReplicaPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcherTest.kt
similarity index 93%
rename from theodolite/src/test/kotlin/theodolite/patcher/ReplicaPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcherTest.kt
index 0e01dead66509e40237952e4d65ea3a377943c5b..852002a07cfb756086afbc6d0573fc548f945683 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/ReplicaPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ReplicaPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
similarity index 97%
rename from theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
index b794ec6ed983dba92526aff67ecb3cab915871eb..b0af74d1e207ee10fac548f27267356711943dd0 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceLimitPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
@@ -8,7 +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.util.PatcherDefinition
 
 /**
  * Resource patcher test
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
similarity index 97%
rename from theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/ResourceRequestPatcherTest.kt
index 300397a96abd34f17f1a4a3d2b3c76e2d9da13ea..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
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/SchedulerNamePatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcherTest.kt
similarity index 94%
rename from theodolite/src/test/kotlin/theodolite/patcher/SchedulerNamePatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcherTest.kt
index 8b6f3e9b1371bce3e17cbbc6e399d425baffd699..2b2021ec5853af4a2ef087a21bde87fb5bdc847e 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/SchedulerNamePatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/SchedulerNamePatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/TemplateLabelPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcherTest.kt
similarity index 87%
rename from theodolite/src/test/kotlin/theodolite/patcher/TemplateLabelPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcherTest.kt
index ebfe147e7b503defe14439fb1b954b9dd269ea3e..94073b9f34d6b76d69d82e4ea40ed047a68655ff 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/TemplateLabelPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/TemplateLabelPatcherTest.kt
@@ -1,8 +1,7 @@
-package theodolite.patcher
+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
 
@@ -28,7 +27,4 @@ internal class TemplateLabelPatcherTest: AbstractPatcherTest() {
         }
     }
 
-    @Test
-    fun getVariableName() {
-    }
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/VolumesConfigMapPatcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcherTest.kt
similarity index 95%
rename from theodolite/src/test/kotlin/theodolite/patcher/VolumesConfigMapPatcherTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcherTest.kt
index 5628fd7c50336dc620dec79945c69fd9856a9c91..db3fc812e426c0f74cf68d35a158f32a3ec0bc3f 100644
--- a/theodolite/src/test/kotlin/theodolite/patcher/VolumesConfigMapPatcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/patcher/VolumesConfigMapPatcherTest.kt
@@ -1,4 +1,4 @@
-package theodolite.patcher
+package rocks.theodolite.kubernetes.patcher
 
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.quarkus.test.junit.QuarkusTest
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2c0b1119402c3c443537367091ce99e601d6c2bd
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt
@@ -0,0 +1,63 @@
+package rocks.theodolite.kubernetes.slo
+
+import com.fasterxml.jackson.databind.node.BooleanNode
+import com.github.tomakehurst.wiremock.WireMockServer
+import com.github.tomakehurst.wiremock.client.WireMock.*
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+@QuarkusTest
+internal class ExternalSloCheckerTest {
+
+    private var wireMockServer: WireMockServer? = null
+
+    @BeforeEach
+    fun start() {
+        wireMockServer = WireMockServer().also {
+            it.start()
+        }
+    }
+
+    @AfterEach
+    fun stop() {
+        wireMockServer?.stop()
+    }
+
+    @Test
+    fun testExternalTrueResult() {
+        this.wireMockServer!!.stubFor(
+            post(urlEqualTo("/"))
+                .willReturn(
+                    aResponse().withJsonBody(BooleanNode.getTrue())
+                )
+        )
+
+        val sloChecker = ExternalSloChecker(
+            wireMockServer!!.baseUrl(),
+            mapOf()
+        )
+        val result = sloChecker.evaluate(listOf())
+        assertTrue(result)
+    }
+
+    @Test
+    fun testExternalFalseResult() {
+        this.wireMockServer!!.stubFor(
+            post(urlEqualTo("/"))
+                .willReturn(
+                    aResponse().withJsonBody(BooleanNode.getFalse())
+                )
+        )
+
+        val sloChecker = ExternalSloChecker(
+            wireMockServer!!.baseUrl(),
+            mapOf()
+        )
+        val result = sloChecker.evaluate(listOf())
+        assertFalse(result)
+    }
+
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a61119bbe0e5be180ccf3ca2c54ac2829eb4558d
--- /dev/null
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt
@@ -0,0 +1,298 @@
+package rocks.theodolite.kubernetes.slo
+
+import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import rocks.theodolite.core.strategies.Metric
+
+@QuarkusTest
+internal class SloCheckerFactoryTest {
+
+    @Test
+    fun testCreateGenericSloWithoutUrl() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.GENERIC.value,
+                mapOf(
+                    "warmup" to "60",
+                    "queryAggregation" to "median",
+                    "repetitionAggregation" to "median",
+                    "operator" to "lte",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateGenericSloWithoutWarmup() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.GENERIC.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "queryAggregation" to "median",
+                    "repetitionAggregation" to "median",
+                    "operator" to "lte",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateGenericSloWithoutQueryAggregation() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.GENERIC.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "warmup" to "60",
+                    "repetitionAggregation" to "median",
+                    "operator" to "lte",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateGenericSloWithoutRepetitionAggregation() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.GENERIC.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "warmup" to "60",
+                    "queryAggregation" to "median",
+                    "operator" to "lte",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateGenericSloWithoutOperator() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.GENERIC.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "warmup" to "60",
+                    "queryAggregation" to "median",
+                    "repetitionAggregation" to "median",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateGenericSloWithoutThreshold() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.GENERIC.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "warmup" to "60",
+                    "queryAggregation" to "median",
+                    "repetitionAggregation" to "median",
+                    "operator" to "lte",
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateGenericSloFloatThreshold() {
+        val factory = SloCheckerFactory()
+        val sloChecker = factory.create(
+            SloTypes.GENERIC.value,
+            mapOf(
+                "externalSloUrl" to "http://localhost:1234",
+                "warmup" to "60",
+                "queryAggregation" to "median",
+                "repetitionAggregation" to "median",
+                "operator" to "lte",
+                "threshold" to "12.34"
+            ),
+            100,
+            5,
+            Metric.DEMAND
+        )
+        assertInstanceOf(ExternalSloChecker::class.java, sloChecker)
+        val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
+        assertTrue(threshold is Double, "Expected threshold to be Double.")
+        assertEquals(12.34, threshold as Double, 0.01)
+    }
+
+    @Test
+    fun testCreateLagTrendSloWithoutUrl() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.LAG_TREND.value,
+                mapOf(
+                    "warmup" to "60",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateLagTrendSloWithoutWarmup() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.LAG_TREND.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "threshold" to "1234"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+
+    @Test
+    fun testCreateLagTrendSloWithoutThreshold() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.LAG_TREND.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "warmup" to "60",
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateLagTrendSloFloatThreshold() {
+        val factory = SloCheckerFactory()
+        val sloChecker = factory.create(
+            SloTypes.LAG_TREND.value,
+            mapOf(
+                "externalSloUrl" to "http://localhost:1234",
+                "warmup" to "60",
+                "threshold" to "12.34"
+            ),
+            100,
+            5,
+            Metric.DEMAND
+        )
+        assertInstanceOf(ExternalSloChecker::class.java, sloChecker)
+        val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
+        assertTrue(threshold is Double, "Expected threshold to be Double.")
+        assertEquals(12.34, threshold as Double, 0.01)
+    }
+
+    @Test
+    fun testCreateLagTrendRatioSloWithoutUrl() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.LAG_TREND_RATIO.value,
+                mapOf(
+                    "warmup" to "60",
+                    "ratio" to "0.123"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateLagTrendRatioSloWithoutWarmup() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.LAG_TREND_RATIO.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "ratio" to "0.123"
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+
+    @Test
+    fun testCreateLagTrendRatioSloWithoutRatioThreshold() {
+        val factory = SloCheckerFactory()
+        assertThrows<IllegalArgumentException> {
+            factory.create(
+                SloTypes.LAG_TREND_RATIO.value,
+                mapOf(
+                    "externalSloUrl" to "http://localhost:1234",
+                    "warmup" to "60",
+                ),
+                100,
+                5,
+                Metric.DEMAND
+            )
+        }
+    }
+
+    @Test
+    fun testCreateLagTrendRatioSloFloatThreshold() {
+        val factory = SloCheckerFactory()
+        val sloChecker = factory.create(
+            SloTypes.LAG_TREND_RATIO.value,
+            mapOf(
+                "externalSloUrl" to "http://localhost:1234",
+                "warmup" to "60",
+                "ratio" to "0.123"
+            ),
+            100,
+            5,
+            Metric.DEMAND
+        )
+        assertInstanceOf(ExternalSloChecker::class.java, sloChecker)
+        val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
+        assertTrue(threshold is Double, "Expected threshold to be Double.")
+        assertEquals(12.3, threshold as Double, 0.01)
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/SloFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloFactoryTest.kt
similarity index 59%
rename from theodolite/src/test/kotlin/theodolite/execution/operator/SloFactoryTest.kt
rename to theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloFactoryTest.kt
index c3dcd1b9529b6f24bd5b0deda920ba3e3ebb2978..de9d4c60dbad069ccb1229bebb4a4751cf96d98d 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/SloFactoryTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloFactoryTest.kt
@@ -1,13 +1,10 @@
-package theodolite.execution.operator
+package rocks.theodolite.kubernetes.slo
 
 import io.quarkus.test.junit.QuarkusTest
+import org.junit.jupiter.api.Assertions
 import org.junit.jupiter.api.Test
-import theodolite.benchmark.BenchmarkExecution
-import theodolite.benchmark.BenchmarkExecution.SloConfiguration
-import theodolite.benchmark.KubernetesBenchmark
-import theodolite.benchmark.Slo
-import theodolite.execution.SloFactory
-import org.junit.jupiter.api.Assertions.*
+import rocks.theodolite.kubernetes.model.BenchmarkExecution
+import rocks.theodolite.kubernetes.model.KubernetesBenchmark
 
 @QuarkusTest
 internal class SloFactoryTest {
@@ -19,7 +16,7 @@ internal class SloFactoryTest {
         val execution = BenchmarkExecution()
 
         // Define Benchmark SLOs
-        val slo = Slo()
+        val slo = KubernetesBenchmark.Slo()
         slo.name="test"
         slo.sloType="lag trend"
         slo.prometheusUrl="test.de"
@@ -36,7 +33,7 @@ internal class SloFactoryTest {
 
 
         // Define Execution SLOs, benchmark SLO values for these properties should be overwritten
-        val sloConfig = SloConfiguration()
+        val sloConfig = BenchmarkExecution.SloConfiguration()
         sloConfig.name = "test"
 
         val executionSloProperties = mutableMapOf<String, String>()
@@ -48,7 +45,7 @@ internal class SloFactoryTest {
         sloConfig.properties = executionSloProperties
 
         // SLO has 'name' that isn't defined in the benchmark, therefore it will be ignored by the SloFactory
-        val sloConfig2 = SloConfiguration()
+        val sloConfig2 = BenchmarkExecution.SloConfiguration()
         sloConfig2.name = "test2"
         sloConfig2.properties = executionSloProperties
 
@@ -57,16 +54,16 @@ internal class SloFactoryTest {
         val sloFactory = SloFactory()
         val combinedSlos = sloFactory.createSlos(execution,benchmark)
 
-        assertEquals(1, combinedSlos.size)
-        assertEquals("test", combinedSlos[0].name)
-        assertEquals("lag trend", combinedSlos[0].sloType)
-        assertEquals("test.de", combinedSlos[0].prometheusUrl)
-        assertEquals(0, combinedSlos[0].offset)
-
-        assertEquals(4, combinedSlos[0].properties.size)
-        assertEquals("3000", combinedSlos[0].properties["threshold"])
-        assertEquals("http://localhost:80/evaluate-slope", combinedSlos[0].properties["externalSloUrl"])
-        assertEquals("80", combinedSlos[0].properties["warmup"])
-        assertEquals("extended", combinedSlos[0].properties["extensionTest"])
+        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/TestBenchmarkExecutorImpl.kt b/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
deleted file mode 100644
index 97197f3bad066235634869c8c37de4bc5c570f8b..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package theodolite
-
-import theodolite.benchmark.Benchmark
-import theodolite.benchmark.Slo
-import theodolite.execution.BenchmarkExecutor
-import theodolite.util.Results
-import java.time.Duration
-
-class TestBenchmarkExecutorImpl(
-        private val mockResults: Array<Array<Boolean>>,
-        benchmark: Benchmark,
-        results: Results,
-        slo: List<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",
-        loadPatcherDefinitions = emptyList(),
-        resourcePatcherDefinitions = emptyList()
-    ) {
-
-    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/patcher/PatcherFactoryTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/PatcherFactoryTest.kt
deleted file mode 100644
index 1c3ecffa06f91d1d6c87706bb3fb28e94c414c35..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/patcher/PatcherFactoryTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package theodolite.patcher
-
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
-
-import org.junit.jupiter.api.Assertions.*
-
-internal class PatcherFactoryTest {
-
-    @BeforeEach
-    fun setUp() {
-    }
-
-    @AfterEach
-    fun tearDown() {
-    }
-}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ServiceSelectorPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ServiceSelectorPatcherTest.kt
deleted file mode 100644
index caffb7eaf37c3930dbbb8a043ccd1cb7bbfd8d74..0000000000000000000000000000000000000000
--- a/theodolite/src/test/kotlin/theodolite/patcher/ServiceSelectorPatcherTest.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package theodolite.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 ServiceSelectorPatcherTest {
-
-    @BeforeEach
-    fun setUp() {
-    }
-
-    @AfterEach
-    fun tearDown() {
-    }
-
-    @Test
-    fun patch() {
-    }
-}
\ No newline at end of file