diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 73976608226406fb3172844aba6097810a89d584..0cb6e600c738cb498050b31f5b54d5ac5827190d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,7 @@
-
 stages:
   - build-and-test
+  - deploy
+  - post-deploy-test
 
 
 .build-and-test:
@@ -28,18 +29,12 @@ stages:
     - ccache --max-size=20G
     - ccache --show-stats
 
-    # Ice configuration to run in Docker.
-    - export ICE_DEFAULT_HOST="127.0.0.1"
-    - export ICE_RUN_AS_ROOT="true"
-
     # Activate Axii.
     - source /axii/scripts/install_axii.sh
+    - _axii_auto_env_refresh
 
   script:
-    # Create workspace.
-    - axii workspace create ~/workspace workspace
-    - axii workspace activate workspace
-    - _axii_auto_env_refresh
+    - echo "ArmarX Workspace = '$ARMARX_WORKSPACE'"
 
     # Use workspace configuration from project.
     - cp "$CI_PROJECT_DIR/.gitlab/ci/armarx-workspace.json" "$ARMARX_WORKSPACE/armarx-workspace.json"
@@ -71,14 +66,6 @@ stages:
 
     - ccache --show-stats
 
-    # Try starting Ice.
-    - armarx switch docker_test --ice-host 127.0.0.1 --ice-port 10000 --ice-default-host 127.0.0.1 --mongo-host 127.0.0.1 --mongo-port 10001
-    - armarx profile
-    - armarx status || true
-    #- armarx start
-    # armarx status
-    #- armarx stop
-
     # Test.
     # ToDo: Add and use `axii ws test -m "$PROJECT_MODULE"`
     - cd "$PROJECT_PATH_IN_WORKSPACE/build"
@@ -93,11 +80,91 @@ build-and-test-bionic:
   stage: build-and-test
   extends: .build-and-test
 
-  image: git.h2t.iar.kit.edu:5050/sw/armarx/meta/axii:latest-bionic
+  image: git.h2t.iar.kit.edu:5050/sw/armarx/armarx-gui:latest-bionic
 
 
 build-and-test-jammy:
   stage: build-and-test
   extends: .build-and-test
 
-  image: git.h2t.iar.kit.edu:5050/sw/armarx/meta/axii:latest-jammy
+  image: git.h2t.iar.kit.edu:5050/sw/armarx/armarx-gui:latest-jammy
+
+
+docker-bionic:
+  stage: deploy
+  needs: ["build-and-test-bionic"]
+  image:
+    name: gcr.io/kaniko-project/executor:v1.9.0-debug
+    entrypoint: [""]
+  script:
+    - /kaniko/executor
+      --context "${CI_PROJECT_DIR}"
+      --dockerfile "${CI_PROJECT_DIR}/docker/bionic"
+      --destination "${CI_REGISTRY_IMAGE}:latest-bionic"
+
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master"
+
+
+docker-jammy:
+  stage: deploy
+  needs: ["build-and-test-jammy"]
+  image:
+    name: gcr.io/kaniko-project/executor:v1.9.0-debug
+    entrypoint: [""]
+  script:
+    - /kaniko/executor
+      --context "${CI_PROJECT_DIR}"
+      --dockerfile "${CI_PROJECT_DIR}/docker/jammy"
+      --destination "${CI_REGISTRY_IMAGE}:latest-jammy"
+
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master"
+
+
+.test-docker-image-common:
+
+  before_script:
+    - source /axii/scripts/install_axii.sh
+    - _axii_auto_env_refresh
+
+  script:
+    - echo "ArmarX Workspace = '$ARMARX_WORKSPACE'"
+    - printenv
+
+    - axii workspace list-modules
+    - axii workspace list-modules --deps
+    - axii workspace info
+    - echo "RobotAPI directory = '$RobotAPI_DIR'"
+
+    - which armarx
+    - which armarx-package
+
+    - armarx switch docker_test --ice-host 127.0.0.1 --ice-port 10000 --ice-default-host 127.0.0.1 --mongo-host 127.0.0.1 --mongo-port 10001
+    - armarx profile
+    - armarx status || true
+
+    - cd $ArmarXGui_DIR
+    - ctest --output-on-failure .
+
+
+test-docker-image-bionic:
+  stage: post-deploy-test
+  needs: ["docker-bionic"]
+  extends: .test-docker-image-common
+
+  image: git.h2t.iar.kit.edu:5050/sw/armarx/robot-api:latest-bionic
+
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master"
+
+
+test-docker-image-jammy:
+  stage: post-deploy-test
+  needs: ["docker-jammy"]
+  extends: .test-docker-image-common
+
+  image: git.h2t.iar.kit.edu:5050/sw/armarx/robot-api:latest-jammy
+
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master"
diff --git a/docker/armarx-workspace.json b/docker/armarx-workspace.json
new file mode 100644
index 0000000000000000000000000000000000000000..7052317cebc5fc6d5def5789b2da698583a252f4
--- /dev/null
+++ b/docker/armarx-workspace.json
@@ -0,0 +1,14 @@
+{
+  "modules": {
+    "armarx/RobotAPI": {}
+  },
+  "global": {
+    "prepare": {
+      "cmake": {
+        "definitions": {
+          "CMAKE_BUILD_TYPE": "RelWithDebInfo"
+        }
+      }
+    }
+  }
+}
diff --git a/docker/bionic b/docker/bionic
new file mode 100644
index 0000000000000000000000000000000000000000..66e01cea105fa3c1f84f0592df96f7fecd93d40f
--- /dev/null
+++ b/docker/bionic
@@ -0,0 +1,24 @@
+FROM git.h2t.iar.kit.edu:5050/sw/armarx/armarx-gui:latest-bionic
+
+# Setup environment.
+SHELL ["/bin/bash", "-c"]
+
+# Setup apt environment.
+RUN apt-get -qq update
+
+# Setup repository in Docker.
+WORKDIR $ARMARX_WORKSPACE/armarx/RobotAPI
+COPY --chmod=755 . .
+
+# Use workspace config.
+COPY docker/armarx-workspace.json $ARMARX_WORKSPACE/armarx-workspace.json
+
+# Fix "CMake Error in CMakeLists.txt: Imported target "VirtualRobot" includes non-existent path "/usr/lib/include"
+# (caused by at least dmp)
+RUN mkdir -p /usr/lib/include
+
+# Run the upgrade.
+RUN axii workspace system --accept-apt-install
+# ToDo: Prevent this from updating the target itself.
+RUN axii workspace update --prefer-https
+RUN axii workspace upgrade
diff --git a/docker/jammy b/docker/jammy
new file mode 100644
index 0000000000000000000000000000000000000000..1eef819fef3a422d72cc063ff21054897d313ab0
--- /dev/null
+++ b/docker/jammy
@@ -0,0 +1,20 @@
+FROM git.h2t.iar.kit.edu:5050/sw/armarx/armarx-gui:latest-jammy
+
+# Setup environment.
+SHELL ["/bin/bash", "-c"]
+
+# Setup apt environment.
+RUN apt-get -qq update
+
+# Setup repository in Docker.
+WORKDIR $ARMARX_WORKSPACE/armarx/RobotAPI
+COPY --chmod=755 . .
+
+# Use workspace config.
+COPY docker/armarx-workspace.json $ARMARX_WORKSPACE/armarx-workspace.json
+
+# Run the upgrade.
+RUN axii workspace system --accept-apt-install
+# ToDo: Prevent this from updating the target itself.
+RUN axii workspace update --prefer-https
+RUN axii workspace upgrade
diff --git a/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp b/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp
index 4722e9c5ce8deaabfc33a917c9b0c744d1a781fd..12dc68399fc92b3d32816dd212d75fc4b0cdab8c 100644
--- a/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp
+++ b/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp
@@ -1,23 +1,24 @@
-#include <regex>
-#include <fstream>
-
 #include "VisualizationRobot.h"
 
-#include <ArmarXCore/core/system/cmake/CMakePackageFinder.h>
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/system/ArmarXDataPath.h>
+#include <fstream>
+#include <regex>
+
 #include <VirtualRobot/SceneObject.h>
-#include <VirtualRobot/XML/RobotIO.h>
 #include <VirtualRobot/Visualization/CoinVisualization/CoinVisualization.h>
+#include <VirtualRobot/XML/RobotIO.h>
 
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/system/ArmarXDataPath.h>
+#include <ArmarXCore/core/system/cmake/CMakePackageFinder.h>
 
 namespace armarx::viz::coin
 {
     namespace
     {
-        VirtualRobot::RobotPtr loadRobot(std::string const& project, std::string const& filename)
+        VirtualRobot::RobotPtr
+        loadRobot(std::string const& project, std::string const& filename)
         {
-            VirtualRobot::RobotPtr  result;
+            VirtualRobot::RobotPtr result;
 
             if (filename.empty())
             {
@@ -32,7 +33,8 @@ namespace armarx::viz::coin
                 ARMARX_INFO << deactivateSpam()
                             << "You specified the absolute path to the robot file:"
                             << "\n\t'" << filename << "'"
-                            << "\nConsider specifying the containing ArmarX package and relative data path instead to "
+                            << "\nConsider specifying the containing ArmarX package and relative "
+                               "data path instead to "
                             << "improve portability to other systems.";
             }
             // We need to always check that the file is readable otherwise, VirtualRobot::RobotIO::loadRobot crashes
@@ -59,9 +61,7 @@ namespace armarx::viz::coin
                 if (result)
                 {
                     result->setThreadsafe(false);
-                    // Do we want to propagate joint values? Probably not...
-                    // Closing the hand on the real robot could be implemented on another level
-                    result->setPropagatingJointValuesEnabled(false);
+                    result->setPropagatingJointValuesEnabled(true);
                 }
                 else
                 {
@@ -88,7 +88,8 @@ namespace armarx::viz::coin
 
         static std::vector<RobotInstancePool> robotCache;
 
-        LoadedRobot getRobotFromCache(std::string const& project, std::string const& filename)
+        LoadedRobot
+        getRobotFromCache(std::string const& project, std::string const& filename)
         {
             // We can use a global variable, since this code is only executed in the GUI thread
 
@@ -104,7 +105,8 @@ namespace armarx::viz::coin
                     if (instancePool.usedInstances < instancePool.robots.size())
                     {
                         // 1) We have still unused instances in the pool ==> Just return one
-                        ARMARX_DEBUG << "Reusing robot instance from cache " << VAROUT(project) << ", " << VAROUT(filename);
+                        ARMARX_DEBUG << "Reusing robot instance from cache " << VAROUT(project)
+                                     << ", " << VAROUT(filename);
                         result.robot = instancePool.robots[instancePool.usedInstances];
                         instancePool.usedInstances += 1;
                     }
@@ -112,14 +114,17 @@ namespace armarx::viz::coin
                     else
                     {
                         // 2) We do not have unused instances in the pool ==> Clone one
-                        ARMARX_DEBUG << "Cloning robot from cache " << VAROUT(project) << ", " << VAROUT(filename);
+                        ARMARX_DEBUG << "Cloning robot from cache " << VAROUT(project) << ", "
+                                     << VAROUT(filename);
 
                         if (instancePool.robots.size() > 0)
                         {
-                            VirtualRobot::RobotPtr const& robotToClone = instancePool.robots.front();
+                            VirtualRobot::RobotPtr const& robotToClone =
+                                instancePool.robots.front();
                             float scaling = 1.0f;
                             bool preventCloningMeshesIfScalingIs1 = true;
-                            result.robot = robotToClone->clone(nullptr, scaling, preventCloningMeshesIfScalingIs1);
+                            result.robot = robotToClone->clone(
+                                nullptr, scaling, preventCloningMeshesIfScalingIs1);
 
                             // Insert the cloned robot into the instance pool
                             instancePool.robots.push_back(result.robot);
@@ -127,8 +132,10 @@ namespace armarx::viz::coin
                         }
                         else
                         {
-                            ARMARX_WARNING << "Encountered empty robot instance pool while trying to clone new instance"
-                                           << "\nRobot: " << VAROUT(project) << ", " << VAROUT(filename)
+                            ARMARX_WARNING << "Encountered empty robot instance pool while trying "
+                                              "to clone new instance"
+                                           << "\nRobot: " << VAROUT(project) << ", "
+                                           << VAROUT(filename)
                                            << "\nUsed instances: " << instancePool.usedInstances
                                            << "\nRobots: " << instancePool.robots.size();
                         }
@@ -137,7 +144,8 @@ namespace armarx::viz::coin
                 }
             }
 
-            ARMARX_DEBUG << "Loading robot from file  " << VAROUT(project) << ", " << VAROUT(filename);
+            ARMARX_DEBUG << "Loading robot from file  " << VAROUT(project) << ", "
+                         << VAROUT(filename);
             result.robot = loadRobot(project, filename);
             if (result.robot)
             {
@@ -146,13 +154,15 @@ namespace armarx::viz::coin
                 instancePool.filename = filename;
                 instancePool.robots.push_back(result.robot);
                 instancePool.usedInstances = 1;
-            } else
+            }
+            else
             {
-                ARMARX_WARNING << deactivateSpam(5) << "Robot " << VAROUT(project) << ", " << VAROUT(filename) << "could not be loaded!";
+                ARMARX_WARNING << deactivateSpam(5) << "Robot " << VAROUT(project) << ", "
+                               << VAROUT(filename) << "could not be loaded!";
             }
             return result;
         }
-    }
+    } // namespace
 
     VisualizationRobot::~VisualizationRobot()
     {
@@ -160,7 +170,8 @@ namespace armarx::viz::coin
         {
             if (instancePool.project == loaded.project && instancePool.filename == loaded.filename)
             {
-                ARMARX_DEBUG << "Removing robot from chace " << VAROUT(loaded.project) << ", " << VAROUT(loaded.filename);
+                ARMARX_DEBUG << "Removing robot from chace " << VAROUT(loaded.project) << ", "
+                             << VAROUT(loaded.filename);
                 std::vector<VirtualRobot::RobotPtr>& robots = instancePool.robots;
                 auto robotIter = std::find(robots.begin(), robots.end(), loaded.robot);
                 if (robotIter != robots.end())
@@ -176,7 +187,8 @@ namespace armarx::viz::coin
                     {
                         ARMARX_WARNING << "Expected there to be at least one used instance "
                                        << "while trying to put robot instance back into the pool"
-                                       << "\nRobot: " << VAROUT(loaded.project) << ", " << VAROUT(loaded.filename)
+                                       << "\nRobot: " << VAROUT(loaded.project) << ", "
+                                       << VAROUT(loaded.filename)
                                        << "\nUsed instances: " << instancePool.usedInstances;
                     }
                 }
@@ -184,12 +196,14 @@ namespace armarx::viz::coin
         }
     }
 
-    bool VisualizationRobot::update(ElementType const& element)
+    bool
+    VisualizationRobot::update(ElementType const& element)
     {
         IceUtil::Time time_start = IceUtil::Time::now();
-        (void) time_start;
+        (void)time_start;
 
-        bool robotChanged = loaded.project != element.project || loaded.filename != element.filename;
+        bool robotChanged =
+            loaded.project != element.project || loaded.filename != element.filename;
         if (robotChanged)
         {
             // The robot file changed, so reload the robot
@@ -199,8 +213,7 @@ namespace armarx::viz::coin
         {
             ARMARX_WARNING << deactivateSpam(10)
                            << "Robot will not visualized since it could not be loaded."
-                           << "\nID: " << element.id
-                           << "\nProject: " << element.project
+                           << "\nID: " << element.id << "\nProject: " << element.project
                            << "\nFilename: " << element.filename;
             return true;
         }
@@ -253,10 +266,8 @@ namespace armarx::viz::coin
 
         if (loadedDrawStyle & data::ModelDrawStyle::OVERRIDE_COLOR)
         {
-            if (loadedColor.r != element.color.r
-                || loadedColor.g != element.color.g
-                || loadedColor.b != element.color.b
-                || loadedColor.a != element.color.a)
+            if (loadedColor.r != element.color.r || loadedColor.g != element.color.g ||
+                loadedColor.b != element.color.b || loadedColor.a != element.color.a)
             {
                 int numChildren = node->getNumChildren();
                 for (int i = 0; i < numChildren; i++)
@@ -294,7 +305,8 @@ namespace armarx::viz::coin
         return true;
     }
 
-    void VisualizationRobot::recreateVisualizationNodes(int drawStyle)
+    void
+    VisualizationRobot::recreateVisualizationNodes(int drawStyle)
     {
         VirtualRobot::SceneObject::VisualizationType visuType = VirtualRobot::SceneObject::Full;
         if (drawStyle & data::ModelDrawStyle::COLLISION)
@@ -331,8 +343,9 @@ namespace armarx::viz::coin
         }
     }
 
-    void clearRobotCache()
+    void
+    clearRobotCache()
     {
         robotCache.clear();
     }
-}
+} // namespace armarx::viz::coin
diff --git a/source/RobotAPI/components/armem/client/GraspProviderExample/GraspProviderExample.cpp b/source/RobotAPI/components/armem/client/GraspProviderExample/GraspProviderExample.cpp
index e4e5b22aa996ecb88f8b63b3db8bba4831d699cd..605911657b2bb74dc53cdf114c4304a82a41be4a 100644
--- a/source/RobotAPI/components/armem/client/GraspProviderExample/GraspProviderExample.cpp
+++ b/source/RobotAPI/components/armem/client/GraspProviderExample/GraspProviderExample.cpp
@@ -5,74 +5,73 @@
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/core/time/Metronome.h>
 
-#include <RobotAPI/libraries/core/Pose.h>
-
-#include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
+#include <RobotAPI/libraries/GraspingUtility/aron/GraspCandidate.aron.generated.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
 #include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
-#include <RobotAPI/libraries/GraspingUtility/aron/GraspCandidate.aron.generated.h>
-
+#include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
+#include <RobotAPI/libraries/core/Pose.h>
 
 namespace armarx
 {
-    GraspProviderExamplePropertyDefinitions::GraspProviderExamplePropertyDefinitions(std::string prefix) :
+    GraspProviderExamplePropertyDefinitions::GraspProviderExamplePropertyDefinitions(
+        std::string prefix) :
         armarx::ComponentPropertyDefinitions(prefix)
     {
     }
 
-    armarx::PropertyDefinitionsPtr GraspProviderExample::createPropertyDefinitions()
+    armarx::PropertyDefinitionsPtr
+    GraspProviderExample::createPropertyDefinitions()
     {
         ARMARX_IMPORTANT << "Prperty defs";
-        armarx::PropertyDefinitionsPtr defs = new GraspProviderExamplePropertyDefinitions(getConfigIdentifier());
+        armarx::PropertyDefinitionsPtr defs =
+            new GraspProviderExamplePropertyDefinitions(getConfigIdentifier());
 
         defs->topic(debugObserver);
 
         defs->optional(memoryName, "mem.MemoryName", "Name of the memory to use.");
 
         return defs;
-
     }
 
-    std::string GraspProviderExample::getDefaultName() const
+    std::string
+    GraspProviderExample::getDefaultName() const
     {
         return "GraspProviderExample";
     }
 
-    GraspProviderExample::GraspProviderExample() : writer(memoryNameSystem()), reader(memoryNameSystem())
+    GraspProviderExample::GraspProviderExample()
     {
-
     }
 
-
-    void GraspProviderExample::onInitComponent()
+    void
+    GraspProviderExample::onInitComponent()
     {
         ARMARX_IMPORTANT << "Init";
     }
 
-
-    void GraspProviderExample::onConnectComponent()
+    void
+    GraspProviderExample::onConnectComponent()
     {
-        writer.connect();
-        reader.connect();
+        writer.connect(memoryNameSystem());
+        reader.connect(memoryNameSystem());
         task = new RunningTask<GraspProviderExample>(this, &GraspProviderExample::run);
         task->start();
     }
 
-
-    void GraspProviderExample::onDisconnectComponent()
+    void
+    GraspProviderExample::onDisconnectComponent()
     {
         task->stop();
     }
 
-
-    void GraspProviderExample::onExitComponent()
+    void
+    GraspProviderExample::onExitComponent()
     {
     }
 
-
-    void GraspProviderExample::run()
+    void
+    GraspProviderExample::run()
     {
         ARMARX_IMPORTANT << "Running example.";
 
@@ -90,9 +89,11 @@ namespace armarx
 
             // initialize all necessary fields of a bimanual grasp candidate and use writer to commit it to memory
             grasping::BimanualGraspCandidate bimanualCandidate = makeDummyBimanualGraspCandidate();
-            bimanualCandidate.groupNr = i; //non-necessary field, but used to commit different candidates
+            bimanualCandidate.groupNr =
+                i; //non-necessary field, but used to commit different candidates
 
-            writer.commitBimanualGraspCandidate(bimanualCandidate, armem::Time::Now(), "bimanualProvider");
+            writer.commitBimanualGraspCandidate(
+                bimanualCandidate, armem::Time::Now(), "bimanualProvider");
 
 
             //test for writing Seqs, candidates from the same object appear as instances of the same snapshot
@@ -102,7 +103,8 @@ namespace armarx
             candidatesToWrite.push_back(new grasping::GraspCandidate(candidate));
 
 
-            writer.commitGraspCandidateSeq(candidatesToWrite, armem::Time::Now(), "candidateProvider");
+            writer.commitGraspCandidateSeq(
+                candidatesToWrite, armem::Time::Now(), "candidateProvider");
 
             // test reader and debug by logging the group number of the candidate
 
@@ -112,15 +114,15 @@ namespace armarx
             {
                 candidates = reader.queryLatestGraspCandidates();
             }
-            catch (armem::error::QueryFailed &e)
+            catch (armem::error::QueryFailed& e)
             {
                 ARMARX_ERROR << e.makeMsg(memoryName);
             }
 
 
-            for (auto &[id, ca] : candidates)
+            for (auto& [id, ca] : candidates)
             {
-                ARMARX_INFO << "candidate with ID " << id << " has group number " <<  ca->groupNr ;
+                ARMARX_INFO << "candidate with ID " << id << " has group number " << ca->groupNr;
             }
 
             std::map<std::string, grasping::BimanualGraspCandidatePtr> bimanualCandidates;
@@ -129,21 +131,23 @@ namespace armarx
             {
                 bimanualCandidates = reader.queryLatestBimanualGraspCandidates();
             }
-            catch (armem::error::QueryFailed &e)
+            catch (armem::error::QueryFailed& e)
             {
                 ARMARX_ERROR << e.makeMsg(memoryName);
             }
 
-            for (auto &[id, ca] : bimanualCandidates)
+            for (auto& [id, ca] : bimanualCandidates)
             {
-                ARMARX_INFO << "bimanual candidate with ID " << id << " has group number " <<  ca->groupNr ;
+                ARMARX_INFO << "bimanual candidate with ID " << id << " has group number "
+                            << ca->groupNr;
             }
 
             m.waitForNextTick();
         }
     }
 
-    grasping::GraspCandidate GraspProviderExample::makeDummyGraspCandidate()
+    grasping::GraspCandidate
+    GraspProviderExample::makeDummyGraspCandidate()
     {
         armarx::grasping::GraspCandidate candidate = armarx::grasping::GraspCandidate();
 
@@ -168,9 +172,11 @@ namespace armarx
         return candidate;
     }
 
-    grasping::BimanualGraspCandidate GraspProviderExample::makeDummyBimanualGraspCandidate()
+    grasping::BimanualGraspCandidate
+    GraspProviderExample::makeDummyBimanualGraspCandidate()
     {
-        armarx::grasping::BimanualGraspCandidate bimanualCandidate = armarx::grasping::BimanualGraspCandidate();
+        armarx::grasping::BimanualGraspCandidate bimanualCandidate =
+            armarx::grasping::BimanualGraspCandidate();
 
         bimanualCandidate.approachVectorLeft = Vector3BasePtr(toIce(zeroVector));
         bimanualCandidate.approachVectorRight = Vector3BasePtr(toIce(zeroVector));
@@ -185,4 +191,4 @@ namespace armarx
         return bimanualCandidate;
     }
 
-}
+} // namespace armarx
diff --git a/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Component.cpp b/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Component.cpp
index 9f13e111eec8e51f3fa67e5d04f03d3df1fd0b64..c1a2f394afe6b50a6d5f5da71ff7296ec5e42d56 100644
--- a/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Component.cpp
+++ b/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Component.cpp
@@ -21,33 +21,31 @@
  */
 
 
-#include "RobotStatePredictionClientExample.h"
-#include "Impl.h"
-
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
+#include "Impl.h"
+#include "RobotStatePredictionClientExample.h"
 
 namespace armarx::robot_state_prediction_client_example
 {
 
-    Component::Component() :
-        pimpl(std::make_unique<Impl>(memoryNameSystem()))
+    Component::Component() : pimpl(std::make_unique<Impl>())
     {
     }
 
-
     RobotStatePredictionClientExample::~RobotStatePredictionClientExample() = default;
 
-
-    std::string Component::getDefaultName() const
+    std::string
+    Component::getDefaultName() const
     {
         return "RobotStatePredictionClientExample";
     }
 
-
-    armarx::PropertyDefinitionsPtr Component::createPropertyDefinitions()
+    armarx::PropertyDefinitionsPtr
+    Component::createPropertyDefinitions()
     {
-        armarx::PropertyDefinitionsPtr defs = new ComponentPropertyDefinitions(getConfigIdentifier());
+        armarx::PropertyDefinitionsPtr defs =
+            new ComponentPropertyDefinitions(getConfigIdentifier());
 
         ARMARX_CHECK_NOT_NULL(pimpl);
         pimpl->defineProperties(defs, "p.");
@@ -55,13 +53,13 @@ namespace armarx::robot_state_prediction_client_example
         return defs;
     }
 
-
-    void Component::onInitComponent()
+    void
+    Component::onInitComponent()
     {
     }
 
-
-    void Component::onConnectComponent()
+    void
+    Component::onConnectComponent()
     {
         pimpl->connect(memoryNameSystem(), arviz);
         pimpl->start();
@@ -70,19 +68,19 @@ namespace armarx::robot_state_prediction_client_example
         RemoteGui_startRunningTask();
     }
 
-
-    void Component::onDisconnectComponent()
+    void
+    Component::onDisconnectComponent()
     {
         pimpl->stop();
     }
 
-
-    void Component::onExitComponent()
+    void
+    Component::onExitComponent()
     {
     }
 
-
-    void Component::createRemoteGuiTab()
+    void
+    Component::createRemoteGuiTab()
     {
         using namespace armarx::RemoteGui::Client;
 
@@ -90,8 +88,9 @@ namespace armarx::robot_state_prediction_client_example
         RemoteGui_createTab(getName(), root, &tab);
     }
 
-    void Component::RemoteGui_update()
+    void
+    Component::RemoteGui_update()
     {
     }
 
-}
+} // namespace armarx::robot_state_prediction_client_example
diff --git a/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.cpp b/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.cpp
index c433669630c9631e471666fa3b3cd02acd25c2f9..a303f1c393b549a907bcfa49c1434a26bd873468 100644
--- a/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.cpp
+++ b/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.cpp
@@ -37,7 +37,6 @@
 #include <RobotAPI/libraries/armem_robot_state/client/common/constants.h>
 #include <RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h>
 
-
 namespace simox::alg
 {
     template <class... Args>
@@ -49,7 +48,6 @@ namespace simox::alg
         return conc;
     }
 
-
     template <class KeyT, class ValueT>
     std::map<KeyT, ValueT>
     map_from_key_value_pairs(const std::vector<KeyT>& lhs, const std::vector<ValueT>& rhs)
@@ -64,7 +62,6 @@ namespace simox::alg
         return map;
     }
 
-
     template <class KeyT, class ValueT>
     std::vector<ValueT>
     multi_at(const std::map<KeyT, ValueT>& map,
@@ -111,15 +108,13 @@ namespace simox::alg
 namespace armarx::robot_state_prediction_client_example
 {
 
-    Impl::Impl(armem::client::MemoryNameSystem& memoryNameSystem)
+    Impl::Impl()
     {
-        client.remote.robotReader.emplace(memoryNameSystem);
+        client.remote.robotReader.emplace();
     }
 
-
     Impl::~Impl() = default;
 
-
     void
     Impl::defineProperties(IceUtil::Handle<PropertyDefinitionContainer>& defs,
                            const std::string& prefix)
@@ -133,7 +128,6 @@ namespace armarx::robot_state_prediction_client_example
         client.remote.robotReader->registerPropertyDefinitions(defs);
     }
 
-
     void
     Impl::connect(armem::client::MemoryNameSystem& mns, viz::Client arviz)
     {
@@ -148,12 +142,11 @@ namespace armarx::robot_state_prediction_client_example
             ARMARX_WARNING << e.what();
         }
 
-        client.remote.robotReader->connect();
+        client.remote.robotReader->connect(mns);
 
         this->remote.arviz = arviz;
     }
 
-
     void
     Impl::start()
     {
@@ -161,14 +154,12 @@ namespace armarx::robot_state_prediction_client_example
         task->start();
     }
 
-
     void
     Impl::stop()
     {
         task->stop();
     }
 
-
     void
     Impl::run()
     {
@@ -182,7 +173,6 @@ namespace armarx::robot_state_prediction_client_example
         }
     }
 
-
     void
     Impl::runOnce()
     {
diff --git a/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.h b/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.h
index 272f9e2e62d6ac16b49a2674a7952d96e8618975..d716f5d94d7502c4c0533485c52ccd2f0a0dc732 100644
--- a/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.h
+++ b/source/RobotAPI/components/armem/client/RobotStatePredictionClientExample/Impl.h
@@ -27,27 +27,25 @@
 
 #include <ArmarXCore/util/tasks.h>
 
-#include <RobotAPI/libraries/armem/core/forward_declarations.h>
-#include <RobotAPI/libraries/armem/client/forward_declarations.h>
-#include <RobotAPI/libraries/armem/client/Reader.h>
-
 #include <RobotAPI/components/ArViz/Client/Client.h>
+#include <RobotAPI/libraries/armem/client/Reader.h>
+#include <RobotAPI/libraries/armem/client/forward_declarations.h>
+#include <RobotAPI/libraries/armem/core/forward_declarations.h>
 
 #include "RobotStatePredictionClient.h"
 
-
 namespace armarx::robot_state_prediction_client_example
 {
 
     class Impl
     {
     public:
-
-        Impl(armem::client::MemoryNameSystem& memoryNameSystem);
+        Impl();
         ~Impl();
 
 
-        void defineProperties(IceUtil::Handle<armarx::PropertyDefinitionContainer>& defs, const std::string& prefix);
+        void defineProperties(IceUtil::Handle<armarx::PropertyDefinitionContainer>& defs,
+                              const std::string& prefix);
         void connect(armem::client::MemoryNameSystem& mns, viz::Client arviz);
 
         void start();
@@ -58,7 +56,6 @@ namespace armarx::robot_state_prediction_client_example
 
 
     public:
-
         struct Properties
         {
             float updateFrequencyHz = 10;
@@ -66,12 +63,14 @@ namespace armarx::robot_state_prediction_client_example
             std::string robotName = "Armar6";
             float predictAheadSeconds = 1.0;
         };
+
         Properties properties;
 
         struct Remote
         {
             viz::Client arviz;
         };
+
         Remote remote;
 
         armarx::SimpleRunningTask<>::pointer_type task;
@@ -82,6 +81,5 @@ namespace armarx::robot_state_prediction_client_example
         std::optional<std::vector<armem::MemoryID>> localizationEntityIDs;
         std::optional<std::vector<armem::MemoryID>> propioceptionEntityIDs;
         std::optional<viz::Robot> robotViz;
-
     };
-}
+} // namespace armarx::robot_state_prediction_client_example
diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
index 02cbe58cef253fc0d741c182caa32b7c3d2a529c..d77d737156239241ed8a62952e788da11c99bb55 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
@@ -156,6 +156,16 @@ namespace armarx
         return SkillManagerComponentPluginUser::executeSkill(info, current);
     }
 
+    skills::manager::dto::SkillExecutionID
+    SkillsMemory::executeSkillAsync(const skills::manager::dto::SkillExecutionRequest& info,
+                                    const Ice::Current& current)
+    {
+        auto e = skills::SkillExecutionRequest::FromIce(info);
+        skillExecutionRequestCoreSegment.addSkillExecutionRequest(e);
+
+        return SkillManagerComponentPluginUser::executeSkillAsync(info, current);
+    }
+
     void
     SkillsMemory::updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
                                        const skills::callback::dto::ProviderID& providerId,
@@ -166,14 +176,27 @@ namespace armarx
         skillEventCoreSegment.addSkillUpdateEvent(u);
     }
 
+    IceUtil::Optional<skills::manager::dto::SkillStatusUpdate>
+    SkillsMemory::getSkillExecutionStatus(const skills::manager::dto::SkillExecutionID& executionId,
+                                          const Ice::Current& current)
+    {
+        auto eid = skills::SkillExecutionID::FromIce(executionId);
+        auto op = this->skillEventCoreSegment.getSkillStatusUpdate(eid);
+        if (op.has_value())
+        {
+            return op->toManagerIce();
+        }
+        return {};
+    }
+
     skills::manager::dto::SkillStatusUpdateMap
-    SkillsMemory::getLatestSkillExecutionStatuses(int n, const Ice::Current& current)
+    SkillsMemory::getSkillExecutionStatuses(const Ice::Current& current)
     {
-        auto m = skillEventCoreSegment.getLatestSkillEvents(n);
         skills::manager::dto::SkillStatusUpdateMap ret;
-        for (const auto& [k, v] : m)
+        auto updates = this->skillEventCoreSegment.getSkillStatusUpdates();
+        for (const auto& [k, v] : updates)
         {
-            ret[k.toManagerIce()] = v.toManagerIce();
+            ret.insert({k.toManagerIce(), v.toManagerIce()});
         }
         return ret;
     }
diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
index 81109b0bdf8787d6446e02fc11dcfe56ba484c4a..ead9f19122bc80266196aff40f138b4bd87c77f1 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
@@ -85,12 +85,21 @@ namespace armarx
         executeSkill(const skills::manager::dto::SkillExecutionRequest& info,
                      const Ice::Current& current) override;
 
+
+        skills::manager::dto::SkillExecutionID
+        executeSkillAsync(const skills::manager::dto::SkillExecutionRequest& info,
+                          const Ice::Current& current) override;
+
         void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
                                   const skills::callback::dto::ProviderID& id,
                                   const Ice::Current& current) override;
 
+        IceUtil::Optional<skills::manager::dto::SkillStatusUpdate>
+        getSkillExecutionStatus(const skills::manager::dto::SkillExecutionID& executionId,
+                                const Ice::Current& current) override;
+
         skills::manager::dto::SkillStatusUpdateMap
-        getLatestSkillExecutionStatuses(int n, const Ice::Current& current) override;
+        getSkillExecutionStatuses(const Ice::Current& current) override;
 
         // WritingInterface interface
         armem::data::CommitResult commit(const armem::data::Commit& commit,
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt b/source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt
index afbb7ef2abd07d6e718c7480ba7d84455574041d..b13f663e25b6c31fbb4ab3b919ce81431d617b70 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt
+++ b/source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt
@@ -13,10 +13,20 @@ set(COMPONENT_LIBS
 
 set(SOURCES
     SkillProviderExample.cpp
+    HelloWorld.cpp
+    Incomplete.cpp
+    Chaining.cpp
+    Callback.cpp
+    Timeout.cpp
 )
 
 set(HEADERS
     SkillProviderExample.h
+    HelloWorld.h
+    Incomplete.h
+    Chaining.h
+    Callback.h
+    Timeout.h
 )
 
 armarx_add_component("${SOURCES}" "${HEADERS}")
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Callback.cpp b/source/RobotAPI/components/skills/SkillProviderExample/Callback.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6dcea52a55191f03716aea507d13cd6c831d8d87
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Callback.cpp
@@ -0,0 +1,37 @@
+
+#include "Callback.h"
+
+namespace armarx::skills::provider
+{
+    CallbackSkill::CallbackSkill() : SimpleSkill(GetSkillDescription())
+    {
+    }
+
+    SkillDescription
+    CallbackSkill::GetSkillDescription()
+    {
+        return SkillDescription{.skillId = skills::SkillID{.skillName = "ShowMeCallbacks"},
+                                .description = "This skill does shows callbacks",
+                                .timeout = armarx::core::time::Duration::MilliSeconds(1000)};
+    }
+
+    Skill::MainResult
+    CallbackSkill::main(const MainInput& in)
+    {
+        ARMARX_IMPORTANT << "Logging three updates via the callback";
+        auto up1 = std::make_shared<aron::data::Dict>();
+        up1->addElement("updateInfo", std::make_shared<aron::data::String>("Update 1"));
+
+        in.callback(skills::SkillStatus::Running, up1);
+
+        auto up2 = std::make_shared<aron::data::Dict>();
+        up2->addElement("updateInfo", std::make_shared<aron::data::String>("Update 2"));
+        in.callback(skills::SkillStatus::Running, up2);
+
+        auto up3 = std::make_shared<aron::data::Dict>();
+        up3->addElement("updateInfo", std::make_shared<aron::data::String>("Update 3"));
+        in.callback(skills::SkillStatus::Running, up3);
+
+        return {TerminatedSkillStatus::Succeeded, nullptr};
+    }
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Callback.h b/source/RobotAPI/components/skills/SkillProviderExample/Callback.h
new file mode 100644
index 0000000000000000000000000000000000000000..c29c2b6f3d6007b1fda30b0c781b91be03a15232
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Callback.h
@@ -0,0 +1,41 @@
+
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Reister ( fabian dot reister at kit dot edu )
+ * @date       2021
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+
+// RobotAPI
+#include <RobotAPI/libraries/skills/provider/SimpleSkill.h>
+
+namespace armarx::skills::provider
+{
+    class CallbackSkill : public SimpleSkill
+    {
+    public:
+        CallbackSkill();
+
+        static SkillDescription GetSkillDescription();
+
+    private:
+        Skill::MainResult main(const MainInput&) final;
+    };
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Chaining.cpp b/source/RobotAPI/components/skills/SkillProviderExample/Chaining.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..983902512c03bc28c8d4429fd22c4690aeb14833
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Chaining.cpp
@@ -0,0 +1,40 @@
+
+
+#include "Chaining.h"
+
+namespace armarx::skills::provider
+{
+
+    ChainingSkill::ChainingSkill() : SimpleSkill(GetSkillDescription())
+    {
+    }
+
+    SkillDescription
+    ChainingSkill::GetSkillDescription()
+    {
+        return SkillDescription{.skillId = armarx::skills::SkillID{.skillName = "ChainingSkill"},
+                                .description =
+                                    "This skill calls the Timeout skill three times. The last "
+                                    "execution is aborted due to a timeout of this skill.",
+                                .timeout = armarx::core::time::Duration::MilliSeconds(5000)};
+    }
+
+    Skill::MainResult
+    ChainingSkill::main(const MainInput& in)
+    {
+        SkillProxy prx(
+            manager,
+            skills::SkillID{.providerId = *getSkillId().providerId, .skillName = "Timeout"});
+
+        ARMARX_INFO << "CALL PROXY FIRST TIME";
+        callSubskill(prx);
+        ARMARX_INFO << "CALL PROXY SECOND TIME";
+        callSubskill(prx);
+        ARMARX_INFO << "CALL PROXY THIRD TIME";
+        callSubskill(prx);
+
+        this->throwIfSkillShouldTerminate();
+
+        return {TerminatedSkillStatus::Succeeded, nullptr};
+    }
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Chaining.h b/source/RobotAPI/components/skills/SkillProviderExample/Chaining.h
new file mode 100644
index 0000000000000000000000000000000000000000..991c4a5aaab5d1be83f9684ca5bdbca1638b946d
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Chaining.h
@@ -0,0 +1,40 @@
+
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Reister ( fabian dot reister at kit dot edu )
+ * @date       2021
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+// RobotAPI
+#include <RobotAPI/libraries/skills/provider/SimpleSkill.h>
+
+namespace armarx::skills::provider
+{
+    class ChainingSkill : public SimpleSkill
+    {
+    public:
+        ChainingSkill();
+
+        static SkillDescription GetSkillDescription();
+
+    private:
+        Skill::MainResult main(const MainInput&) final;
+    };
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp b/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..edf918402a4c8ed1bbe510ab553d6dc568540dd5
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp
@@ -0,0 +1,47 @@
+
+
+#include "HelloWorld.h"
+
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
+#include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
+#include <RobotAPI/libraries/aron/core/type/variant/primitive/String.h>
+
+namespace armarx::skills::provider
+{
+    HelloWorldSkill::HelloWorldSkill() :
+        SimpleSpecializedSkill<skills::Example::HelloWorldAcceptedType>(GetSkillDescription())
+    {
+    }
+
+    SkillDescription
+    HelloWorldSkill::GetSkillDescription()
+    {
+        armarx::skills::Example::HelloWorldAcceptedType root_profile_params;
+        root_profile_params.some_float = 5;
+        root_profile_params.some_int = 42;
+        root_profile_params.some_text = "YOLO";
+        root_profile_params.some_optional_text = "OPTIONAL";
+        root_profile_params.some_list_of_matrices.push_back(Eigen::Matrix3f::Zero());
+        root_profile_params.some_matrix = Eigen::Matrix3f::Zero();
+
+        return SkillDescription{.skillId = skills::SkillID{.skillName = "HelloWorld"},
+                                .description = "This skill logs a message on ARMARX_IMPORTANT",
+                                .rootProfileDefaults = root_profile_params.toAron(),
+                                .timeout = armarx::core::time::Duration::MilliSeconds(1000),
+                                .parametersType =
+                                    armarx::skills::Example::HelloWorldAcceptedType::ToAronType()};
+    }
+
+    Skill::MainResult
+    HelloWorldSkill::main(const SpecializedMainInput& in)
+    {
+        ARMARX_IMPORTANT << "Hi, from the Hello World Skill.\n"
+                         << "I received the following data: \n"
+                         << aron::data::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(
+                                in.parameters.toAron())
+                                .dump(2)
+                         << "\n"
+                         << "(executed at: " << IceUtil::Time::now() << ")";
+        return {TerminatedSkillStatus::Succeeded, nullptr};
+    }
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.h b/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.h
new file mode 100644
index 0000000000000000000000000000000000000000..840b058fb171685db777126157fc21028db89c99
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.h
@@ -0,0 +1,42 @@
+
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Reister ( fabian dot reister at kit dot edu )
+ * @date       2021
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+// RobotAPI
+#include <RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.aron.generated.h>
+#include <RobotAPI/libraries/skills/provider/SimpleSpecializedSkill.h>
+
+namespace armarx::skills::provider
+{
+    // Skills:
+    class HelloWorldSkill : public SimpleSpecializedSkill<skills::Example::HelloWorldAcceptedType>
+    {
+    public:
+        HelloWorldSkill();
+
+        static SkillDescription GetSkillDescription();
+
+    private:
+        Skill::MainResult main(const SpecializedMainInput& in) final;
+    };
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Incomplete.cpp b/source/RobotAPI/components/skills/SkillProviderExample/Incomplete.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d6b4f277dcb36adc2b73bfe94b45b9adb500b22
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Incomplete.cpp
@@ -0,0 +1,53 @@
+
+
+#include "Incomplete.h"
+
+#include <RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.aron.generated.h>
+
+#include "HelloWorld.h"
+
+namespace armarx::skills::provider
+{
+
+    IncompleteSkill::IncompleteSkill() : SimpleSkill(GetSkillDescription())
+    {
+    }
+
+    SkillDescription
+    IncompleteSkill::GetSkillDescription()
+    {
+        auto d = HelloWorldSkill::GetSkillDescription();
+        return SkillDescription{.skillId = {.skillName = "IncompleteSkill"},
+                                .description = d.description,
+                                .timeout = d.timeout + armarx::core::time::Duration::Seconds(2),
+                                .parametersType = d.parametersType};
+    }
+
+    Skill::PrepareResult
+    IncompleteSkill::prepare()
+    {
+        if (!first_prepared)
+        {
+            first_prepared = true;
+
+            // set parameters after two seconds...
+            std::thread foo(
+                [&]()
+                {
+                    auto d = HelloWorldSkill::GetSkillDescription();
+                    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
+                    this->setParameters(d.rootProfileDefaults);
+                });
+            foo.detach();
+        }
+
+        return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
+    }
+
+    Skill::MainResult
+    IncompleteSkill::main(const MainInput& in)
+    {
+        auto s = HelloWorldSkill();
+        return s.mainOfSkill();
+    }
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Incomplete.h b/source/RobotAPI/components/skills/SkillProviderExample/Incomplete.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cf7b6e73b597b201d9d5213db160151d3a971c8
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Incomplete.h
@@ -0,0 +1,44 @@
+
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Reister ( fabian dot reister at kit dot edu )
+ * @date       2021
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+// RobotAPI
+#include <RobotAPI/libraries/skills/provider/SimpleSkill.h>
+
+namespace armarx::skills::provider
+{
+
+    class IncompleteSkill : public SimpleSkill
+    {
+    public:
+        IncompleteSkill();
+
+        static SkillDescription GetSkillDescription();
+
+    private:
+        Skill::PrepareResult prepare() final;
+        Skill::MainResult main(const MainInput&) final;
+
+        std::atomic_bool first_prepared = false;
+    };
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
index 2fbc92142ed7d9da9a381f450e0772cc87460b59..5ab480cd5c05556e2c7ea486ac0ec3976b1eb6df 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
@@ -1,191 +1,8 @@
 
-
 #include "SkillProviderExample.h"
 
-#include <RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.aron.generated.h>
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-#include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
-#include <RobotAPI/libraries/aron/core/type/variant/primitive/String.h>
-
 namespace armarx::skills::provider
 {
-    HelloWorldSkill::HelloWorldSkill() : Skill(GetSkillDescription())
-    {
-    }
-
-    SkillDescription
-    HelloWorldSkill::GetSkillDescription()
-    {
-        armarx::skills::Example::HelloWorldAcceptedType root_profile_params;
-        root_profile_params.some_float = 5;
-        root_profile_params.some_int = 42;
-        root_profile_params.some_text = "YOLO";
-        root_profile_params.some_list_of_matrices.push_back(Eigen::Matrix3f::Zero());
-        //default_params.some_matrix = Eigen::Matrix3f::Zero();
-
-        return SkillDescription{{"HelloWorld"},
-                                "This skill logs a message on ARMARX_IMPORTANT",
-                                root_profile_params.toAron(),
-                                armarx::core::time::Duration::MilliSeconds(1000),
-                                armarx::skills::Example::HelloWorldAcceptedType::ToAronType()};
-    }
-
-    Skill::MainResult
-    HelloWorldSkill::main()
-    {
-        ARMARX_IMPORTANT << "Hi, from the Hello World Skill.\n"
-                         << "I received the following data: \n"
-                         << aron::data::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(
-                                parameters)
-                                .dump(2)
-                         << "\n"
-                         << "Type fulfilled? "
-                         << parameters->fullfillsType(
-                                armarx::skills::Example::HelloWorldAcceptedType::ToAronType())
-                         << "\n"
-                         << "(executed at: " << IceUtil::Time::now() << ")";
-        return {TerminatedSkillStatus::Succeeded, nullptr};
-    }
-
-    IncompleteSkill::IncompleteSkill() : Skill(GetSkillDescription())
-    {
-    }
-
-    SkillDescription
-    IncompleteSkill::GetSkillDescription()
-    {
-        auto d = HelloWorldSkill::GetSkillDescription();
-        return SkillDescription{{"IncompleteSkill"},
-                                d.description,
-                                {},
-                                d.timeout + armarx::core::time::Duration::Seconds(2),
-                                d.acceptedType};
-    }
-
-    Skill::PrepareResult
-    IncompleteSkill::prepare()
-    {
-        if (!first_prepared)
-        {
-            first_prepared = true;
-            std::thread foo(
-                [&]()
-                {
-                    auto d = HelloWorldSkill::GetSkillDescription();
-                    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
-                    this->setParameters(d.rootProfileParameterization);
-                });
-            foo.detach();
-        }
-
-        auto s = HelloWorldSkill();
-        s.setParameters(this->getParameters());
-        s.mainOfSkill();
-
-        return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
-    }
-
-    Skill::MainResult
-    IncompleteSkill::main()
-    {
-        auto s = HelloWorldSkill();
-        s.setParameters(this->getParameters());
-        return s.mainOfSkill();
-    }
-
-    ChainingSkill::ChainingSkill() : Skill(GetSkillDescription())
-    {
-    }
-
-    SkillDescription
-    ChainingSkill::GetSkillDescription()
-    {
-        return SkillDescription{{"ChainingSkill"},
-                                "This skill calls the HelloWorld skill three times.",
-                                {},
-                                armarx::core::time::Duration::MilliSeconds(3000),
-                                nullptr};
-    }
-
-    Skill::MainResult
-    ChainingSkill::main()
-    {
-        armarx::skills::Example::HelloWorldAcceptedType exec1;
-        armarx::skills::Example::HelloWorldAcceptedType exec2;
-        armarx::skills::Example::HelloWorldAcceptedType exec3;
-
-        exec1.some_text = "Hello from the ChainingSkill 1";
-        exec2.some_text = "Hello from the ChainingSkill 2";
-        exec3.some_text = "Hello from the ChainingSkill 3";
-
-        SkillProxy skillExecPrx(
-            manager, skills::SkillID(skills::ProviderID("SkillProviderExample"), "HelloWorld"));
-
-        skillExecPrx.executeSkill(getSkillId().toString(), exec1.toAron());
-        skillExecPrx.executeSkill(getSkillId().toString(), exec2.toAron());
-        skillExecPrx.executeSkill(getSkillId().toString(), exec3.toAron());
-
-        return {TerminatedSkillStatus::Succeeded, nullptr};
-    }
-
-    TimeoutSkill::TimeoutSkill() :
-        PeriodicSkill(GetSkillDescription(), armarx::core::time::Frequency::Hertz(5))
-    {
-    }
-
-    SkillDescription
-    TimeoutSkill::GetSkillDescription()
-    {
-        return SkillDescription{{"Timeout"},
-                                "This fails with timeout reached",
-                                {},
-                                armarx::core::time::Duration::MilliSeconds(5000),
-                                nullptr};
-    }
-
-    PeriodicSkill::StepResult
-    TimeoutSkill::step()
-    {
-        // do heavy work
-        std::this_thread::sleep_for(std::chrono::milliseconds(500));
-
-        return {ActiveOrTerminatedSkillStatus::Running, nullptr};
-    }
-
-    CallbackSkill::CallbackSkill() : Skill(GetSkillDescription())
-    {
-    }
-
-    SkillDescription
-    CallbackSkill::GetSkillDescription()
-    {
-        return SkillDescription{{"ShowMeCallbacks"},
-                                "This skill does shows callbacks",
-                                {},
-                                armarx::core::time::Duration::MilliSeconds(1000),
-                                nullptr};
-    }
-
-    Skill::MainResult
-    CallbackSkill::main()
-    {
-        ARMARX_IMPORTANT << "Logging three updates via the callback";
-        auto up1 = std::make_shared<aron::data::Dict>();
-        up1->addElement("updateInfo", std::make_shared<aron::data::String>("Update 1"));
-
-        this->callback(skills::SkillStatus::Running, up1);
-
-        auto up2 = std::make_shared<aron::data::Dict>();
-        up2->addElement("updateInfo", std::make_shared<aron::data::String>("Update 2"));
-        this->callback(skills::SkillStatus::Running, up2);
-
-        auto up3 = std::make_shared<aron::data::Dict>();
-        up3->addElement("updateInfo", std::make_shared<aron::data::String>("Update 3"));
-        this->callback(skills::SkillStatus::Running, up3);
-
-        return {TerminatedSkillStatus::Succeeded, nullptr};
-    }
-
     SkillProviderExample::SkillProviderExample() : SkillProviderComponentPluginUser()
     {
     }
@@ -213,11 +30,10 @@ namespace armarx::skills::provider
 
         // Add another lambda example skill
         {
-            skills::SkillDescription fooDesc({"Foo"},
-                                             "This skill does exactly nothing.",
-                                             nullptr,
-                                             armarx::core::time::Duration::MilliSeconds(1000),
-                                             nullptr);
+            skills::SkillDescription fooDesc{.skillId = SkillID{.skillName = "Foo"},
+                                             .description = "This skill does exactly nothing.",
+                                             .timeout =
+                                                 armarx::core::time::Duration::MilliSeconds(1000)};
             addSkillFactory(fooDesc,
                             []()
                             {
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
index 190dc56a203e42aadac9f0fc483aed264fdc0685..b8391b0881f625af03b00b601983251c4d90558b 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
@@ -28,69 +28,15 @@
 
 // RobotAPI
 #include <RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h>
-#include <RobotAPI/libraries/skills/provider/SkillProxy.h>
+
+#include "Callback.h"
+#include "Chaining.h"
+#include "HelloWorld.h"
+#include "Incomplete.h"
+#include "Timeout.h"
 
 namespace armarx::skills::provider
 {
-    // Skills:
-    class HelloWorldSkill : public Skill
-    {
-    public:
-        HelloWorldSkill();
-
-        static SkillDescription GetSkillDescription();
-
-    private:
-        Skill::MainResult main() final;
-    };
-
-    class IncompleteSkill : public Skill
-    {
-    public:
-        IncompleteSkill();
-
-        static SkillDescription GetSkillDescription();
-
-    private:
-        Skill::PrepareResult prepare() final;
-        Skill::MainResult main() final;
-
-        std::atomic_bool first_prepared = false;
-    };
-
-    class ChainingSkill : public Skill
-    {
-    public:
-        ChainingSkill();
-
-        static SkillDescription GetSkillDescription();
-
-    private:
-        Skill::MainResult main() final;
-    };
-
-    class TimeoutSkill : public PeriodicSkill
-    {
-    public:
-        TimeoutSkill();
-
-        static SkillDescription GetSkillDescription();
-
-    private:
-        PeriodicSkill::StepResult step() final;
-    };
-
-    class CallbackSkill : public Skill
-    {
-    public:
-        CallbackSkill();
-
-        static SkillDescription GetSkillDescription();
-
-    private:
-        Skill::MainResult main() final;
-    };
-
     /**
      * @defgroup Component-ExampleClient ExampleClient
      * @ingroup RobotAPI-Components
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Timeout.cpp b/source/RobotAPI/components/skills/SkillProviderExample/Timeout.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..31dc03ae05caf0e2be256487e3a6a4294243e9d0
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Timeout.cpp
@@ -0,0 +1,28 @@
+
+#include "Timeout.h"
+
+namespace armarx::skills::provider
+{
+
+    TimeoutSkill::TimeoutSkill() :
+        PeriodicSkill(GetSkillDescription(), armarx::core::time::Frequency::Hertz(5))
+    {
+    }
+
+    SkillDescription
+    TimeoutSkill::GetSkillDescription()
+    {
+        return SkillDescription{.skillId = SkillID{.skillName = "Timeout"},
+                                .description = "This fails with timeout reached",
+                                .timeout = armarx::core::time::Duration::MilliSeconds(2000)};
+    }
+
+    PeriodicSkill::StepResult
+    TimeoutSkill::step()
+    {
+        // do heavy work
+        std::this_thread::sleep_for(std::chrono::milliseconds(50));
+
+        return {ActiveOrTerminatedSkillStatus::Running, nullptr};
+    }
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/Timeout.h b/source/RobotAPI/components/skills/SkillProviderExample/Timeout.h
new file mode 100644
index 0000000000000000000000000000000000000000..347e216a956c22d8d38b3b0b434ec0b5f4cf0225
--- /dev/null
+++ b/source/RobotAPI/components/skills/SkillProviderExample/Timeout.h
@@ -0,0 +1,42 @@
+
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Reister ( fabian dot reister at kit dot edu )
+ * @date       2021
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+
+// RobotAPI
+#include <RobotAPI/libraries/skills/provider/PeriodicSkill.h>
+
+namespace armarx::skills::provider
+{
+
+    class TimeoutSkill : public PeriodicSkill
+    {
+    public:
+        TimeoutSkill();
+
+        static SkillDescription GetSkillDescription();
+
+    private:
+        PeriodicSkill::StepResult step() final;
+    };
+} // namespace armarx::skills::provider
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml b/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml
index e90781ca62d7ef67751ed79b7556ab2c61f160a5..10c81ab542736b5a06bcd605f95353a619c3ad25 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml
+++ b/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml
@@ -22,6 +22,9 @@
             <ObjectChild key='some_text'>
                 <String />
             </ObjectChild>
+            <ObjectChild key='some_optional_text'>
+                <String optional="True" />
+            </ObjectChild>
 
             <ObjectChild key='some_list_of_matrices'>
                 <List>
diff --git a/source/RobotAPI/components/units/GraspCandidateObserver.cpp b/source/RobotAPI/components/units/GraspCandidateObserver.cpp
index 41ffefe98882f69004610a233dee16614f5b4f60..b434d1e3983096de91e73ddd2319fc843d3504a0 100644
--- a/source/RobotAPI/components/units/GraspCandidateObserver.cpp
+++ b/source/RobotAPI/components/units/GraspCandidateObserver.cpp
@@ -24,45 +24,51 @@
 #include "GraspCandidateObserver.h"
 
 //#include <ArmarXCore/core/checks/ConditionCheckEqualsPoseWithTolerance.h>
-#include <ArmarXCore/observers/checks/ConditionCheckUpdated.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/observers/checks/ConditionCheckEquals.h>
 #include <ArmarXCore/observers/checks/ConditionCheckInRange.h>
 #include <ArmarXCore/observers/checks/ConditionCheckLarger.h>
 #include <ArmarXCore/observers/checks/ConditionCheckSmaller.h>
+#include <ArmarXCore/observers/checks/ConditionCheckUpdated.h>
+
 #include <RobotAPI/libraries/core/checks/ConditionCheckEqualsPoseWithTolerance.h>
 #include <RobotAPI/libraries/core/checks/ConditionCheckMagnitudeChecks.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
 #define TCP_POSE_CHANNEL "TCPPose"
 #define TCP_TRANS_VELOCITIES_CHANNEL "TCPVelocities"
 using namespace armarx;
 using namespace armarx::grasping;
 
-GraspCandidateObserver::GraspCandidateObserver() : graspCandidateWriter(memoryNameSystem())
+GraspCandidateObserver::GraspCandidateObserver()
 {
 }
 
-void GraspCandidateObserver::onInitObserver()
+void
+GraspCandidateObserver::onInitObserver()
 {
     usingTopic(getProperty<std::string>("GraspCandidatesTopicName").getValue());
     offeringTopic(getProperty<std::string>("ConfigTopicName").getValue());
-
-
 }
 
-void GraspCandidateObserver::onConnectObserver()
+void
+GraspCandidateObserver::onConnectObserver()
 {
-    configTopic = getTopic<GraspCandidateProviderInterfacePrx>(getProperty<std::string>("ConfigTopicName").getValue());
-    graspCandidateWriter.connect();
+    configTopic = getTopic<GraspCandidateProviderInterfacePrx>(
+        getProperty<std::string>("ConfigTopicName").getValue());
+    graspCandidateWriter.connect(memoryNameSystem());
 }
 
-PropertyDefinitionsPtr GraspCandidateObserver::createPropertyDefinitions()
+PropertyDefinitionsPtr
+GraspCandidateObserver::createPropertyDefinitions()
 {
-    return PropertyDefinitionsPtr(new GraspCandidateObserverPropertyDefinitions(
-                                      getConfigIdentifier()));
+    return PropertyDefinitionsPtr(
+        new GraspCandidateObserverPropertyDefinitions(getConfigIdentifier()));
 }
 
-bool GraspCandidateObserver::FilterMatches(const CandidateFilterConditionPtr& filter, const std::string& providerName, const GraspCandidatePtr& candidate)
+bool
+GraspCandidateObserver::FilterMatches(const CandidateFilterConditionPtr& filter,
+                                      const std::string& providerName,
+                                      const GraspCandidatePtr& candidate)
 {
     if (filter->providerName != "*" && filter->providerName != providerName)
     {
@@ -72,11 +78,13 @@ bool GraspCandidateObserver::FilterMatches(const CandidateFilterConditionPtr& fi
     {
         return false;
     }
-    if (filter->approach != AnyApproach && (candidate->executionHints == 0 || filter->approach != candidate->executionHints->approach))
+    if (filter->approach != AnyApproach &&
+        (candidate->executionHints == 0 || filter->approach != candidate->executionHints->approach))
     {
         return false;
     }
-    if (filter->preshape != AnyAperture && (candidate->executionHints == 0 || filter->preshape != candidate->executionHints->preshape))
+    if (filter->preshape != AnyAperture &&
+        (candidate->executionHints == 0 || filter->preshape != candidate->executionHints->preshape))
     {
         return false;
     }
@@ -87,7 +95,8 @@ bool GraspCandidateObserver::FilterMatches(const CandidateFilterConditionPtr& fi
     return true;
 }
 
-std::string GraspCandidateObserver::ObjectTypeToString(objpose::ObjectType type)
+std::string
+GraspCandidateObserver::ObjectTypeToString(objpose::ObjectType type)
 {
     switch (type)
     {
@@ -102,7 +111,8 @@ std::string GraspCandidateObserver::ObjectTypeToString(objpose::ObjectType type)
     }
 }
 
-void GraspCandidateObserver::handleProviderUpdate(const std::string& providerName, int candidateCount)
+void
+GraspCandidateObserver::handleProviderUpdate(const std::string& providerName, int candidateCount)
 {
     if (updateCounters.count(providerName) == 0)
     {
@@ -118,26 +128,40 @@ void GraspCandidateObserver::handleProviderUpdate(const std::string& providerNam
     {
         offerChannel(providerName, "Channel of " + providerName);
     }
-    offerOrUpdateDataField(providerName, "updateCounter", Variant(updateCounters[providerName]), "Counter that increases for each update");
-    offerOrUpdateDataField(providerName, "candidateCount", Variant(candidateCount), "Number of provided candiates");
+    offerOrUpdateDataField(providerName,
+                           "updateCounter",
+                           Variant(updateCounters[providerName]),
+                           "Counter that increases for each update");
+    offerOrUpdateDataField(
+        providerName, "candidateCount", Variant(candidateCount), "Number of provided candiates");
 }
 
-void GraspCandidateObserver::reportGraspCandidates(const std::string& providerName, const GraspCandidateSeq& candidates, const Ice::Current&)
+void
+GraspCandidateObserver::reportGraspCandidates(const std::string& providerName,
+                                              const GraspCandidateSeq& candidates,
+                                              const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     this->candidates[providerName] = candidates;
-    graspCandidateWriter.commitGraspCandidateSeq(candidates, armarx::armem::Time::Now(), providerName);
+    graspCandidateWriter.commitGraspCandidateSeq(
+        candidates, armarx::armem::Time::Now(), providerName);
     handleProviderUpdate(providerName, candidates.size());
 }
 
-void GraspCandidateObserver::reportBimanualGraspCandidates(const std::string& providerName, const BimanualGraspCandidateSeq& candidates, const Ice::Current&)
+void
+GraspCandidateObserver::reportBimanualGraspCandidates(const std::string& providerName,
+                                                      const BimanualGraspCandidateSeq& candidates,
+                                                      const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     this->bimanualCandidates[providerName] = candidates;
     handleProviderUpdate(providerName, candidates.size());
 }
 
-void GraspCandidateObserver::reportProviderInfo(const std::string& providerName, const ProviderInfoPtr& info, const Ice::Current&)
+void
+GraspCandidateObserver::reportProviderInfo(const std::string& providerName,
+                                           const ProviderInfoPtr& info,
+                                           const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     providers[providerName] = info;
@@ -154,36 +178,37 @@ void GraspCandidateObserver::reportProviderInfo(const std::string& providerName,
     offerOrUpdateDataField(providerName, "objectType", ObjectTypeToString(info->objectType), "");
 }
 
-InfoMap GraspCandidateObserver::getAvailableProvidersWithInfo(const Ice::Current&)
+InfoMap
+GraspCandidateObserver::getAvailableProvidersWithInfo(const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     return providers;
 }
 
-StringSeq GraspCandidateObserver::getAvailableProviderNames(const Ice::Current&)
+StringSeq
+GraspCandidateObserver::getAvailableProviderNames(const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     return getAvailableProviderNames();
 }
 
-
-
-ProviderInfoPtr GraspCandidateObserver::getProviderInfo(const std::string& providerName, const Ice::Current&)
+ProviderInfoPtr
+GraspCandidateObserver::getProviderInfo(const std::string& providerName, const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     checkHasProvider(providerName);
     return providers[providerName];
 }
 
-bool GraspCandidateObserver::hasProvider(const std::string& providerName, const Ice::Current& c)
+bool
+GraspCandidateObserver::hasProvider(const std::string& providerName, const Ice::Current& c)
 {
     std::unique_lock lock(dataMutex);
     return hasProvider(providerName);
 }
 
-
-
-GraspCandidateSeq GraspCandidateObserver::getAllCandidates(const Ice::Current&)
+GraspCandidateSeq
+GraspCandidateObserver::getAllCandidates(const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     GraspCandidateSeq all;
@@ -194,11 +219,16 @@ GraspCandidateSeq GraspCandidateObserver::getAllCandidates(const Ice::Current&)
     return all;
 }
 
-GraspCandidateSeq GraspCandidateObserver::getCandidatesByProvider(const std::string& providerName, const Ice::Current& c)
+GraspCandidateSeq
+GraspCandidateObserver::getCandidatesByProvider(const std::string& providerName,
+                                                const Ice::Current& c)
 {
     return getCandidatesByProviders(Ice::StringSeq{providerName});
 }
-GraspCandidateSeq GraspCandidateObserver::getCandidatesByProviders(const Ice::StringSeq& providerNames, const Ice::Current& c)
+
+GraspCandidateSeq
+GraspCandidateObserver::getCandidatesByProviders(const Ice::StringSeq& providerNames,
+                                                 const Ice::Current& c)
 {
     std::unique_lock lock(dataMutex);
     GraspCandidateSeq all;
@@ -213,7 +243,9 @@ GraspCandidateSeq GraspCandidateObserver::getCandidatesByProviders(const Ice::St
     return all;
 }
 
-GraspCandidateSeq GraspCandidateObserver::getCandidatesByFilter(const CandidateFilterConditionPtr& filter, const Ice::Current&)
+GraspCandidateSeq
+GraspCandidateObserver::getCandidatesByFilter(const CandidateFilterConditionPtr& filter,
+                                              const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     GraspCandidateSeq matching;
@@ -230,20 +262,26 @@ GraspCandidateSeq GraspCandidateObserver::getCandidatesByFilter(const CandidateF
     return matching;
 }
 
-Ice::Int GraspCandidateObserver::getUpdateCounterByProvider(const std::string& providerName, const Ice::Current&)
+Ice::Int
+GraspCandidateObserver::getUpdateCounterByProvider(const std::string& providerName,
+                                                   const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     checkHasProvider(providerName);
     return updateCounters[providerName];
 }
 
-IntMap GraspCandidateObserver::getAllUpdateCounters(const Ice::Current& providerName)
+IntMap
+GraspCandidateObserver::getAllUpdateCounters(const Ice::Current& providerName)
 {
     std::unique_lock lock(dataMutex);
     return updateCounters;
 }
 
-bool GraspCandidateObserver::setProviderConfig(const std::string& providerName, const StringVariantBaseMap& config, const Ice::Current&)
+bool
+GraspCandidateObserver::setProviderConfig(const std::string& providerName,
+                                          const StringVariantBaseMap& config,
+                                          const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     if (providers.count(providerName) == 0)
@@ -254,19 +292,23 @@ bool GraspCandidateObserver::setProviderConfig(const std::string& providerName,
     return true;
 }
 
-void GraspCandidateObserver::setSelectedCandidates(const GraspCandidateSeq& candidates, const Ice::Current&)
+void
+GraspCandidateObserver::setSelectedCandidates(const GraspCandidateSeq& candidates,
+                                              const Ice::Current&)
 {
     std::unique_lock lock(selectedCandidatesMutex);
     selectedCandidates = candidates;
 }
 
-GraspCandidateSeq GraspCandidateObserver::getSelectedCandidates(const Ice::Current&)
+GraspCandidateSeq
+GraspCandidateObserver::getSelectedCandidates(const Ice::Current&)
 {
     std::unique_lock lock(selectedCandidatesMutex);
     return selectedCandidates;
 }
 
-BimanualGraspCandidateSeq GraspCandidateObserver::getAllBimanualCandidates(const Ice::Current&)
+BimanualGraspCandidateSeq
+GraspCandidateObserver::getAllBimanualCandidates(const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
     BimanualGraspCandidateSeq all;
@@ -277,19 +319,25 @@ BimanualGraspCandidateSeq GraspCandidateObserver::getAllBimanualCandidates(const
     return all;
 }
 
-void GraspCandidateObserver::setSelectedBimanualCandidates(const grasping::BimanualGraspCandidateSeq& candidates, const Ice::Current&)
+void
+GraspCandidateObserver::setSelectedBimanualCandidates(
+    const grasping::BimanualGraspCandidateSeq& candidates,
+    const Ice::Current&)
 {
     std::unique_lock lock(selectedCandidatesMutex);
     selectedBimanualCandidates = candidates;
 }
 
-BimanualGraspCandidateSeq GraspCandidateObserver::getSelectedBimanualCandidates(const Ice::Current&)
+BimanualGraspCandidateSeq
+GraspCandidateObserver::getSelectedBimanualCandidates(const Ice::Current&)
 {
     std::unique_lock lock(selectedCandidatesMutex);
     return selectedBimanualCandidates;
 }
 
-void GraspCandidateObserver::clearCandidatesByProvider(const std::string& providerName, const Ice::Current&)
+void
+GraspCandidateObserver::clearCandidatesByProvider(const std::string& providerName,
+                                                  const Ice::Current&)
 {
     std::unique_lock lock(dataMutex);
 
@@ -299,18 +347,24 @@ void GraspCandidateObserver::clearCandidatesByProvider(const std::string& provid
     }
 }
 
-bool GraspCandidateObserver::hasProvider(const std::string& providerName)
+bool
+GraspCandidateObserver::hasProvider(const std::string& providerName)
 {
     return providers.count(providerName) > 0;
 }
-void GraspCandidateObserver::checkHasProvider(const std::string& providerName)
+
+void
+GraspCandidateObserver::checkHasProvider(const std::string& providerName)
 {
     if (!hasProvider(providerName))
     {
-        throw LocalException("Unknown provider name '") << providerName << "'. Available providers: " << getAvailableProviderNames();
+        throw LocalException("Unknown provider name '")
+            << providerName << "'. Available providers: " << getAvailableProviderNames();
     }
 }
-StringSeq GraspCandidateObserver::getAvailableProviderNames()
+
+StringSeq
+GraspCandidateObserver::getAvailableProviderNames()
 {
     StringSeq names;
     for (const auto& pair : providers)
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp
index 697b087cc7f0b53edc3196b499c0f76dd3dec312..08870cfcc27981ee9e0e97f096563a35a1f51507 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp
@@ -129,8 +129,8 @@ namespace armarx
         }
         //visu
         {
-            _tripFakeRobotGP.getWriteBuffer()(0, 0) = std::nanf("");
-            _tripFakeRobotGP.commitWrite();
+            _tripRt2NonRtRobotGP.getWriteBuffer().setIdentity();
+            _tripRt2NonRtRobotGP.commitWrite();
         }
     }
 
@@ -281,6 +281,9 @@ namespace armarx
             }
         }
         _tripRt2NonRt.commitWrite();
+
+        _tripRt2NonRtRobotGP.getWriteBuffer() = _rtRobot->getGlobalPose();
+        _tripRt2NonRtRobotGP.commitWrite();
     }
 
     void
@@ -412,17 +415,13 @@ namespace armarx
     NJointCartesianWaypointController::setVisualizationRobotGlobalPose(const Eigen::Matrix4f& p,
                                                                        const Ice::Current&)
     {
-        std::lock_guard g{_tripFakeRobotGPWriteMutex};
-        _tripFakeRobotGP.getWriteBuffer() = p;
-        _tripFakeRobotGP.commitWrite();
+        ; // No longer used ...
     }
 
     void
     NJointCartesianWaypointController::resetVisualizationRobotGlobalPose(const Ice::Current&)
     {
-        std::lock_guard g{_tripFakeRobotGPWriteMutex};
-        _tripFakeRobotGP.getWriteBuffer()(0, 0) = std::nanf("");
-        _tripFakeRobotGP.commitWrite();
+        ; // No longer used ...
     }
 
     void
@@ -477,7 +476,7 @@ namespace armarx
             std::lock_guard g{_tripRt2NonRtMutex};
             const auto& buf = _tripRt2NonRt.getUpToDateReadBuffer();
 
-            const Eigen::Matrix4f fakeGP = _tripFakeRobotGP.getUpToDateReadBuffer();
+            const Eigen::Matrix4f fakeGP = _tripRt2NonRtRobotGP.getUpToDateReadBuffer();
             const Eigen::Matrix4f gp = std::isfinite(fakeGP(0, 0)) ? fakeGP : buf.rootPose;
 
             if (buf.tcp != buf.tcpTarg)
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h
index dce6aed44f8bb931baf2a598c06f127cb9b20d66..59734617b4bb75cd3599f0d2c198beb7e7694bc0 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h
@@ -146,8 +146,7 @@ namespace armarx
         mutable std::recursive_mutex _tripRt2NonRtMutex;
         TripleBuffer<RtToNonRtData> _tripRt2NonRt;
 
-        mutable std::recursive_mutex _tripFakeRobotGPWriteMutex;
-        TripleBuffer<Eigen::Matrix4f> _tripFakeRobotGP;
+        TripleBuffer<Eigen::Matrix4f> _tripRt2NonRtRobotGP;
 
         //publish data
         std::atomic_size_t _publishWpsNum{0};
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp
index e9aea0a9858d85e24b9e49ee088c18405af0668a..61d0d6c3a63f6a82f981eed63a61d6cabd57105e 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp
@@ -722,7 +722,7 @@ namespace armarx::RobotUnitModule
             for (std::size_t idxRobot = 0; idxRobot < nodes.size(); ++idxRobot)
             {
                 const VirtualRobot::RobotNodePtr& node = nodes.at(idxRobot);
-                if (node->isRotationalJoint() || node->isTranslationalJoint())
+                if (node->isJoint())
                 {
                     const auto& name = node->getName();
                     if (sensorDevices.has(name))
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleLogging.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleLogging.cpp
index 8cb11c331040c5dfd12fea456c0d2391a36c9f2b..ee8522d21984cbf6936bd1b2c259e37850398d7f 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleLogging.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleLogging.cpp
@@ -494,10 +494,13 @@ namespace armarx::RobotUnitModule
         ARMARX_TRACE;
         throwIfInControlThread(BOOST_CURRENT_FUNCTION);
         std::lock_guard<std::mutex> guard{rtLoggingMutex};
-        if (!rtDataStreamingEntry.count(receiver))
+        
+        if (rtDataStreamingEntry.count(receiver) == 0u)
         {
-            throw InvalidArgumentException{"stopDataStreaming called for a nonexistent log"};
+            ARMARX_INFO << "stopDataStreaming called for a nonexistent log";
+            return;
         }
+
         ARMARX_INFO_S << "RobotUnit: request to stop DataStreaming for " << receiver->ice_id();
         rtDataStreamingEntry.at(receiver).stopStreaming = true;
     }
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp
index a4d9867488a2a2f8e9cb176158ba18fc01a8c538..698df2657899773a1a111bd02ce561abd66308ef 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp
@@ -21,12 +21,17 @@
  */
 
 #include "RobotUnitModuleSelfCollisionChecker.h"
+#include <algorithm>
+#include <cstddef>
+#include <string>
 
 #include <SimoxUtility/algorithm/string/string_tools.h>
 #include <VirtualRobot/CollisionDetection/CollisionChecker.h>
 #include <VirtualRobot/Obstacle.h>
 #include <VirtualRobot/RobotNodeSet.h>
 
+#include "ArmarXCore/core/logging/Logging.h"
+#include "ArmarXCore/core/time/Metronome.h"
 #include <ArmarXCore/core/util/OnScopeExit.h>
 
 #include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
@@ -219,6 +224,58 @@ namespace armarx::RobotUnitModule
                 node->getCollisionModel()->inflateModel(minSelfDistance / 2.f);
             }
         }
+
+        // Remove / filter collision pairs according to robot model (XML: Physics/IgnoreCollision)
+        {
+            ARMARX_VERBOSE << "Removing ignored collision pairs";
+            // introduce vector to remove elements "in-place" via remove-erase-if idiom (not possible for sets)
+            std::vector<std::pair<std::string, std::string>> validNamePairsToCheck(namePairsToCheck.begin(), namePairsToCheck.end());
+
+            const auto isCollisionIgnored = [this](const std::string& a, const std::string& b) -> bool {
+
+                if(a == FLOOR_OBJ_STR or b == FLOOR_OBJ_STR)
+                {
+                    return false;
+                }
+
+                const auto nodeA = selfCollisionAvoidanceRobot->getRobotNode(a);
+                const auto nodeB = selfCollisionAvoidanceRobot->getRobotNode(b);
+
+                if(nodeA == nullptr or nodeB == nullptr)
+                {
+                    return false;
+                }
+
+                const std::vector<std::string> nodesIgnoredByA = nodeA->getIgnoredCollisionModels();
+                const std::vector<std::string> nodesIgnoredByB = nodeB->getIgnoredCollisionModels();
+
+                if(std::find(nodesIgnoredByA.begin(), nodesIgnoredByA.end(), b) != nodesIgnoredByA.end())
+                {
+                    ARMARX_VERBOSE << "Ignoring collision between nodes: " << a << " -- " << b;
+                    return true;
+                }
+
+                if(std::find(nodesIgnoredByB.begin(), nodesIgnoredByB.end(), a) != nodesIgnoredByB.end())
+                {
+                    ARMARX_VERBOSE << "Ignoring collision between nodes: " << b << " -- " << a;
+                    return true;
+                }
+
+                return false;
+
+            };
+
+            validNamePairsToCheck.erase(std::remove_if(validNamePairsToCheck.begin(), validNamePairsToCheck.end(), [&isCollisionIgnored](const auto& p) -> bool {
+                const auto& [a, b] = p;
+                return isCollisionIgnored(a, b);
+            }), validNamePairsToCheck.end());
+
+            ARMARX_VERBOSE << "Removed " << (namePairsToCheck.size() - validNamePairsToCheck.size()) << " collision pairs.";
+
+            // copy over name pairs which should not be ignored
+            namePairsToCheck = std::set(validNamePairsToCheck.begin(), validNamePairsToCheck.end());
+        }
+
         //collect pairs
         for (const auto& pair : namePairsToCheck)
         {
@@ -227,14 +284,18 @@ namespace armarx::RobotUnitModule
                     ? floor->getSceneObject(0)
                     : selfCollisionAvoidanceRobot->getRobotNode(pair.first);
 
+            ARMARX_CHECK_NOT_NULL(first) << pair.first;
+
             VirtualRobot::SceneObjectPtr second =
                 (pair.second == FLOOR_OBJ_STR)
                     ? floor->getSceneObject(0)
                     : selfCollisionAvoidanceRobot->getRobotNode(pair.second);
 
+            ARMARX_CHECK_NOT_NULL(second) << pair.second;
+
             nodePairsToCheck.emplace_back(first, second);
         }
-        ARMARX_CHECK_EQUAL(nodePairsToCheck.size(), nodePairsToCheck.size());
+        ARMARX_CHECK_EQUAL(nodePairsToCheck.size(), namePairsToCheck.size());
     }
 
     void
@@ -303,21 +364,23 @@ namespace armarx::RobotUnitModule
         };
         while (true)
         {
-            const auto startT = std::chrono::high_resolution_clock::now();
+            const auto freq = checkFrequency.load();
+
+            core::time::Metronome metronome(Frequency::Hertz(freq));
+
             //done
             if (isShuttingDown())
             {
                 return;
             }
-            const auto freq = checkFrequency.load();
             const bool inEmergencyStop =
                 _module<ControlThread>().getEmergencyStopState() == eEmergencyStopActive;
             if (inEmergencyStop || freq == 0)
             {
-                ARMARX_INFO << deactivateSpam() << "Self collision checker: skipping check "
+                ARMARX_VERBOSE << deactivateSpam() << "Self collision checker: skipping check "
                             << VAROUT(freq) << " " << VAROUT(inEmergencyStop);
                 //currently wait
-                std::this_thread::sleep_for(std::chrono::microseconds{1000});
+                std::this_thread::sleep_for(std::chrono::microseconds{1'000});
                 continue;
             }
             //update robot + check
@@ -332,6 +395,7 @@ namespace armarx::RobotUnitModule
                     bool allJoints0 = true;
                     for (const auto& node : selfCollisionAvoidanceRobotNodes)
                     {
+                        ARMARX_CHECK_NOT_NULL(node);
                         if (0 != node->getJointValue())
                         {
                             allJoints0 = false;
@@ -348,6 +412,10 @@ namespace armarx::RobotUnitModule
                 for (std::size_t idx = 0; idx < nodePairsToCheck.size(); ++idx)
                 {
                     const auto& pair = nodePairsToCheck.at(idx);
+
+                    ARMARX_CHECK_NOT_NULL(pair.first);
+                    ARMARX_CHECK_NOT_NULL(pair.second);
+
                     if (selfCollisionAvoidanceRobot->getCollisionChecker()->checkCollision(
                             pair.first, pair.second))
                     {
@@ -370,9 +438,16 @@ namespace armarx::RobotUnitModule
                                    << nodePairsToCheck.size() << " pairs";
                 }
             }
+
             //sleep remaining
-            std::this_thread::sleep_until(
-                startT + std::chrono::microseconds{static_cast<int64_t>(1000000 / freq)});
+            const auto duration = metronome.waitForNextTick();
+
+            if(not duration.isPositive())
+            {
+                ARMARX_WARNING << deactivateSpam(10) << 
+                    "Self collision checking took too long. "
+                    "Exceeding time budget by " << duration.toMilliSecondsDouble() << "ms.";
+            }
         }
     }
 
diff --git a/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.cpp b/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.cpp
index 1431b8b5219ef4622d21024132397690a81d9526..14cc8fb49d139d177425040e4b69334f4e9e042a 100644
--- a/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.cpp
+++ b/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.cpp
@@ -22,6 +22,7 @@
 
 #include "GamepadUnit.h"
 
+#include "ArmarXCore/core/logging/Logging.h"
 #include <ArmarXCore/util/CPPUtility/trace.h>
 #include <ArmarXCore/observers/variant/TimestampVariant.h>
 #include <linux/joystick.h>
@@ -33,6 +34,7 @@ void GamepadUnit::onInitComponent()
     ARMARX_TRACE;
     offeringTopic(getProperty<std::string>("GamepadTopicName").getValue());
     deviceName = getProperty<std::string>("GamepadDeviceName").getValue();
+    deviceEventName = getProperty<std::string>("GamepadForceFeedbackName").getValue();
     readTask = new RunningTask<GamepadUnit>(this, &GamepadUnit::run, "GamepadUnit");
 }
 
@@ -52,7 +54,7 @@ void GamepadUnit::onConnectComponent()
         ARMARX_TRACE;
         if (!dataTimestamp)
         {
-            ARMARX_INFO << "dataTimestamp is null, waiting for value";
+            ARMARX_INFO << deactivateSpam(1) << "dataTimestamp is null, waiting for value";
             return;
         }
         ARMARX_CHECK_NOT_NULL(dataTimestamp);
@@ -69,15 +71,23 @@ void GamepadUnit::onConnectComponent()
             ARMARX_INFO << deactivateSpam(100000, std::to_string(dataTimestamp->getTimestamp())) << "No new signal from gamepad for " << age.toMilliSecondsDouble() << " milliseconds. Not sending data. Timeout: " <<  getProperty<int>("PublishTimeout").getValue() << " ms";
         }
     }, 30);
+    
     sendTask->start();
     ARMARX_TRACE;
     openGamepadConnection();
 }
 
+void GamepadUnit::vibrate(const ::Ice::Current&)
+{
+    ARMARX_INFO << "vibration!";
+    js.executeEffect();
+}
+
 bool GamepadUnit::openGamepadConnection()
 {
-    if (js.open(deviceName))
+    if (js.open(deviceName, deviceEventName))
     {
+
         ARMARX_TRACE;
         ARMARX_INFO << "opened a gamepad named " << js.name << " with " << js.numberOfAxis << " axis and " << js.numberOfButtons << " buttons.";
         if (js.numberOfAxis == 8 && js.numberOfButtons == 11)
@@ -185,4 +195,3 @@ armarx::PropertyDefinitionsPtr GamepadUnit::createPropertyDefinitions()
     return armarx::PropertyDefinitionsPtr(new GamepadUnitPropertyDefinitions(
             getConfigIdentifier()));
 }
-
diff --git a/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.h b/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.h
index 109ce81a17a98c5154b396e09064d9943be6ff0a..a2008600dc1f50432bbbf3f00c646153c7d7e83e 100644
--- a/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.h
+++ b/source/RobotAPI/drivers/GamepadUnit/GamepadUnit.h
@@ -53,6 +53,7 @@ namespace armarx
             //defineOptionalProperty<std::string>("PropertyName", "DefaultValue", "Description");
             defineOptionalProperty<std::string>("GamepadTopicName", "GamepadValues", "Name of the Gamepad Topic");
             defineOptionalProperty<std::string>("GamepadDeviceName", "/dev/input/js2", "device that will be opened as a gamepad");
+            defineOptionalProperty<std::string>("GamepadForceFeedbackName", "", "device that will be used for force feedback, leave empty to disable. See RobotAPI/source/RobotAPI/drivers/GamepadUnit/README.md for more details.");
             defineOptionalProperty<int>("PublishTimeout", 2000, "In Milliseconds. Timeout after which the gamepad data is not published after, if no new data was read from the gamepad");
         }
     };
@@ -69,7 +70,8 @@ namespace armarx
      * Detailed description of class GamepadUnit.
      */
     class GamepadUnit :
-        virtual public armarx::Component
+        virtual public armarx::Component,
+        virtual public GamepadUnitInterface
     {
     public:
         /**
@@ -108,6 +110,8 @@ namespace armarx
 
         bool openGamepadConnection();
 
+        void vibrate(const ::Ice::Current& = ::Ice::emptyCurrent) override;
+
     private:
         GamepadUnitListenerPrx topicPrx;
         RunningTask<GamepadUnit>::pointer_type readTask;
@@ -116,9 +120,9 @@ namespace armarx
         void run();
         std::mutex mutex;
         std::string deviceName;
+        std::string deviceEventName;
         Joystick js;
         GamepadData data;
         TimestampVariantPtr dataTimestamp;
     };
 }
-
diff --git a/source/RobotAPI/drivers/GamepadUnit/Joystick.h b/source/RobotAPI/drivers/GamepadUnit/Joystick.h
index 1f39074b7a1449f9d58b643d42be68f2c123c445..af7cc386dc35a8b1b8ec3122545fd0bb88fef4bd 100644
--- a/source/RobotAPI/drivers/GamepadUnit/Joystick.h
+++ b/source/RobotAPI/drivers/GamepadUnit/Joystick.h
@@ -22,12 +22,17 @@
 
 #pragma once
 
-#include<linux/joystick.h>
-#include<sys/stat.h>
-#include<fcntl.h>
+#include <cstdint>
+
+#include <fcntl.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include <ArmarXCore/core/Component.h>
 
+#include <linux/joystick.h>
+
 namespace armarx
 {
 
@@ -36,21 +41,39 @@ namespace armarx
 
     private:
         int fd = -1;
+        int fdEvent = -1;
         js_event event;
 
     public:
-
         std::vector<int16_t> axis;
         std::vector<bool> buttonsPressed;
         int numberOfAxis;
         int numberOfButtons;
         std::string name;
 
-        bool open(std::string const& deviceName)
+        bool
+        open(std::string const& deviceName, std::string const& deviceEventName)
         {
+
             fd = ::open(deviceName.c_str(), O_RDONLY);
+
+            if (!deviceEventName.empty())
+            {
+                ARMARX_INFO << "Force feedback enabled";
+                fdEvent = ::open(deviceEventName.c_str(), O_RDWR | O_CLOEXEC);
+
+                ARMARX_CHECK(fdEvent != -1);
+            } else {
+                ARMARX_INFO << "Force feedback disabled";
+            }
+
             if (fd != -1)
             {
+                // ARMARX_INFO << "before";
+                // executeEffect();
+                // ARMARX_INFO << "after";
+
+
                 ioctl(fd, JSIOCGAXES, &numberOfAxis);
                 ioctl(fd, JSIOCGBUTTONS, &numberOfButtons);
                 name.resize(255);
@@ -59,15 +82,21 @@ namespace armarx
                 name = name.c_str();
                 buttonsPressed.resize(numberOfButtons, false);
             }
+
+            ARMARX_INFO << "execute effect";
+            executeEffect();
+
             return fd != -1;
         }
 
-        bool opened() const
+        bool
+        opened() const
         {
             return fd != -1;
         }
 
-        bool pollEvent()
+        bool
+        pollEvent()
         {
             int bytes = read(fd, &event, sizeof(event));
 
@@ -89,10 +118,165 @@ namespace armarx
             return true;
         }
 
-        void close()
+        void
+        executeEffect(int gain = 100, const int nTimes = 1)
+        {
+            // this feature is disabled
+            if(fdEvent < 0) return;
+
+            // see https://docs.kernel.org/input/ff.html
+
+
+            // https://xnux.eu/devices/feature/vibrator.html
+
+            int ret;
+            // pollfd pfds[1];
+            int effects;
+
+            // fd = open_event_dev("vibrator", O_RDWR | O_CLOEXEC);
+            // syscall_error(fd < 0, "Can't open vibrator event device");
+
+            ret = ioctl(fdEvent, EVIOCGEFFECTS, &effects);
+            ARMARX_CHECK(ret >= 0);
+            // syscall_error(ret < 0, "EVIOCGEFFECTS failed");
+
+            // ARMARX_CHECK(effects & FF_RUMBLE);
+
+            // Set the gain of the device
+            {
+                // int gain; between 0 and 100
+                struct input_event ie; // structure used to communicate with the driver
+
+                ie.type = EV_FF;
+                ie.code = FF_GAIN;
+                ie.value = 0xFFFFUL * gain / 100;
+
+                if (write(fdEvent, &ie, sizeof(ie)) == -1)
+                {
+                    perror("set gain");
+                }
+            }
+
+
+            ff_effect e;
+            // e.type = FF_RUMBLE;
+            // e.id = -1;
+            // e.replay.length = 5000;
+            // e.replay.delay = 500;
+            // e.u.rumble.strong_magnitude = 1;
+
+            e.type = FF_PERIODIC;
+            e.id = -1;
+            e.replay.length = 5000;
+            e.replay.delay = 500;
+            e.u.periodic.waveform = FF_SQUARE;
+            e.u.periodic.period = 1000;
+            e.u.periodic.magnitude = 0xFF;
+            e.u.periodic.offset = 0xFF;
+
+            ret = ioctl(fdEvent, EVIOCSFF, &e);
+            ARMARX_CHECK(ret >= 0);
+
+            // syscall_error(ret < 0, "EVIOCSFF failed");
+
+            ARMARX_INFO << VAROUT(e.id);
+
+            input_event play;
+            play.type = EV_FF;
+            play.code = static_cast<std::uint16_t>(e.id);
+            play.value = 1;
+
+            ret = write(fdEvent, &play, sizeof(play));
+            ARMARX_CHECK(ret >= 0);
+
+            ARMARX_INFO << "Executing effect";
+
+
+            for (int i = 0; i < 5; i++)
+            {
+                
+                input_event statusIe; // structure used to communicate with the driver
+                statusIe.type = EV_FF_STATUS;
+                statusIe.code = e.id;
+                // statusIe.value = 0;
+
+                ret = write(fdEvent, &statusIe, sizeof(statusIe));
+
+                // ARMARX_CHECK()
+                // ret should be FF_STATUS_PLAYING
+                ARMARX_INFO << VAROUT(ret);
+
+                sleep(1);
+            }
+
+
+            // syscall_error(ret < 0, "write failed");
+
+            ARMARX_INFO << "Executing effect";
+            // sleep(6);
+
+
+            input_event stop;
+            stop.type = EV_FF;
+            stop.code = e.id;
+            stop.value = 0;
+            [[maybe_unused]] const int stopStatus = write(fdEvent, static_cast<const void*>(&stop), sizeof(stop));
+
+
+            ret = ioctl(fdEvent, EVIOCRMFF, e.id);
+            ARMARX_CHECK(ret >= 0);
+
+            // syscall_error(ret < 0, "EVIOCRMFF failed");
+
+            // close(fdEvent);
+
+
+            /**/
+            // Set the gain of the device
+            // {
+            //     // int gain; between 0 and 100
+            //     struct input_event ie; // structure used to communicate with the driver
+
+            //     ie.type = EV_FF;
+            //     ie.code = FF_GAIN;
+            //     ie.value = 0xFFFFUL * gain / 100;
+
+            //     if (write(fd, &ie, sizeof(ie)) == -1)
+            //     {
+            //         perror("set gain");
+            //     }
+            // }
+
+
+            // struct input_event play;
+            // struct input_event stop;
+
+            // // upload request to device
+            // ff_effect effect;
+            // const auto uploadStatus = ioctl(fd, EVIOCSFF, &effect);
+
+            // // Play n times
+            // play.type = EV_FF;
+            // play.code = effect.id;
+            // play.value = nTimes;
+
+            // const int playStatus = write(fd, static_cast<const void*>(&play), sizeof(play));
+
+            // // Stop an effect
+            // stop.type = EV_FF;
+            // stop.code = effect.id;
+            // stop.value = 0;
+            // const int stopStatus = write(fd, static_cast<const void*>(&stop), sizeof(stop));
+
+            // // remove effect
+            // ioctl(fd, EVIOCRMFF, effect.id);
+        }
+
+        void
+        close()
         {
             ::close(fd);
             fd = -1;
         }
     };
-}
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitConfigDialog.cpp b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitConfigDialog.cpp
index 2e4c5851c2417c67158785cb31226b03fff7c269..55776817eee69b3f783cda883871b88ec9679439 100644
--- a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitConfigDialog.cpp
+++ b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitConfigDialog.cpp
@@ -36,11 +36,11 @@ armarx::HandUnitConfigDialog::HandUnitConfigDialog(QWidget* parent) :
 
 
     proxyFinderLeftHand = new IceProxyFinder<HandUnitInterfacePrx>(this);
-    proxyFinderLeftHand->setSearchMask("*Unit");
+    proxyFinderLeftHand->setSearchMask("*LeftHandUnit");
     ui->proxyFinderContainerLeftHand->addWidget(proxyFinderLeftHand, 0, 0, 1, 1);
 
     proxyFinderRightHand = new IceProxyFinder<HandUnitInterfacePrx>(this);
-    proxyFinderRightHand->setSearchMask("*Unit");
+    proxyFinderRightHand->setSearchMask("*RightHandUnit");
     ui->proxyFinderContainerRightHand->addWidget(proxyFinderRightHand, 0, 0, 1, 1);
 }
 
diff --git a/source/RobotAPI/gui-plugins/KinematicUnitPlugin/KinematicUnitGuiPlugin.cpp b/source/RobotAPI/gui-plugins/KinematicUnitPlugin/KinematicUnitGuiPlugin.cpp
index fa8011d66e9fb45de290395eab222e9299888620..bdf8a1cd639b473cf9ac4cb4af27f8d97da81fc1 100644
--- a/source/RobotAPI/gui-plugins/KinematicUnitPlugin/KinematicUnitGuiPlugin.cpp
+++ b/source/RobotAPI/gui-plugins/KinematicUnitPlugin/KinematicUnitGuiPlugin.cpp
@@ -74,6 +74,7 @@
 #include <iostream>
 #include <memory>
 #include <optional>
+#include <stdexcept>
 #include <string>
 
 
@@ -81,8 +82,10 @@
 //#define KINEMATIC_UNIT_FILE_DEFAULT_PACKAGE std::string("RobotAPI")
 #define KINEMATIC_UNIT_NAME_DEFAULT "Robot"
 //#define TOPIC_NAME_DEFAULT "RobotState"
-#define SLIDER_POS_DEG_MULTIPLIER 5
-#define SLIDER_POS_RAD_MULTIPLIER 100
+
+constexpr float SLIDER_POS_DEG_MULTIPLIER = 5;
+constexpr float SLIDER_POS_RAD_MULTIPLIER = 100;
+constexpr float SLIDER_POS_HEMI_MULTIPLIER = 100;
 
 namespace armarx
 {
@@ -648,15 +651,26 @@ namespace armarx
         {
             if (currentNode)
             {
-                const bool isDeg = ui.checkBoxUseDegree->isChecked();
-                const bool isRot = currentNode->isRotationalJoint();
-                const auto factor =
-                    isRot && !isDeg ? SLIDER_POS_RAD_MULTIPLIER : SLIDER_POS_DEG_MULTIPLIER;
-                float conversionFactor = isRot && isDeg ? 180.0 / M_PI : 1.0f;
-                float pos = currentNode->getJointValue() * conversionFactor;
-
-                ui.lcdNumberKinematicUnitJointValue->display((int)pos);
-                ui.horizontalSliderKinematicUnitPos->setSliderPosition((int)(pos * factor));
+                if (currentNode->isRotationalJoint() or currentNode->isHemisphereJoint() or currentNode->isFourBarJoint())
+                {
+                    const bool isDeg = ui.checkBoxUseDegree->isChecked();
+                    const auto factor =
+                        isDeg ? SLIDER_POS_DEG_MULTIPLIER : SLIDER_POS_RAD_MULTIPLIER;
+                    const float conversionFactor = isDeg ? 180.0 / M_PI : 1.0f;
+                    const float pos = currentNode->getJointValue() * conversionFactor;
+
+                    ui.lcdNumberKinematicUnitJointValue->display((int)pos);
+                    ui.horizontalSliderKinematicUnitPos->setSliderPosition((int)(pos * factor));
+                }
+
+                if (currentNode->isTranslationalJoint())
+                {
+                    const auto factor = SLIDER_POS_DEG_MULTIPLIER;
+                    const float pos = currentNode->getJointValue();
+
+                    ui.lcdNumberKinematicUnitJointValue->display((int)pos);
+                    ui.horizontalSliderKinematicUnitPos->setSliderPosition((int)(pos * factor));
+                }
             }
         }
     }
@@ -712,15 +726,49 @@ namespace armarx
 
         if (currentNode)
         {
-            QString unit = currentNode->isRotationalJoint()
-                               ? (ui.checkBoxUseDegree->isChecked() ? "deg" : "rad")
-                               : "mm";
+            const QString unit = [&]() -> QString
+            {
+                if (currentNode->isRotationalJoint() or currentNode->isHemisphereJoint() or currentNode->isFourBarJoint())
+                {
+                    if (ui.checkBoxUseDegree->isChecked())
+                    {
+                        return "deg";
+                    }
+
+                    return "rad";
+                }
+
+                if (currentNode->isTranslationalJoint())
+                {
+                    return "mm";
+                }
+
+                throw std::invalid_argument("unknown/unsupported joint type");
+            }();
+
             ui.labelUnit->setText(unit);
-            const bool isDeg = ui.checkBoxUseDegree->isChecked();
-            const bool isRot = currentNode->isRotationalJoint();
-            const auto factor =
-                isRot && !isDeg ? SLIDER_POS_RAD_MULTIPLIER : SLIDER_POS_DEG_MULTIPLIER;
-            float conversionFactor = isRot && isDeg ? 180.0 / M_PI : 1.0f;
+
+
+            const auto [factor, conversionFactor] = [&]() -> std::pair<float, float>
+            {
+                if (currentNode->isRotationalJoint() or currentNode->isHemisphereJoint() or currentNode->isFourBarJoint())
+                {
+                    const bool isDeg = ui.checkBoxUseDegree->isChecked();
+                    if (isDeg)
+                    {
+                        return {SLIDER_POS_DEG_MULTIPLIER, 180.0 / M_PI};
+                    }
+                    return {SLIDER_POS_RAD_MULTIPLIER, 1};
+                }
+
+                if (currentNode->isTranslationalJoint())
+                {
+                    return {SLIDER_POS_DEG_MULTIPLIER, 1};
+                }
+
+                throw std::invalid_argument("unknown/unsupported joint type");
+            }();
+
             jointModes[currentNode->getName()] = ePositionControl;
 
             if (kinematicUnitInterfacePrx)
@@ -728,8 +776,8 @@ namespace armarx
                 kinematicUnitInterfacePrx->switchControlMode(jointModes);
             }
 
-            float lo = currentNode->getJointLimitLo() * conversionFactor;
-            float hi = currentNode->getJointLimitHi() * conversionFactor;
+            const float lo = currentNode->getJointLimitLo() * conversionFactor;
+            const float hi = currentNode->getJointLimitHi() * conversionFactor;
 
             if (hi - lo <= 0.0f)
             {
@@ -745,7 +793,7 @@ namespace armarx
                 synchronizeRobotJointAngles();
             }
 
-            float pos = currentNode->getJointValue() * conversionFactor;
+            const float pos = currentNode->getJointValue() * conversionFactor;
             ARMARX_INFO << "Setting position control for current node "
                         << "(name '" << currentNode->getName() << "' with current value " << pos
                         << ")";
@@ -754,8 +802,18 @@ namespace armarx
             // This will initially send a position target with a small delta to the joint.
             ui.horizontalSliderKinematicUnitPos->blockSignals(true);
 
-            ui.horizontalSliderKinematicUnitPos->setMaximum(hi * factor);
-            ui.horizontalSliderKinematicUnitPos->setMinimum(lo * factor);
+            const float sliderMax = hi * factor;
+            const float sliderMin = lo * factor;
+
+            ui.horizontalSliderKinematicUnitPos->setMaximum(sliderMax);
+            ui.horizontalSliderKinematicUnitPos->setMinimum(sliderMin);
+
+            const std::size_t desiredNumberOfTicks = 1'000;
+
+            const float tickInterval = (sliderMax - sliderMin) / desiredNumberOfTicks;
+            ARMARX_INFO << VAROUT(tickInterval);
+
+            ui.horizontalSliderKinematicUnitPos->setTickInterval(tickInterval);
             ui.lcdNumberKinematicUnitJointValue->display(pos);
 
             ui.horizontalSliderKinematicUnitPos->blockSignals(false);
@@ -780,14 +838,37 @@ namespace armarx
             // set the velocity to zero to stop any previous controller (e.g. torque controller)
             jointVelocities[currentNode->getName()] = 0;
 
-            const bool isDeg = ui.checkBoxUseDegree->isChecked();
-            const bool isRot = currentNode->isRotationalJoint();
-            QString unit = isRot ? (isDeg ? "deg/s" : "rad/(100*s)") : "mm/s";
+
+            const QString unit = [&]() -> QString
+            {
+                if (currentNode->isRotationalJoint() or currentNode->isHemisphereJoint() or currentNode->isFourBarJoint())
+                {
+                    if (ui.checkBoxUseDegree->isChecked())
+                    {
+                        return "deg/s";
+                    }
+
+                    return "rad/(100*s)";
+                }
+
+                if (currentNode->isTranslationalJoint())
+                {
+                    return "mm/s";
+                }
+
+                throw std::invalid_argument("unknown/unsupported joint type");
+            }();
+
+
             ui.labelUnit->setText(unit);
             ARMARX_INFO << "setting velocity control for current Node Name: "
                         << currentNode->getName() << flush;
-            float lo = isRot ? (isDeg ? -90 : -M_PI * 100) : -1000;
-            float hi = isRot ? (isDeg ? +90 : +M_PI * 100) : 1000;
+
+            const bool isDeg = ui.checkBoxUseDegree->isChecked();
+            const bool isRot = currentNode->isRotationalJoint() or currentNode->isHemisphereJoint() or currentNode->isFourBarJoint();
+
+            const float lo = isRot ? (isDeg ? -90 : -M_PI * 100) : -1000;
+            const float hi = isRot ? (isDeg ? +90 : +M_PI * 100) : 1000;
 
             try
             {
@@ -1105,7 +1186,7 @@ namespace armarx
         const ControlMode currentControlMode = getSelectedControlMode();
 
         const bool isDeg = ui.checkBoxUseDegree->isChecked();
-        const bool isRot = currentNode->isRotationalJoint();
+        const bool isRot = currentNode->isRotationalJoint() or currentNode->isHemisphereJoint() or currentNode->isFourBarJoint();
 
         if (currentControlMode == ePositionControl)
         {
@@ -1361,7 +1442,10 @@ namespace armarx
 
             QModelIndex index = ui.tableJointList->model()->index(i, eTabelColumnAngleProgressbar);
             float conversionFactor =
-                ui.checkBoxUseDegree->isChecked() && node->isRotationalJoint() ? 180.0 / M_PI : 1;
+                ui.checkBoxUseDegree->isChecked() &&
+                        (node->isRotationalJoint() or node->isHemisphereJoint() or node->isFourBarJoint())
+                    ? 180.0 / M_PI
+                    : 1;
             ui.tableJointList->model()->setData(
                 index,
                 (int)(cutJitter(currentValue * conversionFactor) * 100) / 100.0f,
@@ -1401,7 +1485,8 @@ namespace armarx
             }
 
             float currentValue = it->second;
-            if (ui.checkBoxUseDegree->isChecked() && rn[i]->isRotationalJoint())
+            if (ui.checkBoxUseDegree->isChecked() &&
+                (rn[i]->isRotationalJoint() or rn[i]->isHemisphereJoint() or rn[i]->isFourBarJoint()))
             {
                 currentValue *= 180.0 / M_PI;
             }
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
index 01cb60a2d3a6cc716f4f36be94c92767cafc918e..a8dac1d2988b3f5e149338dae4f4657745554898 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
@@ -237,8 +237,8 @@ namespace armarx
         widget.treeWidgetSkills->clear();
         widget.treeWidgetSkillDetails->clear();
         skillsArgumentsTreeWidgetItem = nullptr;
-        selectedSkill.skillId.providerId->providerName = skills::SkillID::UNKNOWN;
-        selectedSkill.skillId.skillName = skills::SkillID::UNKNOWN;
+        selectedSkill.skillId.providerId->providerName = "";
+        selectedSkill.skillId.skillName = "";
     }
 
     void
@@ -311,9 +311,10 @@ namespace armarx
             {
                 auto description = skills::SkillDescription::FromIce(desc);
                 auto skillId = skills::SkillID::FromIce(sid);
-                auto providerId = skills::ProviderID(skillId);
+                auto providerId = skillId.providerId.value_or(
+                    skills::ProviderID{.providerName = "UNKNOWN PROVIDER NAME"});
 
-                ARMARX_CHECK(skillId.fullySpecified());
+                ARMARX_CHECK(skillId.isFullySpecified());
 
                 auto& providedSkillsMap = skills[providerId]; // create new if not existent
                 providedSkillsMap.insert({skillId, description});
@@ -325,7 +326,7 @@ namespace armarx
             {
                 auto* providerItem = widget.treeWidgetSkills->topLevelItem(i);
                 auto providerName = providerItem->text(0).toStdString();
-                skills::ProviderID providerId(providerName);
+                skills::ProviderID providerId{.providerName = providerName};
 
                 if (skills.find(providerId) == skills.end())
                 {
@@ -344,7 +345,9 @@ namespace armarx
                     auto* skillItem = providerItem->child(j);
                     auto skillName = skillItem->text(0).toStdString();
 
-                    skills::SkillID skillId(providerName, skillName);
+                    skills::SkillID skillId{.providerId =
+                                                skills::ProviderID{.providerName = providerName},
+                                            .skillName = skillName};
 
                     if (providedSkills.find(skillId) == providedSkills.end())
                     {
@@ -366,7 +369,7 @@ namespace armarx
                 {
                     auto el = widget.treeWidgetSkills->topLevelItem(i);
                     auto providerName = el->text(0).toStdString();
-                    skills::ProviderID elProviderId(providerName);
+                    skills::ProviderID elProviderId{.providerName = providerName};
 
                     if (providerId == elProviderId)
                     {
@@ -388,7 +391,7 @@ namespace armarx
                     {
                         auto el = providerItem->child(i);
                         auto skillName = el->text(0).toStdString();
-                        skills::SkillID elSkillId(providerId.providerName, skillName);
+                        skills::SkillID elSkillId{providerId, skillName};
 
                         if (skillId == elSkillId)
                         {
@@ -436,8 +439,9 @@ namespace armarx
         {
             std::scoped_lock l(updateMutex);
 
-            auto currentManagerStatuses = memory->getLatestSkillExecutionStatuses(
-                100); // we assume that there are no more than 100 new skills..
+            auto currentManagerStatuses =
+                memory
+                    ->getSkillExecutionStatuses(); // we assume that there are no more than 100 new skills..
 
             for (const auto& [k, v] : currentManagerStatuses)
             {
@@ -472,16 +476,16 @@ namespace armarx
                         // update values
                         //found->setText(3,
                         //               QString::fromStdString(
-                        //                   statusUpdate.hasBeenConstructed() ? " (\xfb) " : ""));
+                        //                   statusUpdate.hasBeenConstructed() ? " yes " : " no "));
                         found->setText(4,
                                        QString::fromStdString(
-                                           statusUpdate.hasBeenInitialized() ? " (\xfb) " : ""));
+                                           statusUpdate.hasBeenInitialized() ? " yes " : " no "));
                         found->setText(5,
                                        QString::fromStdString(
-                                           statusUpdate.hasBeenPrepared() ? " (\xfb) " : ""));
+                                           statusUpdate.hasBeenPrepared() ? " yes " : " no "));
                         found->setText(6,
                                        QString::fromStdString(
-                                           statusUpdate.hasBeenRunning() ? " (\xfb) " : ""));
+                                           statusUpdate.hasBeenRunning() ? " yes " : " no "));
                         found->setText(7,
                                        QString::fromStdString(
                                            statusUpdate.hasBeenTerminated() ? " (\xfb) " : ""));
@@ -549,12 +553,12 @@ namespace armarx
         char hostname[HOST_NAME_MAX];
         gethostname(hostname, HOST_NAME_MAX);
 
-        skills::SkillExecutionRequest req(selectedSkill.skillId,
+        skills::SkillExecutionRequest req{selectedSkill.skillId,
                                           "Skills.Manager GUI (hostname: " + std::string(hostname) +
                                               ")",
                                           params);
 
-        ARMARX_CHECK(selectedSkill.skillId.fullySpecified()); // sanity check
+        ARMARX_CHECK(selectedSkill.skillId.isFullySpecified()); // sanity check
         ARMARX_IMPORTANT << "Executing skill from GUI: " << selectedSkill.skillId << ".";
         // Note that we execute the skill in a seperate thread so that the GUI thread does not freeze.
         memory->begin_executeSkill(req.toManagerIce());
@@ -619,7 +623,9 @@ namespace armarx
 
         if (!current->parent())
         {
-            // no parent available. Perhaps provider clicked?
+            // no parent available. Perhaps provider clicked? Reset selected skill.
+            selectedSkill.skillId.providerId->providerName = "";
+            selectedSkill.skillId.skillName = "";
             return;
         }
 
@@ -645,7 +651,7 @@ namespace armarx
         skillsArgumentsTreeWidgetItem = nullptr;
 
         // We assert that the skill exists
-        ARMARX_CHECK(skills.count(selectedSkill.skillId) > 0);
+        ARMARX_CHECK(skills.count(*selectedSkill.skillId.providerId) > 0);
         ARMARX_CHECK(skills.at(*selectedSkill.skillId.providerId).count(selectedSkill.skillId) > 0);
         auto skillDesc = skills.at(*selectedSkill.skillId.providerId).at(selectedSkill.skillId);
 
@@ -686,8 +692,8 @@ namespace armarx
 
         skillsArgumentsTreeWidgetItem = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
                                                             {QString::fromStdString("Arguments")});
-        auto aron_args = skillDesc.acceptedType;
-        auto default_args_of_profile = skillDesc.rootProfileParameterization;
+        auto aron_args = skillDesc.parametersType;
+        auto default_args_of_profile = skillDesc.rootProfileDefaults;
 
         aronTreeWidgetController =
             std::make_shared<AronTreeWidgetController>(widget.treeWidgetSkillDetails,
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
index 2e52ed4cf4854583641d1a83f85822096d8f5226..5c3db21fbe8604c9842cb834565274a4294e6233 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
@@ -90,6 +90,16 @@ namespace armarx
         createdAron = createdAronDict;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         unsigned int x = 0;
         for (const auto& [key, value] : i->getMemberTypes())
         {
@@ -113,6 +123,16 @@ namespace armarx
         createdAron = createdAronDict;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         for (int x = 0; x < el->childCount(); ++x)
         {
             auto it = el->child(x);
@@ -134,12 +154,23 @@ namespace armarx
         ARMARX_TRACE;
         auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
         createdAron = createdAronList;
-        auto* elem = parentItem->child(index);
+        auto* el = parentItem->child(index);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         auto childrenTypes = i->getChildren();
         ARMARX_CHECK(childrenTypes.size() == 1);
-        for (int j = 0; j < elem->childCount(); ++j)
+        for (int j = 0; j < el->childCount(); ++j)
         {
-            AronTreeWidgetConverterVisitor convVisitor(elem, j);
+            AronTreeWidgetConverterVisitor convVisitor(el, j);
             aron::type::visit(convVisitor, childrenTypes[0]);
             handleErrors(convVisitor);
 
@@ -156,11 +187,21 @@ namespace armarx
         ARMARX_TRACE;
         auto createdAronPair = std::make_shared<aron::data::List>(i->getPath());
         createdAron = createdAronPair;
-        auto* elem = parentItem->child(index);
+        auto* el = parentItem->child(index);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
 
         for (int j = 0; j < 2; ++j)
         {
-            AronTreeWidgetConverterVisitor convVisitor(elem, j);
+            AronTreeWidgetConverterVisitor convVisitor(el, j);
             handleErrors(convVisitor);
             if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
             {
@@ -177,6 +218,16 @@ namespace armarx
         createdAron = createdAronList;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         for (int x = 0; x < el->childCount(); ++x)
         {
             auto* it = el->child(x);
@@ -242,11 +293,22 @@ namespace armarx
         createdMatrix->setShape({i->getRows(), i->getCols(), dataSize});
         int totalByteSize = i->getRows() * i->getCols() * dataSize;
         createdAron = createdMatrix;
+        auto* el = parentItem->child(index);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
 
-        auto* currElem = parentItem->child(index);
-        auto* rootWidget = currElem->treeWidget();
+
+        auto* rootWidget = el->treeWidget();
         ARMARX_CHECK(rootWidget);
-        auto* widget = rootWidget->itemWidget(currElem, 1);
+        auto* widget = rootWidget->itemWidget(el, 1);
         auto* matrixWidget = EditMatrixWidget::DynamicCastAndCheck(widget);
 
         handleErrors(matrixWidget->hasParseErrors());
@@ -280,8 +342,19 @@ namespace armarx
         int dataSize = i->getElementType() == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8;
         createdQuat->setShape({1, 4, dataSize});
         createdQuat->setType(i->getFullName());
-        auto* currTreeElem = parentItem->child(index);
-        auto* itemWidget = currTreeElem->treeWidget()->itemWidget(currTreeElem, 1);
+        auto* el = parentItem->child(index);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
+        auto* itemWidget = el->treeWidget()->itemWidget(el, 1);
         auto* quatWidget = QuaternionWidget::DynamicCastAndCheck(itemWidget);
 
         // error handling
@@ -320,6 +393,17 @@ namespace armarx
     {
         ARMARX_TRACE;
         QTreeWidgetItem* el = parentItem->child(index);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         auto* genericWidget = el->treeWidget()->itemWidget(el, 1);
         auto* intEnumWidget = IntEnumWidget::DynamicCastAndCheck(genericWidget);
         if (!intEnumWidget)
@@ -341,6 +425,16 @@ namespace armarx
         createdAron = createdAronInt;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         std::string str = el->text(1).toStdString();
         if (str.empty())
         {
@@ -370,6 +464,16 @@ namespace armarx
         createdAron = createdAronLong;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         std::string str = el->text(1).toStdString();
         if (str.empty())
         {
@@ -398,6 +502,16 @@ namespace armarx
         createdAron = createdAronFloat;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         std::string str = el->text(1).toStdString();
         if (str.empty())
         {
@@ -425,6 +539,16 @@ namespace armarx
         createdAron = createdAronDouble;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         std::string str = el->text(1).toStdString();
         if (str.empty())
         {
@@ -452,6 +576,16 @@ namespace armarx
         createdAron = createdAronBool;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         std::string str = el->text(1).toStdString();
         if (str.empty())
         {
@@ -479,6 +613,16 @@ namespace armarx
         createdAron = createdAronString;
         QTreeWidgetItem* el = parentItem->child(index);
 
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            // its a maybetype. We have to check the state
+            if (el->checkState(1) == Qt::CheckState::Unchecked)
+            {
+                createdAron = nullptr;
+                return;
+            }
+        }
+
         std::string str = el->text(1).toStdString();
         createdAronString->setValue(str);
     }
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp
index 84cb58585e3b4e7f3a058db66f3b5f3a40f54aea..5bc5a40bbd407c104ce96905850e9d0beabecb48 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp
@@ -101,6 +101,11 @@ namespace armarx
 
         createdQWidgetItem =
             new AronTreeWidgetItem(isDictChild, editableValue, QString::fromStdString(key), i);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            createdQWidgetItem->setCheckState(1, Qt::CheckState::Unchecked);
+        }
         createdQWidgetItem->setText(1, QString::fromStdString(defaul));
         createdQWidgetItem->setText(2, QString::fromStdString(i->getShortName()));
         createdQWidgetItem->setText(
@@ -129,6 +134,12 @@ namespace armarx
 
         createdQWidgetItem =
             new AronTreeWidgetItem(editableValue, false, QString::fromStdString(key), i);
+
+        if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            createdQWidgetItem->setCheckState(1, Qt::CheckState::Unchecked);
+        }
+
         parentOfCreatedObj->addChild(createdQWidgetItem);
 
         for (const auto& [key, value] : i->getMemberTypes())
@@ -149,6 +160,7 @@ namespace armarx
         // The DictType has only one member, its key-type. This also must be present
         ARMARX_CHECK_EQUAL(i->getChildren().size(), 1);
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PairPtr& pair)
     {
@@ -167,6 +179,7 @@ namespace armarx
             }
         }
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& tuple)
     {
@@ -185,6 +198,7 @@ namespace armarx
             }
         }
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::ListPtr& i)
     {
@@ -192,6 +206,7 @@ namespace armarx
         auto txt = misc::generateNumElementsText(0);
         createdQWidgetItem->setText(1, txt);
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::NDArrayPtr& i)
     {
@@ -233,6 +248,7 @@ namespace armarx
             i->getRows(), i->getCols(), i->getElementType(), createdQWidgetItem);
         toplevelWidget->setItemWidget(createdQWidgetItem, 1, matWidget);
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::QuaternionPtr& i)
     {
@@ -257,16 +273,19 @@ namespace armarx
             new QuaternionWidget(i->getElementType(), createdQWidgetItem);
         toplevelWidget->setItemWidget(createdQWidgetItem, 1, quatWidget);
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::ImagePtr& i)
     {
         insertNewTreeViewWidget(i, "");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PointCloudPtr& i)
     {
         insertNewTreeViewWidget(i, "");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::IntEnumPtr& i)
     {
@@ -278,36 +297,42 @@ namespace armarx
         IntEnumWidget* widget = new IntEnumWidget(i, createdQWidgetItem);
         createdQWidgetItem->treeWidget()->setItemWidget(createdQWidgetItem, 1, widget);
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::IntPtr& i)
     {
         editableValue = true;
         insertNewTreeViewWidget(i, "0");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::LongPtr& i)
     {
         editableValue = true;
         insertNewTreeViewWidget(i, "0");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::FloatPtr& i)
     {
         editableValue = true;
         insertNewTreeViewWidget(i, "0.0");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::DoublePtr& i)
     {
         editableValue = true;
         insertNewTreeViewWidget(i, "0.0");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::BoolPtr& i)
     {
         editableValue = true;
         insertNewTreeViewWidget(i, "false");
     }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::StringPtr& i)
     {
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
index cf719f8a2d1360d574fb8ebcac867378c3fd6f1b..cafc9b499b45a587efcc7a52ca531e028a8391df 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
@@ -31,7 +31,6 @@
 #include "AronTreeWidgetContextMenu.h"
 #include "AronTreeWidgetCreator.h"
 
-
 template <typename T>
 std::string
 usString(T number, size_t precision = 3)
@@ -44,7 +43,6 @@ usString(T number, size_t precision = 3)
     return ss.str();
 }
 
-
 //visitors
 namespace armarx
 {
@@ -101,7 +99,6 @@ namespace armarx
         }
     }
 
-
     void
     AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::DictPtr& i)
     {
@@ -109,7 +106,7 @@ namespace armarx
         if (i->getPath().size() == 0 ||
             checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
             // allocate enough child items
             adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
@@ -123,7 +120,11 @@ namespace armarx
                 AronTreeWidgetSetterVisitor v(el, x++);
                 aron::data::visit(v, value);
             }
-            return;
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
@@ -132,7 +133,7 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
             adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
 
@@ -154,10 +155,14 @@ namespace armarx
             auto currFont = aronTreeWidget->font(1);
             currFont.setItalic(true);
             aronTreeWidget->setFont(1, currFont);
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
-
     void
     visitMatrix(EditMatrixWidget* matrixWidget,
                 const std::shared_ptr<armarx::aron::type::Matrix>& matrixType,
@@ -215,6 +220,7 @@ namespace armarx
             }
         }
     }
+
     void
     visitQuaternion(QuaternionWidget* quatWidget,
                     std::shared_ptr<armarx::aron::type::Quaternion>& quatType,
@@ -256,16 +262,16 @@ namespace armarx
     AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::NDArrayPtr& arr)
     {
         // Matrices are handled as NDArray. Raw ndarrays cannot be created currently
-        auto* castedEl = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
-        ARMARX_CHECK(castedEl);
+        auto* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
+        ARMARX_CHECK(el);
 
-        auto matrixCast = aron::type::Matrix::DynamicCast(castedEl->aronType);
-        auto quaternionCast = aron::type::Quaternion::DynamicCast(castedEl->aronType);
+        auto matrixCast = aron::type::Matrix::DynamicCast(el->aronType);
+        auto quaternionCast = aron::type::Quaternion::DynamicCast(el->aronType);
 
-        auto* rootWidget = castedEl->treeWidget();
+        auto* rootWidget = el->treeWidget();
         ARMARX_CHECK(rootWidget);
-        auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(castedEl, 1));
-        auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(castedEl, 1));
+        auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(el, 1));
+        auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(el, 1));
 
         if (matrixCast && matrixWidget)
         {
@@ -280,6 +286,11 @@ namespace armarx
             ARMARX_ERROR
                 << "we do not support raw NDArrays. Ask Fabian Peller for more information.";
         }
+
+        if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+        {
+            el->setCheckState(1, Qt::CheckState::Checked);
+        }
     }
 
     void
@@ -287,7 +298,7 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             auto* enumWidget = IntEnumWidget::DynamicCast(el->treeWidget()->itemWidget(el, 1));
             auto newText = QString::fromStdString(usString<int>(i->getValue()));
             if (enumWidget)
@@ -300,6 +311,11 @@ namespace armarx
                 // Its just an int. -> do the QTreeWidgetItem call
                 el->setText(1, newText);
             }
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
@@ -308,8 +324,13 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             el->setText(1, QString::fromStdString(usString<long>(i->getValue())));
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
@@ -318,8 +339,13 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             el->setText(1, QString::fromStdString(usString<float>(i->getValue())));
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
@@ -328,8 +354,13 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             el->setText(1, QString::fromStdString(usString<double>(i->getValue())));
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
@@ -338,8 +369,13 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             el->setText(1, QString::fromStdString(usString<bool>(i->getValue())));
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
@@ -348,8 +384,13 @@ namespace armarx
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
-            QTreeWidgetItem* el = parentItem->child(index);
+            AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
             el->setText(1, QString::fromStdString(i->getValue()));
+
+            if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE)
+            {
+                el->setCheckState(1, Qt::CheckState::Checked);
+            }
         }
     }
 
diff --git a/source/RobotAPI/interface/skills/SkillManagerInterface.ice b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
index b2c3b5deba9aa8239023d4559b6d20405e5b0889..f22738bda8b71cac09faf71620e226135ac93532 100644
--- a/source/RobotAPI/interface/skills/SkillManagerInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
@@ -49,8 +49,8 @@ module armarx
                     SkillID skillId;
                     string description;
                     armarx::core::time::dto::Duration timeout;
-                    aron::type::dto::AronObject acceptedType;
-                    aron::type::dto::AronObject returnType;
+                    aron::type::dto::AronObject parametersType;
+                    aron::type::dto::AronObject resultType;
                     aron::data::dto::Dict rootProfileDefaults;
                 };
 
@@ -74,10 +74,10 @@ module armarx
                 struct SkillStatusUpdate
                 {
                     SkillExecutionID executionId;
-                    aron::data::dto::Dict usedParams;
-                    callback::dti::SkillProviderCallbackInterface* usedCallbackInterface;
+                    aron::data::dto::Dict parameters;
+                    callback::dti::SkillProviderCallbackInterface* callbackInterface;
                     core::dto::Execution::Status status;
-                    aron::data::dto::Dict data;
+                    aron::data::dto::Dict result;
                 };
 
                 dictionary<SkillExecutionID, SkillStatusUpdate> SkillStatusUpdateMap;
@@ -86,7 +86,7 @@ module armarx
                 {
                     SkillID skillId;
                     string executorName;
-                    aron::data::dto::Dict params;
+                    aron::data::dto::Dict parameters;
                 };
             }
 
@@ -99,7 +99,7 @@ module armarx
 
                     void addProvider(dto::ProviderInfo providerInfo);
 
-                    void removeProvider(dto::ProviderID provider);
+                    void removeProvider(dto::ProviderID providerId);
 
                     optional(1) dto::SkillDescription getSkillDescription(
                         dto::SkillID skillId); // get one skilldescriptions from a provider
@@ -115,16 +115,20 @@ module armarx
 
                     dto::SkillStatusUpdate
                     executeSkill(dto::SkillExecutionRequest
-                                     skillExecutionInfo); // blocks until skill is finished.
+                                     skillExecutionRequest); // blocks until skill is finished.
 
                     dto::SkillExecutionID executeSkillAsync(
                         dto::SkillExecutionRequest
                             skillExecutionRequest); // directly returns the execution id
 
-                    void addSkillParameters(dto::SkillExecutionID executionId,
-                                            aron::data::dto::Dict params); // add params to a skill
+                    provider::dto::ParameterUpdateResult updateSkillParameters(
+                        dto::SkillExecutionID executionId,
+                        aron::data::dto::Dict parameters); // add params to a skill
 
-                    void abortSkill(dto::SkillExecutionID execId); // notify a skill to stop ASAP.
+                    // notify a skill to stop ASAP.
+                    provider::dto::AbortSkillResult abortSkill(dto::SkillExecutionID executionId);
+                    provider::dto::AbortSkillResult
+                    abortSkillAsync(dto::SkillExecutionID executionId);
                 };
             }
         }
diff --git a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
index 934d2fabaf539697a8416f4567c734e36de25858..3d0d8ee61b23a5e184514b87792323d379c81173 100644
--- a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
@@ -36,11 +36,7 @@ module armarx
         module dti
         {
             interface SkillMemoryInterface extends armem::server::MemoryInterface,
-                dti::StatechartListenerInterface, manager::dti::SkillManagerInterface
-            {
-                manager::dto::SkillStatusUpdateMap getLatestSkillExecutionStatuses(
-                    int n); // returns latest n statusupdates of all providers
-            };
+                dti::StatechartListenerInterface, manager::dti::SkillManagerInterface{};
         }
     }
 }
diff --git a/source/RobotAPI/interface/skills/SkillProviderInterface.ice b/source/RobotAPI/interface/skills/SkillProviderInterface.ice
index 80a8a97fbdb9f6eff8f19cfaf1384338748c6232..3066c962e45326fecfdf8f08c6985bb89bf6c3d7 100644
--- a/source/RobotAPI/interface/skills/SkillProviderInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillProviderInterface.ice
@@ -58,9 +58,6 @@ module armarx
         {
             module dto
             {
-
-                sequence<string> StringList;
-
                 // The status enum of a skill
                 module Execution
                 {
@@ -77,11 +74,6 @@ module armarx
                         Aborted
                     };
                 }
-
-                // Status updates of a skill
-                class SkillStatusUpdateBase
-                {
-                };
             }
         }
     }
@@ -123,8 +115,8 @@ module armarx
                     SkillID skillId;
                     string description;
                     armarx::core::time::dto::Duration timeout;
-                    aron::type::dto::AronObject acceptedType;
-                    aron::type::dto::AronObject returnType;
+                    aron::type::dto::AronObject parametersType;
+                    aron::type::dto::AronObject resultType;
                     aron::data::dto::Dict rootProfileDefaults;
                 };
 
@@ -135,7 +127,7 @@ module armarx
                 {
                     SkillID skillId;
                     string executorName;
-                    aron::data::dto::Dict params;
+                    aron::data::dto::Dict parameters;
                     callback::dti::SkillProviderCallbackInterface* callbackInterface;
                 };
 
@@ -152,13 +144,25 @@ module armarx
                 struct SkillStatusUpdate
                 {
                     SkillExecutionID executionId;
-                    aron::data::dto::Dict usedParams;
-                    callback::dti::SkillProviderCallbackInterface* usedCallbackInterface;
+                    aron::data::dto::Dict parameters;
+                    callback::dti::SkillProviderCallbackInterface* callbackInterface;
                     core::dto::Execution::Status status;
-                    aron::data::dto::Dict data;
+                    aron::data::dto::Dict result;
+                    /// @todo maybe add in future:
+                    // aron::data::dto::Dict feedback;
                 };
 
                 dictionary<SkillExecutionID, SkillStatusUpdate> SkillStatusUpdateMap;
+
+                struct ParameterUpdateResult
+                {
+                    bool success; // false if skill is not running (anymore) or already prepared
+                };
+
+                struct AbortSkillResult
+                {
+                    bool success; // false if skill is not running (anymore)
+                };
             }
 
             module dti
@@ -183,11 +187,13 @@ module armarx
                     dto::SkillExecutionID
                     executeSkillAsync(dto::SkillExecutionRequest executionInfo);
 
-                    void addSkillParameters(dto::SkillExecutionID executionId,
-                                            aron::data::dto::Dict params); // add params to a skill
+                    dto::ParameterUpdateResult
+                    updateSkillParameters(dto::SkillExecutionID executionId,
+                                          aron::data::dto::Dict params); // add params to a skill
 
                     // try to kill a skill as soon as possible. When the skill is stopped depends on the implementation.
-                    void abortSkill(dto::SkillExecutionID skill);
+                    dto::AbortSkillResult abortSkill(dto::SkillExecutionID skill);
+                    dto::AbortSkillResult abortSkillAsync(dto::SkillExecutionID skill);
                 };
             }
         }
diff --git a/source/RobotAPI/interface/units/GamepadUnit.ice b/source/RobotAPI/interface/units/GamepadUnit.ice
index 671e1de9b99591f0d4e23ab923feac8a5e1d535d..c63ddcfdad36942cfcca6c65155c8e96c6847f79 100644
--- a/source/RobotAPI/interface/units/GamepadUnit.ice
+++ b/source/RobotAPI/interface/units/GamepadUnit.ice
@@ -62,8 +62,9 @@ module armarx
         bool rightStickButton;
 
     };
-    interface GamepadUnitInterface extends armarx::SensorActorUnitInterface
+    interface GamepadUnitInterface // extends armarx::SensorActorUnitInterface
     {
+        void vibrate();
     };
 
     interface GamepadUnitListener
@@ -78,4 +79,3 @@ module armarx
     };
 
 };
-
diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp
index 4e14baacb6040f7bf97a4855d3da7e4d252bce03..0eecc8e79de97cb3e164b195dd43cedc57b789cf 100644
--- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp
+++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.cpp
@@ -10,13 +10,12 @@
 
 namespace armarx::armem
 {
-    GraspCandidateReader::GraspCandidateReader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
+    GraspCandidateReader::GraspCandidateReader()
     {
     }
 
     void
-    GraspCandidateReader::connect(bool use)
+    GraspCandidateReader::connect(armem::client::MemoryNameSystem& memoryNameSystem, bool use)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "GraspCandidateReader: Waiting for memory '" << properties.memoryName
diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h
index 384f5cdb0c1158b714ba8b3038e09f4707dd74bb..4b7bba78baae8c78c7c37fdc77ebdaff8e6fd154 100644
--- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h
+++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateReader.h
@@ -12,9 +12,9 @@ namespace armarx::armem
     class GraspCandidateReader
     {
     public:
-        GraspCandidateReader(armem::client::MemoryNameSystem& memoryNameSystem);
+        GraspCandidateReader();
 
-        void connect(bool use = true);
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem, bool use = true);
 
         ::armarx::grasping::GraspCandidatePtr
         queryGraspCandidateInstanceByID(armem::MemoryID const& id) const;
@@ -65,8 +65,6 @@ namespace armarx::armem
         } properties;
 
         const std::string propertyPrefix = "mem.grasping.";
-
-        armem::client::MemoryNameSystem& memoryNameSystem;
     };
 
 } // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.cpp b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.cpp
index 7aa20ba28af1b49404118cfedb3abd006d784738..1f14e344ee988f984813e2a402903cfb0627b940 100644
--- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.cpp
+++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.cpp
@@ -6,16 +6,11 @@
 #include <RobotAPI/libraries/GraspingUtility/aron_conversions.h>
 #include <RobotAPI/libraries/armem/core/error/mns.h>
 
-
 namespace armarx::armem
 {
 
-    GraspCandidateWriter::GraspCandidateWriter(armem::client::MemoryNameSystem& memoryNameSystem)
-        : memoryNameSystem(memoryNameSystem)
-    {
-    }
-
-    void GraspCandidateWriter::connect()
+    void
+    GraspCandidateWriter::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "GraspCandidateWriter: Waiting for memory '" << properties.memoryName
@@ -23,33 +18,37 @@ namespace armarx::armem
         try
         {
             memoryWriter = memoryNameSystem.useWriter(properties.memoryName);
-            ARMARX_IMPORTANT << "GraspCandidateWriter: Connected to memory '" << properties.memoryName << "'";
+            ARMARX_IMPORTANT << "GraspCandidateWriter: Connected to memory '"
+                             << properties.memoryName << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
             ARMARX_ERROR << e.what();
             return;
         }
-
     }
 
-    void GraspCandidateWriter::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+    void
+    GraspCandidateWriter::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
         ARMARX_DEBUG << "GraspCandidateWriter: registerPropertyDefinitions";
 
         const std::string prefix = propertyPrefix;
 
-        def->optional(properties.graspMemoryName, prefix + "GraspMemoryName",
+        def->optional(properties.graspMemoryName,
+                      prefix + "GraspMemoryName",
                       "Name of the grasping memory core segment to use.");
-        def->optional(properties.bimanualGraspMemoryName, prefix + "BimanualGraspMemoryName",
+        def->optional(properties.bimanualGraspMemoryName,
+                      prefix + "BimanualGraspMemoryName",
                       "Name of the bimanual grasping memory core segment to use.");
 
         def->optional(properties.memoryName, prefix + "MemoryName");
-
     }
 
-    bool GraspCandidateWriter::commitGraspCandidate(const armarx::grasping::GraspCandidate& candidate,
-            const armem::Time& timestamp, const std::string& provider)
+    bool
+    GraspCandidateWriter::commitGraspCandidate(const armarx::grasping::GraspCandidate& candidate,
+                                               const armem::Time& timestamp,
+                                               const std::string& provider)
     {
         armarx::grasping::arondto::GraspCandidate aronGraspCandidate;
         std::string objectName = "UnknownObject";
@@ -65,8 +64,11 @@ namespace armarx::armem
         return commitToMemory({dict}, provider, objectName, timestamp, properties.graspMemoryName);
     }
 
-    bool GraspCandidateWriter::commitBimanualGraspCandidate(const armarx::grasping::BimanualGraspCandidate& candidate,
-            const armem::Time& timestamp, const std::string& provider)
+    bool
+    GraspCandidateWriter::commitBimanualGraspCandidate(
+        const armarx::grasping::BimanualGraspCandidate& candidate,
+        const armem::Time& timestamp,
+        const std::string& provider)
     {
         armarx::grasping::arondto::BimanualGraspCandidate aronGraspCandidate;
 
@@ -80,11 +82,15 @@ namespace armarx::armem
 
         auto dict = aronGraspCandidate.toAron();
 
-        return commitToMemory({dict}, provider, objectName, timestamp, properties.bimanualGraspMemoryName);
+        return commitToMemory(
+            {dict}, provider, objectName, timestamp, properties.bimanualGraspMemoryName);
     }
 
-    bool GraspCandidateWriter::commitGraspCandidateSeq(const armarx::grasping::GraspCandidateSeq& candidates,
-            const armem::Time& timestamp, const std::string& provider)
+    bool
+    GraspCandidateWriter::commitGraspCandidateSeq(
+        const armarx::grasping::GraspCandidateSeq& candidates,
+        const armem::Time& timestamp,
+        const std::string& provider)
     {
 
         bool success = true;
@@ -107,7 +113,7 @@ namespace armarx::armem
         for (const auto& [key, dict] : updates)
         {
 
-            if (! commitToMemory(dict, provider, key, timestamp, properties.graspMemoryName))
+            if (!commitToMemory(dict, provider, key, timestamp, properties.graspMemoryName))
             {
                 success = false;
             }
@@ -115,8 +121,10 @@ namespace armarx::armem
         return success;
     }
 
-    bool GraspCandidateWriter::commitBimanualGraspCandidateSeq(
-        const armarx::grasping::BimanualGraspCandidateSeq& candidates, const armem::Time& timestamp,
+    bool
+    GraspCandidateWriter::commitBimanualGraspCandidateSeq(
+        const armarx::grasping::BimanualGraspCandidateSeq& candidates,
+        const armem::Time& timestamp,
         const std::string& provider)
     {
         bool success = true;
@@ -138,7 +146,7 @@ namespace armarx::armem
         for (const auto& [key, dict] : updates)
         {
 
-            if (! commitToMemory(dict, provider, key, timestamp, properties.bimanualGraspMemoryName))
+            if (!commitToMemory(dict, provider, key, timestamp, properties.bimanualGraspMemoryName))
             {
                 success = false;
             }
@@ -146,14 +154,16 @@ namespace armarx::armem
         return success;
     }
 
-    bool GraspCandidateWriter::commitToMemory(const std::vector<armarx::aron::data::DictPtr>& instances,
-            const std::string& providerName, const std::string& entityName, const armem::Time& timestamp,
-            const std::string& coreMemoryName)
+    bool
+    GraspCandidateWriter::commitToMemory(const std::vector<armarx::aron::data::DictPtr>& instances,
+                                         const std::string& providerName,
+                                         const std::string& entityName,
+                                         const armem::Time& timestamp,
+                                         const std::string& coreMemoryName)
     {
         std::lock_guard g{memoryWriterMutex};
 
-        const auto result =
-            memoryWriter.addSegment(coreMemoryName, providerName);
+        const auto result = memoryWriter.addSegment(coreMemoryName, providerName);
 
         if (not result.success)
         {
@@ -164,8 +174,7 @@ namespace armarx::armem
         }
 
         const auto providerId = armem::MemoryID(result.segmentID);
-        const auto entityID =
-            providerId.withEntityName(entityName).withTimestamp(timestamp);
+        const auto entityID = providerId.withEntityName(entityName).withTimestamp(timestamp);
 
         armem::EntityUpdate update;
         update.entityID = entityID;
@@ -184,4 +193,4 @@ namespace armarx::armem
 
         return updateResult.success;
     }
-}
+} // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.h b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.h
index 88793cb534cb18af0fefddcd72be4215eaa70e2b..526f16b0ae327f6e3465c7adfc3d2c1c7fb1b26b 100644
--- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.h
+++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateWriter.h
@@ -1,58 +1,60 @@
 #pragma once
 
-#include <RobotAPI/libraries/armem/client/Writer.h>
-#include <RobotAPI/libraries/armem/client.h>
 #include <mutex>
 
-#include <RobotAPI/interface/units/GraspCandidateProviderInterface.h>
 #include <ArmarXCore/core/application/properties/forward_declarations.h>
 
+#include <RobotAPI/interface/units/GraspCandidateProviderInterface.h>
+#include <RobotAPI/libraries/armem/client.h>
+#include <RobotAPI/libraries/armem/client/Writer.h>
+
 namespace armarx::armem
 {
     class GraspCandidateWriter
     {
     public:
-        GraspCandidateWriter(armem::client::MemoryNameSystem& memoryNameSystem);
+        GraspCandidateWriter() = default;
 
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
 
         bool commitGraspCandidate(const armarx::grasping::GraspCandidate& candidate,
-                                  const armem::Time& timestamp, const std::string& provider);
+                                  const armem::Time& timestamp,
+                                  const std::string& provider);
         bool commitBimanualGraspCandidate(const armarx::grasping::BimanualGraspCandidate& candidate,
-                                          const armem::Time& timestamp, const std::string& provider);
+                                          const armem::Time& timestamp,
+                                          const std::string& provider);
 
         bool commitGraspCandidateSeq(const armarx::grasping::GraspCandidateSeq& candidates,
-                                     const armem::Time& timestamp, const std::string& provider);
-        bool commitBimanualGraspCandidateSeq(const armarx::grasping::BimanualGraspCandidateSeq& candidates,
-                                             const armem::Time& timestamp, const std::string& provider);
-
+                                     const armem::Time& timestamp,
+                                     const std::string& provider);
+        bool commitBimanualGraspCandidateSeq(
+            const armarx::grasping::BimanualGraspCandidateSeq& candidates,
+            const armem::Time& timestamp,
+            const std::string& provider);
 
 
     private:
-
         bool commitToMemory(const std::vector<armarx::aron::data::DictPtr>& instances,
-                            const std::string& providerName, const std::string& entityName, const armem::Time& timestamp,
+                            const std::string& providerName,
+                            const std::string& entityName,
+                            const armem::Time& timestamp,
                             const std::string& coreMemoryName);
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
-
         armem::client::Writer memoryWriter;
 
         struct Properties
         {
-            std::string memoryName         = "Grasp";
-            std::string graspMemoryName  = "GraspCandidate";
+            std::string memoryName = "Grasp";
+            std::string graspMemoryName = "GraspCandidate";
             std::string bimanualGraspMemoryName = "BimanualGraspCandidate";
         } properties;
 
-
         std::mutex memoryWriterMutex;
 
         const std::string propertyPrefix = "mem.grasping.";
-
     };
 
 
-}
+} // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/CMakeLists.txt b/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/CMakeLists.txt
index e3467eb9a250af792c5c53d578b0555b49a95efa..ce15a37df98b729bd0a0dc875ccbac13aae2108f 100644
--- a/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/CMakeLists.txt
+++ b/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/CMakeLists.txt
@@ -8,12 +8,17 @@ armarx_add_library(
         SimoxUtility
         RobotAPI::Core
         RobotAPI::Aron::Common
+
+        ArViz
+        RobotAPIArmarXObjects
     SOURCES
         datatypes/CommonPlace.cpp
         CommonPlaceLoader.cpp
+        Visu.cpp
     HEADERS
         datatypes/CommonPlace.h
         CommonPlaceLoader.h
+        Visu.h
 )
 
 add_library(${PROJECT_NAME}::PriorKnowledge::util::CommonPlaceLoader ALIAS ${PROJECT_NAME}PriorKnowledgeCommonPlaceLoaderUtil)
diff --git a/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/Visu.cpp b/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/Visu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfd68864ff87c6490af33be5d40645051b0e4fe7
--- /dev/null
+++ b/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/Visu.cpp
@@ -0,0 +1,24 @@
+#include "Visu.h"
+
+#include <ArmarXCore/core/logging/Logging.h>
+
+#include <RobotAPI/libraries/ArmarXObjects/ObjectID.h>
+
+namespace armarx::priorknowledge::util::common_place
+{
+    viz::Layer
+    Visu::commonPlaceToLayer(const std::string& layerName,
+                             const std::map<std::string, CommonPlaceData>& commonPlaceData) const
+    {
+        auto layer = arviz.layer(layerName);
+        for (auto& [id, data] : commonPlaceData)
+        {
+            auto o = armarx::viz::Object("");
+            o = o.fileByObjectFinder(armarx::ObjectID(data.objectId));
+            o.pose(data.globalPose).alpha(0.5);
+            layer.add(o);
+        }
+        return layer;
+    }
+
+} // namespace armarx::priorknowledge::util::common_place
diff --git a/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/Visu.h b/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/Visu.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4df667ca056b92db65053834a1fea75b75d8eb9
--- /dev/null
+++ b/source/RobotAPI/libraries/PriorKnowledge/util/CommonPlaceLoader/Visu.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <RobotAPI/components/ArViz/Client/Client.h>
+#include <RobotAPI/components/ArViz/Client/ScopedClient.h>
+
+#include "datatypes/CommonPlace.h"
+
+namespace armarx::priorknowledge::util::common_place
+{
+
+    class Visu
+    {
+    public:
+        struct CommonPlaceData
+        {
+            Eigen::Matrix4f globalPose;
+            std::string objectId;
+        };
+
+        Visu(viz::Client& arviz) : arviz(arviz)
+
+        {
+        }
+
+        ~Visu() = default;
+
+        viz::Layer commonPlaceToLayer(const std::string& layerName,
+                                      const std::map<std::string, CommonPlaceData>& data) const;
+
+
+    public:
+        struct Settings
+        {
+
+        } settings;
+
+    protected:
+        viz::Client& arviz;
+    };
+} // namespace armarx::priorknowledge::util::common_place
diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 676c1fd0752baf0c2995e479dfad2cca4f3d9960..9030bd17597399abf79e3413ec71a789f3a113ca 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -57,12 +57,14 @@ set(LIB_FILES
     client/MemoryNameSystem.cpp
     client/Reader.cpp
     client/Writer.cpp
+    client/ReadStream.cpp
 
     client/plugins/ListeningPluginUser.cpp
     client/plugins/ListeningPlugin.cpp
     client/plugins/PluginUser.cpp
     client/plugins/Plugin.cpp
 
+    client/util/SubscriptionHandle.cpp
     client/util/MemoryListener.cpp
     client/util/SimpleReaderBase.cpp
     client/util/SimpleWriterBase.cpp
@@ -138,6 +140,7 @@ set(LIB_HEADERS
     client/MemoryNameSystem.h
     client/Reader.h
     client/Writer.h
+    client/ReadStream.h
 
     client/plugins.h
     client/plugins/ListeningPluginUser.h
@@ -154,6 +157,7 @@ set(LIB_HEADERS
     client/query/detail/NameSelectorOps.h
     client/query/detail/SelectorOps.h
 
+    client/util/SubscriptionHandle.h
     client/util/MemoryListener.h
     client/util/SimpleReaderBase.h
     client/util/SimpleWriterBase.h
diff --git a/source/RobotAPI/libraries/armem/client/ReadStream.cpp b/source/RobotAPI/libraries/armem/client/ReadStream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..688357958419900abbea45f85b2c35cf4868f26f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/ReadStream.cpp
@@ -0,0 +1,172 @@
+#include "ReadStream.h"
+
+#include <ArmarXCore/core/time/Clock.h>
+
+#include <RobotAPI/libraries/armem/client/query/Builder.h>
+
+namespace armarx::armem::client
+{
+    ReadStream::ReadStream() : metronome{armarx::core::time::Frequency::Hertz(10)}
+    {
+    }
+
+    ReadStream::ReadStream(const Reader& reader,
+                           const MemoryID& queriedId,
+                           const core::time::Frequency& maxPollFrequency) :
+        reader{reader}, queriedId{queriedId}, metronome{maxPollFrequency}
+    {
+        timeStart = armarx::core::time::Clock::Now();
+    }
+
+    std::optional<wm::EntitySnapshot>
+    ReadStream::pollBlocking(const SnapshotCallbackT& callback)
+    {
+        if (isPolling.exchange(true))
+        {
+            throw armarx::armem::error::ReadStreamAlreadyPolling(queriedId, __PRETTY_FUNCTION__);
+        }
+        pollingStoppedExternally = false;
+
+        auto result = _pollBlocking(callback);
+
+        isPolling = false;
+        return result;
+    }
+
+    void
+    ReadStream::pollAsync(const SnapshotCallbackT& callback)
+    {
+        if (isPolling.exchange(true))
+        {
+            throw armarx::armem::error::ReadStreamAlreadyPolling(queriedId, __PRETTY_FUNCTION__);
+        }
+        pollingStoppedExternally = false;
+
+        this->pollingThread = std::thread([&]() { this->_pollBlocking(callback); });
+    }
+
+    std::optional<wm::EntitySnapshot>
+    ReadStream::_pollBlocking(const SnapshotCallbackT& callback)
+    {
+        while (not pollingStoppedExternally)
+        {
+            auto snapshot = _pollOnce(callback);
+            if (snapshot.has_value())
+            {
+                return snapshot;
+            }
+        }
+        return std::nullopt;
+    }
+
+    void
+    ReadStream::stop()
+    {
+        pollingStoppedExternally = true;
+        if (pollingThread.joinable())
+        {
+            pollingThread.join();
+            isPolling = false;
+        }
+    }
+
+    std::optional<wm::EntitySnapshot>
+    ReadStream::pollOnce(const SnapshotCallbackT& callback)
+    {
+        if (isPolling.exchange(true))
+        {
+            throw armarx::armem::error::ReadStreamAlreadyPolling(queriedId, __PRETTY_FUNCTION__);
+        }
+
+        auto snapshot = _pollOnce(callback);
+
+        isPolling = false;
+        return snapshot;
+    }
+
+    std::optional<wm::EntitySnapshot>
+    ReadStream::_pollOnce(const SnapshotCallbackT& callback)
+    {
+        // Make sure to not busy wait. Also wait until probably data is available in first iteration.
+        metronome.waitForNextTick();
+
+        auto timeEnd = armarx::core::time::Clock::Now();
+        auto makeQuery = [this, &timeEnd](const MemoryID& id)
+        {
+            query::Builder qb;
+            query::CoreSegmentSelector& core =
+                id.hasCoreSegmentName() ? qb.coreSegments().withID(id) : qb.coreSegments().all();
+            query::ProviderSegmentSelector& prov = id.hasProviderSegmentName()
+                                                       ? core.providerSegments().withID(id)
+                                                       : core.providerSegments().all();
+            query::EntitySelector& entity =
+                id.hasEntityName() ? prov.entities().withID(id) : prov.entities().all();
+            entity.snapshots().timeRange(timeStart, timeEnd);
+
+            return qb.buildQueryInput();
+        };
+
+        auto query = makeQuery(queriedId);
+
+        auto result = reader.query(query);
+
+        if (result.success)
+        {
+            using EntitySnapshotReference =
+                std::reference_wrapper<armarx::armem::wm::EntitySnapshot>;
+            // Copy references of snapshots into vector to sort them.
+            std::vector<EntitySnapshotReference> snapshots;
+
+            result.memory.forEachSnapshot([&snapshots](armarx::armem::wm::EntitySnapshot& snapshot)
+                                          { snapshots.push_back(snapshot); });
+
+            // Sort correctly.
+            std::sort(snapshots.begin(),
+                      snapshots.end(),
+                      [](const EntitySnapshotReference& a, const EntitySnapshotReference& b)
+                      { return a.get().id().timestamp < b.get().id().timestamp; });
+
+            // Determine the next start time.
+            DateTime nextStart;
+            if (snapshots.size() > 0)
+            {
+                // Because they are sorted, back() has the highest time stamp.
+                nextStart = snapshots.back().get().id().timestamp +
+                            armarx::core::time::Duration::MicroSeconds(1);
+            }
+            else
+            {
+                nextStart = timeStart;
+            }
+
+            // Call the callback on all snapshots.
+            for (const auto& snapshot : snapshots)
+            {
+                // Assert times in correct interval.
+                ARMARX_CHECK_LESS_EQUAL(timeStart, snapshot.get().id().timestamp);
+                ARMARX_CHECK_GREATER_EQUAL(timeEnd, snapshot.get().id().timestamp);
+
+                const bool continue_ = callback(snapshot.get());
+                if (not continue_)
+                {
+                    return snapshot;
+                }
+            }
+
+            timeStart = nextStart;
+        }
+        else
+        {
+            ARMARX_WARNING
+                << deactivateSpam()
+                << "Received an error in ReadStream when querying data from a "
+                   "memory. The error was '"
+                << result.errorMessage
+                << "'. Continue with stream, perhaps the memory was not yet initialized.";
+        }
+
+        return std::nullopt;
+    }
+
+
+} // namespace armarx::armem::client
diff --git a/source/RobotAPI/libraries/armem/client/ReadStream.h b/source/RobotAPI/libraries/armem/client/ReadStream.h
new file mode 100644
index 0000000000000000000000000000000000000000..c86fb5b0675ddfc3fa3c4cd9abe49df5ab7a3016
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/ReadStream.h
@@ -0,0 +1,138 @@
+#pragma once
+
+#include <functional>
+#include <optional>
+#include <thread>
+
+#include <ArmarXCore/core/time/DateTime.h>
+#include <ArmarXCore/core/time/Frequency.h>
+#include <ArmarXCore/core/time/Metronome.h>
+
+#include <RobotAPI/libraries/armem/core/MemoryID.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+
+#include "Reader.h"
+
+namespace armarx::armem::client
+{
+    /**
+     * @brief A stream reading entity snapshots from the memory.
+     *
+     * After constructing a ReadStream, polling can be started in three ways:
+     *
+     * 1. Run a polling loop in this thread, blocking execution until terminated.
+     *    See pollBlocking().
+     * 2. Run a polling loop in a new, separate thread, until it is stopped via stop().
+     *    See pollAsync() and stop().
+     * 3. Perform a single query and process the result, embedded in your own loop or other control
+     *    flow logic.
+     *    See pollOnce().
+     */
+    class ReadStream
+    {
+    public:
+        /**
+         * @brief Callback called on each entity snapshot in the queried ID.
+         *
+         * If it returns false, the stream is stopped.
+         */
+        using SnapshotCallbackT = std::function<bool(const wm::EntitySnapshot&)>;
+
+        /**
+         * @brief Inizialize a ReadStream which does not represent a stream.
+         */
+        ReadStream();
+
+        /**
+         * @brief Initialize a read stream.
+         *
+         * @param reader
+         *   The reader to perform the queries.
+         * @param queriedId
+         *   The memory ID in which all snapshots should be processed by the stream.
+         * @param maxPollFrequency
+         *   The maximum frequency with which queries are performed. The
+         *   real frequency might be lower.
+         */
+        ReadStream(const Reader& reader,
+                   const MemoryID& queriedId,
+                   const armarx::core::time::Frequency& maxPollFrequency =
+                       armarx::core::time::Frequency::Hertz(10));
+
+
+        /**
+         * @brief Poll in this thread as long as callback returns true.
+         *
+         * @param callback Function to call on each entity snapshot.
+         * @return The snapshot object that returns false.
+         * @throw armarx::armem::error::ReadStreamAlreadyPolling If the stream is already polling.
+         */
+        std::optional<wm::EntitySnapshot> pollBlocking(const SnapshotCallbackT& callback);
+
+        /**
+         * @brief Poll in a new thread as long as callback returns true.
+         *
+         * Note that callback will be called in a separate thread, so take care of synchronizing
+         * access to variables in the callback appropriately.
+         *
+         * Roughly equivalent to:
+         * @code
+         * std::thread thread([]() { stream.pollBlocking(); });
+         * @endcode
+         *
+         * @param callback Function to call on each entity snapshot.
+         * @throw armarx::armem::error::ReadStreamAlreadyPolling If the stream is already polling.
+         */
+        void pollAsync(const SnapshotCallbackT& callback);
+        /**
+         * @brief Stop a running polling loop.
+         *
+         * If a polling thread has been started by pollAsync() before, joins the thread.
+         */
+        void stop();
+
+        /**
+         * @brief Perform one query and call the callbacks on each snapshot.
+         *
+         * This allows you to define your own loop, for example:
+         *
+         * @code
+         * bool condition = true;
+         * while (condition)
+         * {
+         *     auto snapshot = stream.pollOnce(callback);
+         *
+         *     ...
+         *
+         *     if (...)
+         *     {
+         *        condition = false;
+         *     }
+         * }
+         * @endcode
+         *
+         * @param callback Function to call on each entity snapshot.
+         * @throw armarx::armem::error::ReadStreamAlreadyPolling If the stream is already polling.
+         */
+        std::optional<wm::EntitySnapshot> pollOnce(const SnapshotCallbackT& callback);
+
+
+    private:
+        std::optional<wm::EntitySnapshot> _pollBlocking(const SnapshotCallbackT& callback);
+        std::optional<wm::EntitySnapshot> _pollOnce(const SnapshotCallbackT& callback);
+
+
+    private:
+        Reader reader;
+        MemoryID queriedId;
+
+        armarx::core::time::Metronome metronome;
+        armarx::DateTime timeStart;
+
+        std::atomic_bool isPolling = false;
+        std::atomic_bool pollingStoppedExternally = false;
+
+        std::thread pollingThread;
+    };
+
+} // namespace armarx::armem::client
diff --git a/source/RobotAPI/libraries/armem/client/Reader.h b/source/RobotAPI/libraries/armem/client/Reader.h
index 875250eb836740ec46dc3cc009ded155e97a2264..d476b25ef2003edeeb183fbe4e74bcd70a6176c0 100644
--- a/source/RobotAPI/libraries/armem/client/Reader.h
+++ b/source/RobotAPI/libraries/armem/client/Reader.h
@@ -2,9 +2,9 @@
 
 
 // STD/STL
+#include <mutex>
 #include <optional>
 #include <vector>
-#include <mutex>
 
 // RobotAPI
 #include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
@@ -15,7 +15,6 @@
 
 #include "Query.h"
 
-
 namespace armarx::armem::client
 {
 
@@ -26,11 +25,11 @@ namespace armarx::armem::client
     {
 
     public:
-
         /**
          * @brief Construct a memory reader.
          * @param memory The memory proxy.
          */
+        Reader(const Reader&) = default;
         Reader(server::ReadingMemoryInterfacePrx readingMemory = nullptr,
                server::PredictingMemoryInterfacePrx predictingMemory = nullptr);
 
@@ -41,8 +40,10 @@ namespace armarx::armem::client
         QueryResult query(const QueryInput& input) const;
         armem::query::data::Result query(const armem::query::data::Input& input) const;
 
-        QueryResult query(armem::query::data::MemoryQueryPtr query, armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
-        QueryResult query(const armem::query::data::MemoryQuerySeq& queries, armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
+        QueryResult query(armem::query::data::MemoryQueryPtr query,
+                          armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
+        QueryResult query(const armem::query::data::MemoryQuerySeq& queries,
+                          armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
 
         QueryResult query(const QueryBuilder& queryBuilder) const;
 
@@ -114,7 +115,8 @@ namespace armarx::armem::client
          * @return The query result.
          */
         QueryResult
-        queryMemoryIDs(const std::vector<MemoryID>& ids, armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
+        queryMemoryIDs(const std::vector<MemoryID>& ids,
+                       armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
 
 
         /**
@@ -132,8 +134,9 @@ namespace armarx::armem::client
          * @param dataMode With or without data.
          * @return The query result.
          */
-        QueryResult
-        getLatestSnapshotsIn(const MemoryID& id, armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
+        QueryResult getLatestSnapshotsIn(
+            const MemoryID& id,
+            armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
 
         /**
          * @brief Get the latest snapshot under the given memory ID.
@@ -141,8 +144,9 @@ namespace armarx::armem::client
          * @param dataMode With or without data.
          * @return The latest contained snapshot, if any.
          */
-        std::optional<wm::EntitySnapshot>
-        getLatestSnapshotIn(const MemoryID& id, armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
+        std::optional<wm::EntitySnapshot> getLatestSnapshotIn(
+            const MemoryID& id,
+            armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
 
 
         /**
@@ -150,8 +154,8 @@ namespace armarx::armem::client
          * @param dataMode With or without data.
          * @return The query result.
          */
-        QueryResult
-        getAllLatestSnapshots(armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
+        QueryResult getAllLatestSnapshots(
+            armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
 
 
         /**
@@ -163,7 +167,8 @@ namespace armarx::armem::client
         getAll(armem::query::DataMode dataMode = armem::query::DataMode::WithData) const;
 
 
-        server::dto::DirectlyStoreResult directlyStore(const server::dto::DirectlyStoreInput& input) const;
+        server::dto::DirectlyStoreResult
+        directlyStore(const server::dto::DirectlyStoreInput& input) const;
         void startRecording() const;
         void stopRecording() const;
 
@@ -201,7 +206,6 @@ namespace armarx::armem::client
                                        int recursionDepth);
 
     public:
-
         server::ReadingMemoryInterfacePrx readingPrx;
         server::PredictingMemoryInterfacePrx predictionPrx;
     };
diff --git a/source/RobotAPI/libraries/armem/client/Writer.h b/source/RobotAPI/libraries/armem/client/Writer.h
index 6c4b223ce12e0ee80cd5564e2d2d3ad688661cbc..61eeef93be3164d79d09f6c5aa3371cb362b58b2 100644
--- a/source/RobotAPI/libraries/armem/client/Writer.h
+++ b/source/RobotAPI/libraries/armem/client/Writer.h
@@ -1,10 +1,8 @@
 #pragma once
 
 #include <RobotAPI/interface/armem/server/WritingMemoryInterface.h>
-
 #include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
 
-
 namespace armarx::armem::client
 {
 
@@ -24,17 +22,21 @@ namespace armarx::armem::client
     class Writer
     {
     public:
-
         /**
          * @brief Construct a memory writer.
          * @param memory The memory proxy.
          */
+        Writer(const Writer&) = default;
         Writer(server::WritingMemoryInterfacePrx memory = nullptr);
 
 
-        data::AddSegmentResult addSegment(const std::string& coreSegmentName, const std::string& providerSegmentName, bool clearWhenExists = false);
-        data::AddSegmentResult addSegment(const MemoryID& providerSegmentID, bool clearWhenExists = false);
-        data::AddSegmentResult addSegment(const std::pair<std::string, std::string>& names, bool clearWhenExists = false);
+        data::AddSegmentResult addSegment(const std::string& coreSegmentName,
+                                          const std::string& providerSegmentName,
+                                          bool clearWhenExists = false);
+        data::AddSegmentResult addSegment(const MemoryID& providerSegmentID,
+                                          bool clearWhenExists = false);
+        data::AddSegmentResult addSegment(const std::pair<std::string, std::string>& names,
+                                          bool clearWhenExists = false);
         data::AddSegmentResult addSegment(const data::AddSegmentInput& input);
         data::AddSegmentsResult addSegments(const data::AddSegmentsInput& input);
 
@@ -46,10 +48,9 @@ namespace armarx::armem::client
         /// Commit a single entity update.
         EntityUpdateResult commit(const EntityUpdate& update);
         /// Commit a single entity update.
-        EntityUpdateResult commit(
-            const MemoryID& entityID,
-            const std::vector<aron::data::DictPtr>& instancesData,
-            Time referencedTime);
+        EntityUpdateResult commit(const MemoryID& entityID,
+                                  const std::vector<aron::data::DictPtr>& instancesData,
+                                  Time referencedTime);
 
         // with bare-ice types
         data::CommitResult commit(const data::Commit& commit);
@@ -63,18 +64,15 @@ namespace armarx::armem::client
         }
 
     private:
-
         /// Sets `timeSent` on all entity updates and performs the commit,
         data::CommitResult _commit(data::Commit& commit);
 
 
     public:
-
         server::WritingMemoryInterfacePrx memory;
-
     };
 
-}
+} // namespace armarx::armem::client
 
 namespace armarx::armem::data
 {
@@ -82,4 +80,4 @@ namespace armarx::armem::data
     std::ostream& operator<<(std::ostream& os, const AddSegmentsInput& rhs);
     std::ostream& operator<<(std::ostream& os, const AddSegmentResult& rhs);
     std::ostream& operator<<(std::ostream& os, const AddSegmentsResult& rhs);
-}
+} // namespace armarx::armem::data
diff --git a/source/RobotAPI/libraries/armem/client/plugins/ReaderWriterPlugin.h b/source/RobotAPI/libraries/armem/client/plugins/ReaderWriterPlugin.h
index 168686040e37f0346757b4ee259dd0107b0e4a37..868d3ef30cd593ab09c4ac55bcdcdcbdf2f7f81d 100644
--- a/source/RobotAPI/libraries/armem/client/plugins/ReaderWriterPlugin.h
+++ b/source/RobotAPI/libraries/armem/client/plugins/ReaderWriterPlugin.h
@@ -23,13 +23,12 @@
 
 #include <string>
 
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/core/ComponentPlugin.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include <RobotAPI/libraries/armem/client/plugins/Plugin.h>
 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
 #include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
-
+#include <RobotAPI/libraries/armem/client/plugins/Plugin.h>
 
 namespace armarx::armem::client::plugins
 {
@@ -45,8 +44,8 @@ namespace armarx::armem::client::plugins
     class ReaderWriterPlugin : public armarx::ComponentPlugin
     {
     public:
-        ReaderWriterPlugin(ManagedIceObject& parent, const std::string pre) :
-            ComponentPlugin(parent, pre), readerWriter(memoryNameSystem())
+        ReaderWriterPlugin(ManagedIceObject& parent, const std::string& pre) :
+            ComponentPlugin(parent, pre)
         {
             if (not armemPlugin)
             {
@@ -74,7 +73,7 @@ namespace armarx::armem::client::plugins
                 return;
             }
 
-            readerWriter.connect();
+            readerWriter.connect(memoryNameSystem());
         }
 
         bool
@@ -114,9 +113,8 @@ namespace armarx::armem::client::plugins
         }
 
         armarx::armem::client::plugins::Plugin* armemPlugin = nullptr;
-        
-        T readerWriter;
 
+        T readerWriter;
     };
 
 } // namespace armarx::armem::client::plugins
diff --git a/source/RobotAPI/libraries/armem/client/util/MemoryListener.cpp b/source/RobotAPI/libraries/armem/client/util/MemoryListener.cpp
index c8a7c6c683467194d6e2248edc0e5be57d3b547b..9aa23153cbfe67047579fdedab8753e35c260002 100644
--- a/source/RobotAPI/libraries/armem/client/util/MemoryListener.cpp
+++ b/source/RobotAPI/libraries/armem/client/util/MemoryListener.cpp
@@ -2,36 +2,33 @@
 
 #include <sstream>
 
+#include <ArmarXCore/core/ManagedIceObject.h>
 #include <ArmarXCore/core/exceptions/LocalException.h>
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/ice_conversions/ice_conversions_templates.h>
-#include <ArmarXCore/core/ManagedIceObject.h>
+#include <ArmarXCore/core/logging/Logging.h>
 
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
 #include <RobotAPI/libraries/armem/core/error.h>
-
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
 
 namespace armarx::armem::client::util
 {
 
-    std::string MemoryListener::MakeMemoryTopicName(const MemoryID& memoryID)
+    std::string
+    MemoryListener::MakeMemoryTopicName(const MemoryID& memoryID)
     {
         return "MemoryUpdates." + memoryID.memoryName;
     }
 
-
-    MemoryListener::MemoryListener(ManagedIceObject* component) :
-        component(component)
+    MemoryListener::MemoryListener(ManagedIceObject* component) : component(component)
     {
     }
 
-
-    void MemoryListener::setComponent(ManagedIceObject* component)
+    void
+    MemoryListener::setComponent(ManagedIceObject* component)
     {
         this->component = component;
     }
 
-
     void
     MemoryListener::updated(const std::vector<data::MemoryID>& updatedSnapshotIDs) const
     {
@@ -40,7 +37,6 @@ namespace armarx::armem::client::util
         updated(bos);
     }
 
-
     void
     MemoryListener::updated(const std::vector<MemoryID>& updatedSnapshotIDs) const
     {
@@ -76,68 +72,104 @@ namespace armarx::armem::client::util
             if (not matchingSnapshotIDs.empty())
             {
                 ARMARX_DEBUG << "Calling " << subCallbacks.size() << " callbacks"
-                             << " subscribing " << subscription
-                             << " with " << matchingSnapshotIDs.size() << " snapshot IDs ...";
-                for (auto& callback : subCallbacks)
+                             << " subscribing " << subscription << " with "
+                             << matchingSnapshotIDs.size() << " snapshot IDs ...";
+                for (auto& managedCallback : subCallbacks)
                 {
                     try
                     {
-                        callback(subscription, matchingSnapshotIDs);
+                        managedCallback.callback(subscription, matchingSnapshotIDs);
                     }
                     catch (const armarx::LocalException& e)
                     {
                         error << "Calling callback subscribing " << subscription << " failed."
                               << "\nCaught armarx::LocalException:"
-                              << "\n" << e.getReason()
-                              << "\n Stacktrace: \n" << e.generateBacktrace()
                               << "\n"
-                                 ;
+                              << e.getReason() << "\n Stacktrace: \n"
+                              << e.generateBacktrace() << "\n";
                     }
                     catch (const std::exception& e)
                     {
                         error << "Calling callback subscribing " << subscription << " failed."
                               << "\nCaught armarx::Exception:"
-                              << "\n" << e.what()
                               << "\n"
-                                 ;
+                              << e.what() << "\n";
                     }
                     catch (...)
                     {
                         error << "Calling callback subscribing " << subscription << " failed."
                               << "\nCaught unknown exception."
-                              << "\n"
-                                 ;
+                              << "\n";
                     }
                 }
             }
         }
         if (error.str().size() > 0)
         {
-            ARMARX_WARNING << "The following issues were encountered during MemoryListener::" << __FUNCTION__ << "(): \n\n"
+            ARMARX_WARNING << "The following issues were encountered during MemoryListener::"
+                           << __FUNCTION__ << "(): \n\n"
                            << error.str();
         }
     }
 
-
-    void
-    MemoryListener::subscribe(const MemoryID& id, Callback callback)
+    SubscriptionHandle
+    MemoryListener::subscribe(const MemoryID& memoryID, Callback callback)
     {
-        callbacks[id].push_back(callback);
-        if (component)
+        ARMARX_CHECK_NOT_EMPTY(memoryID.memoryName)
+            << "The memoryName must be specified to subscribe";
+
+        if (component and memoryRefCount[memoryID.memoryName] == 0)
         {
-            component->usingTopic(MakeMemoryTopicName(id));
+            component->usingTopic(MakeMemoryTopicName(memoryID));
         }
+
+        auto id = nextId++;
+        callbacks[memoryID].push_back({id, callback});
+
+        memoryRefCount[memoryID.memoryName]++;
+
+        return SubscriptionHandle(this, memoryID, id);
     }
 
+    SubscriptionHandle
+    MemoryListener::subscribe(const MemoryID& subscriptionID, CallbackUpdatedOnly callback)
+    {
+        return subscribe(
+            subscriptionID,
+            [callback](const MemoryID&, const std::vector<MemoryID>& updatedSnapshotIDs)
+            { callback(updatedSnapshotIDs); });
+    }
 
     void
-    MemoryListener::subscribe(const MemoryID& subscriptionID, CallbackUpdatedOnly callback)
+    MemoryListener::unsubscribe(SubscriptionHandle& handle)
     {
-        subscribe(subscriptionID, [callback](const MemoryID&, const std::vector<MemoryID>& updatedSnapshotIDs)
+        if (not handle.valid)
+        {
+            return;
+        }
+        handle.valid = false;
+
+        // Remove ManagedCallback with ManagedCallback.id == handle.id from callbacks[handle.memoryID]
+        auto it = std::find_if(callbacks[handle.memoryID].begin(),
+                               callbacks[handle.memoryID].end(),
+                               [&handle](ManagedCallback& mCb) { return mCb.id == handle.id; });
+
+        std::iter_swap(it, callbacks[handle.memoryID].end() - 1);
+        callbacks[handle.memoryID].pop_back();
+
+        memoryRefCount[handle.memoryID.memoryName]--;
+
+        if (callbacks[handle.memoryID].empty())
         {
-            callback(updatedSnapshotIDs);
-        });
+            callbacks.erase(handle.memoryID);
+
+            // unsubscribe from memory topic if no remainig callback needs it
+            if (component and memoryRefCount[handle.memoryID.memoryName] == 0)
+            {
+                component->unsubscribeFromTopic(MakeMemoryTopicName(handle.memoryID));
+            }
+        }
     }
 
 
-}
+} // namespace armarx::armem::client::util
diff --git a/source/RobotAPI/libraries/armem/client/util/MemoryListener.h b/source/RobotAPI/libraries/armem/client/util/MemoryListener.h
index 521d9ce6981e9503d90515b0fc10c518eedaae5a..80d8eb3313c44a99abcc87d0048c2a24c2a137e3 100644
--- a/source/RobotAPI/libraries/armem/client/util/MemoryListener.h
+++ b/source/RobotAPI/libraries/armem/client/util/MemoryListener.h
@@ -1,6 +1,5 @@
 #pragma once
 
-
 // STD/STL
 #include <functional>
 #include <unordered_map>
@@ -10,7 +9,7 @@
 #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
 #include <RobotAPI/libraries/armem/core/MemoryID.h>
 
-
+#include "SubscriptionHandle.h"
 
 namespace armarx
 {
@@ -19,34 +18,36 @@ namespace armarx
 
 namespace armarx::armem::client::util
 {
-
     /**
      * @brief Handles update signals from the memory system and distributes it
      * to its subsribers.
      */
     class MemoryListener
     {
-    public:
 
-        using Callback = std::function<void(const MemoryID& subscriptionID, const std::vector<MemoryID>& updatedSnapshotIDs)>;
-        using CallbackUpdatedOnly = std::function<void(const std::vector<MemoryID>& updatedSnapshotIDs)>;
+    public:
+        using Callback = std::function<void(const MemoryID& subscriptionID,
+                                            const std::vector<MemoryID>& updatedSnapshotIDs)>;
+        using CallbackUpdatedOnly =
+            std::function<void(const std::vector<MemoryID>& updatedSnapshotIDs)>;
 
         template <class CalleeT>
-        using MemberCallback = void(CalleeT::*)(const MemoryID& subscriptionID, const std::vector<MemoryID>& updatedSnapshotIDs);
+        using MemberCallback = void (CalleeT::*)(const MemoryID& subscriptionID,
+                                                 const std::vector<MemoryID>& updatedSnapshotIDs);
         template <class CalleeT>
-        using MemberCallbackUpdatedOnly = void(CalleeT::*)(const std::vector<MemoryID>& updatedSnapshotIDs);
+        using MemberCallbackUpdatedOnly =
+            void (CalleeT::*)(const std::vector<MemoryID>& updatedSnapshotIDs);
 
         static std::string MakeMemoryTopicName(const MemoryID& memoryID);
 
 
     public:
-
         MemoryListener(ManagedIceObject* component = nullptr);
 
         void setComponent(ManagedIceObject* component);
 
-        void subscribe(const MemoryID& subscriptionID, Callback Callback);
-        void subscribe(const MemoryID& subscriptionID, CallbackUpdatedOnly Callback);
+        SubscriptionHandle subscribe(const MemoryID& subscriptionID, Callback Callback);
+        SubscriptionHandle subscribe(const MemoryID& subscriptionID, CallbackUpdatedOnly Callback);
 
         /**
          * Subscribe with a class member function:
@@ -55,28 +56,33 @@ namespace armarx::armem::client::util
          * @endcode
          */
         template <class CalleeT>
-        void subscribe(const MemoryID& subscriptionID, CalleeT* callee, MemberCallback<CalleeT> callback)
+        SubscriptionHandle
+        subscribe(const MemoryID& subscriptionID, CalleeT* callee, MemberCallback<CalleeT> callback)
         {
-            auto cb = [callee, callback](const MemoryID & subscriptionID, const std::vector<MemoryID>& updatedSnapshotIDs)
-            {
-                (callee->*callback)(subscriptionID, updatedSnapshotIDs);
-            };
-            subscribe(subscriptionID, cb);
+            auto cb = [callee, callback](const MemoryID& subscriptionID,
+                                         const std::vector<MemoryID>& updatedSnapshotIDs)
+            { (callee->*callback)(subscriptionID, updatedSnapshotIDs); };
+            return subscribe(subscriptionID, cb);
         }
 
         template <class CalleeT>
-        void subscribe(const MemoryID& subscriptionID, CalleeT* callee, MemberCallbackUpdatedOnly<CalleeT> callback)
+        SubscriptionHandle
+        subscribe(const MemoryID& subscriptionID,
+                  CalleeT* callee,
+                  MemberCallbackUpdatedOnly<CalleeT> callback)
         {
-            auto cb = [callee, callback](const MemoryID&, const std::vector<MemoryID>& updatedSnapshotIDs)
+            auto cb =
+                [callee, callback](const MemoryID&, const std::vector<MemoryID>& updatedSnapshotIDs)
             {
-                if(callee)
+                if (callee)
                 {
                     (callee->*callback)(updatedSnapshotIDs);
                 }
             };
-            subscribe(subscriptionID, cb);
+            return subscribe(subscriptionID, cb);
         }
 
+        void unsubscribe(SubscriptionHandle& subscriptionHandle);
 
         /// Function handling updates from the MemoryListener ice topic.
         void updated(const std::vector<MemoryID>& updatedIDs) const;
@@ -84,13 +90,21 @@ namespace armarx::armem::client::util
 
 
     protected:
+        long nextId = 0;
 
-        std::unordered_map<MemoryID, std::vector<Callback>> callbacks;
+        struct ManagedCallback
+        {
+            long id = 0;
+            Callback callback;
+        };
 
-    private:
+        std::unordered_map<MemoryID, std::vector<ManagedCallback>> callbacks;
 
-        armarx::ManagedIceObject* component;
+        /// memoryName -> #callbacks needing memory topic
+        std::unordered_map<std::string, int> memoryRefCount;
 
+    private:
+        armarx::ManagedIceObject* component;
     };
 
-}
+} // namespace armarx::armem::client::util
diff --git a/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.cpp b/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.cpp
index 856bc217146eb651770fc192dd9ce8a03ebcdf3c..e14ce8848fd1fe8242d681770563bf9cddefd7cd 100644
--- a/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.cpp
+++ b/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.cpp
@@ -6,8 +6,7 @@
 namespace armarx::armem::client::util
 {
 
-    SimpleReaderBase::SimpleReaderBase(MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
+    SimpleReaderBase::SimpleReaderBase()
     {
     }
 
@@ -25,14 +24,13 @@ namespace armarx::armem::client::util
     }
 
     void
-    SimpleReaderBase::connect()
+    SimpleReaderBase::connect(armarx::armem::client::MemoryNameSystem& mns)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "SimpleReaderBase: Waiting for memory '" << props.memoryName << "' ...";
         try
         {
-            memoryReaderClient =
-                memoryNameSystem.useReader(MemoryID().withMemoryName(props.memoryName));
+            memoryReaderClient = mns.useReader(MemoryID().withMemoryName(props.memoryName));
             ARMARX_IMPORTANT << "SimpleReaderBase: Connected to memory '" << props.memoryName
                              << "'";
         }
diff --git a/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.h b/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.h
index 45b26e7c9e8c4dd124b762d297d2fb0dca29a317..2b637193765215b81519c55397bcc51a7436041b 100644
--- a/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.h
+++ b/source/RobotAPI/libraries/armem/client/util/SimpleReaderBase.h
@@ -27,7 +27,6 @@
 
 #include <RobotAPI/libraries/armem/client/Reader.h>
 
-
 namespace armarx::armem::client
 {
     class MemoryNameSystem;
@@ -43,40 +42,36 @@ namespace armarx::armem::client::util
         // Properties
         struct Properties
         {
-          std::string memoryName      = "";
-          std::string coreSegmentName = "";
+            std::string memoryName = "";
+            std::string coreSegmentName = "";
         };
 
-        SimpleReaderBase(MemoryNameSystem& memoryNameSystem);
+        SimpleReaderBase();
         virtual ~SimpleReaderBase() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        virtual void connect();
+        virtual void connect(armarx::armem::client::MemoryNameSystem& mns);
 
         const Properties& properties() const;
-        void setProperties(const Properties& p)
+
+        void
+        setProperties(const Properties& p)
         {
-          props = p;
+            props = p;
         }
 
     protected:
-
-        virtual std::string propertyPrefix() const   = 0;
+        virtual std::string propertyPrefix() const = 0;
         virtual Properties defaultProperties() const = 0;
 
         std::mutex& memoryReaderMutex();
         const armem::client::Reader& memoryReader() const;
 
-
-        MemoryNameSystem& memoryNameSystem;
-
     private:
-
         Properties props;
 
         armem::client::Reader memoryReaderClient;
         std::mutex memoryMutex;
-
     };
 
 } // namespace armarx::armem::client::util
diff --git a/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.cpp b/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.cpp
index 9e27df2c2ef5d7af53529502489085e4f43c231d..e5d468c552d96d70d3ef4ae92196cdb714f39163 100644
--- a/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.cpp
+++ b/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.cpp
@@ -1,17 +1,14 @@
 #include "SimpleWriterBase.h"
 
-#include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
-
+#include <RobotAPI/libraries/armem/core/error.h>
 
 namespace armarx::armem::client::util
 {
-    SimpleWriterBase::SimpleWriterBase(MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
+    SimpleWriterBase::SimpleWriterBase()
     {
     }
 
-
     void
     SimpleWriterBase::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
@@ -26,21 +23,19 @@ namespace armarx::armem::client::util
 
         // TODO(fabian.reister): this might also be part of the subclass
         //  if the provider name has to be derived from e.g. the component name
-        def->optional(props.providerName,
-                      prefix + "Provider",
-                      "Name of this provider");
+        def->optional(props.providerName, prefix + "Provider", "Name of this provider");
     }
 
-
-    void SimpleWriterBase::connect()
+    void
+    SimpleWriterBase::connect(armarx::armem::client::MemoryNameSystem& mns)
     {
         // Wait for the memory to become available and add it as dependency.
-        ARMARX_IMPORTANT << "SimpleWriterBase: Waiting for memory '"
-                         << props.memoryName << "' ...";
+        ARMARX_IMPORTANT << "SimpleWriterBase: Waiting for memory '" << props.memoryName << "' ...";
         try
         {
-            memoryWriterClient = memoryNameSystem.useWriter(MemoryID().withMemoryName(props.memoryName));
-            ARMARX_IMPORTANT << "SimpleWriterBase: Connected to memory '" << props.memoryName << "'";
+            memoryWriterClient = mns.useWriter(MemoryID().withMemoryName(props.memoryName));
+            ARMARX_IMPORTANT << "SimpleWriterBase: Connected to memory '" << props.memoryName
+                             << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -49,20 +44,20 @@ namespace armarx::armem::client::util
         }
     }
 
-
-    std::mutex& SimpleWriterBase::memoryWriterMutex()
+    std::mutex&
+    SimpleWriterBase::memoryWriterMutex()
     {
         return memoryMutex;
     }
 
-
-    armem::client::Writer& SimpleWriterBase::memoryWriter()
+    armem::client::Writer&
+    SimpleWriterBase::memoryWriter()
     {
         return memoryWriterClient;
     }
 
-
-    const SimpleWriterBase::Properties& SimpleWriterBase::properties() const
+    const SimpleWriterBase::Properties&
+    SimpleWriterBase::properties() const
     {
         return props;
     }
diff --git a/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.h b/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.h
index 1413299a3081f36dfaa83cce425c50994e7018c2..13a54cc5b213a90e1949f73c1b11de716c0593cc 100644
--- a/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.h
+++ b/source/RobotAPI/libraries/armem/client/util/SimpleWriterBase.h
@@ -27,7 +27,6 @@
 
 #include <RobotAPI/libraries/armem/client/Writer.h>
 
-
 namespace armarx::armem::client
 {
     class MemoryNameSystem;
@@ -39,26 +38,24 @@ namespace armarx::armem::client::util
     class SimpleWriterBase
     {
     public:
-
-        SimpleWriterBase(MemoryNameSystem& memoryNameSystem);
+        SimpleWriterBase();
         virtual ~SimpleWriterBase() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        void connect();
+        void connect(armarx::armem::client::MemoryNameSystem& mns);
 
 
     protected:
-
         struct Properties
         {
-            std::string memoryName      = "";
+            std::string memoryName = "";
             std::string coreSegmentName = "";
-            std::string providerName    = ""; // required property
+            std::string providerName = ""; // required property
         };
 
         const Properties& properties() const;
 
-        virtual std::string propertyPrefix() const   = 0;
+        virtual std::string propertyPrefix() const = 0;
         virtual Properties defaultProperties() const = 0;
 
         std::mutex& memoryWriterMutex();
@@ -66,14 +63,10 @@ namespace armarx::armem::client::util
 
 
     private:
-
         Properties props;
 
         armem::client::Writer memoryWriterClient;
         std::mutex memoryMutex;
-
-        MemoryNameSystem& memoryNameSystem;
-
     };
 
 } // namespace armarx::armem::client::util
diff --git a/source/RobotAPI/libraries/armem/client/util/SubscriptionHandle.cpp b/source/RobotAPI/libraries/armem/client/util/SubscriptionHandle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..114146c91699ff6a8a7fdf88bef61fdca734b892
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/util/SubscriptionHandle.cpp
@@ -0,0 +1,73 @@
+#include "SubscriptionHandle.h"
+
+#include "MemoryListener.h"
+
+namespace armarx::armem::client::util
+{
+    SubscriptionHandle::SubscriptionHandle(MemoryListener* memoryListener,
+                                           const MemoryID& memoryID,
+                                           long id) :
+        valid{true}, memoryListener{memoryListener}, memoryID(memoryID), id{id}
+    {
+    }
+
+    SubscriptionHandle::SubscriptionHandle() : valid{false}
+    {
+    }
+
+    SubscriptionHandle::SubscriptionHandle(SubscriptionHandle&& other) :
+        valid{other.valid},
+        memoryListener{other.memoryListener},
+        memoryID(std::move(other.memoryID)),
+        id{other.id}
+    {
+        other.valid = false;
+    }
+
+    SubscriptionHandle&
+    SubscriptionHandle::operator=(SubscriptionHandle other)
+    {
+        swap(*this, other);
+        return *this;
+    }
+
+    void
+    SubscriptionHandle::release()
+    {
+        memoryListener->unsubscribe(*this);
+    }
+
+    ScopedSubscriptionHandle::ScopedSubscriptionHandle()
+    {
+    }
+
+    ScopedSubscriptionHandle::ScopedSubscriptionHandle(SubscriptionHandle&& handle) :
+        handle(std::move(handle))
+    {
+    }
+
+    ScopedSubscriptionHandle&
+    ScopedSubscriptionHandle::operator=(SubscriptionHandle handle)
+    {
+        std::swap(this->handle, handle);
+        return *this;
+    }
+
+    ScopedSubscriptionHandle::~ScopedSubscriptionHandle()
+    {
+        handle.release();
+    }
+
+} // namespace armarx::armem::client::util
+
+namespace armarx::armem::client
+{
+    void
+    util::swap(util::SubscriptionHandle& first, util::SubscriptionHandle& second)
+    {
+        std::swap(first.valid, second.valid);
+        std::swap(first.memoryListener, second.memoryListener);
+        std::swap(first.memoryID, second.memoryID);
+        std::swap(first.id, second.id);
+    }
+} // namespace armarx::armem::client
diff --git a/source/RobotAPI/libraries/armem/client/util/SubscriptionHandle.h b/source/RobotAPI/libraries/armem/client/util/SubscriptionHandle.h
new file mode 100644
index 0000000000000000000000000000000000000000..6847ac9a7273cef86d91548b2e66befc8573c015
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/util/SubscriptionHandle.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/MemoryID.h>
+
+namespace armarx::armem::client::util
+{
+
+    class MemoryListener;
+
+    class SubscriptionHandle
+    {
+        friend class MemoryListener;
+
+    public:
+        SubscriptionHandle();
+        SubscriptionHandle(SubscriptionHandle&& other);
+
+        /**
+        * @brief Assignment operator.
+        *
+        * @note Intentional call by value, since this leverages the move constructor. See
+        * https://stackoverflow.com/a/11540204 (section "Move assignment operators").
+        */
+        SubscriptionHandle& operator=(SubscriptionHandle other);
+
+        friend void swap(SubscriptionHandle& first, SubscriptionHandle& second);
+
+        void release();
+
+    private:
+        SubscriptionHandle(MemoryListener* memoryListener, const MemoryID& memoryID, long id);
+
+    private:
+        bool valid = false;
+        MemoryListener* memoryListener = nullptr;
+        MemoryID memoryID;
+        long id = 0;
+    };
+
+    class ScopedSubscriptionHandle
+    {
+    public:
+        ScopedSubscriptionHandle();
+        ScopedSubscriptionHandle(SubscriptionHandle&& handle);
+
+        /**
+        * @brief Assignment operator.
+        *
+        * @note Intentional call by value, since this leverages the move constructor. See
+        * https://stackoverflow.com/a/11540204 (section "Move assignment operators").
+        */
+        ScopedSubscriptionHandle& operator=(SubscriptionHandle handle);
+
+        ~ScopedSubscriptionHandle();
+
+    private:
+        SubscriptionHandle handle;
+    };
+
+    void swap(SubscriptionHandle& first, SubscriptionHandle& second);
+
+} // namespace armarx::armem::client::util
diff --git a/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp b/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp
index 354b95712761f6a14d3fb6deb5baeff6b2a18aba..7abe9891d8a1d4f599ae1e135d0dbe8e0d2a29dd 100644
--- a/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp
+++ b/source/RobotAPI/libraries/armem/core/error/ArMemError.cpp
@@ -246,4 +246,19 @@ namespace armarx::armem::error
         return sstream.str();
     }
 
+    ReadStreamAlreadyPolling::ReadStreamAlreadyPolling(const MemoryID& queriedId,
+                                                       const std::string& calledFunction) :
+        ArMemError(makeMsg(queriedId, calledFunction))
+    {
+    }
+
+    std::string
+    ReadStreamAlreadyPolling::makeMsg(const MemoryID& queriedId, const std::string& calledFunction)
+    {
+        std::stringstream ss;
+        ss << "The ReadStream for " << queriedId << " was already running when " << calledFunction
+           << " was called.";
+        return ss.str();
+    }
+
 } // namespace armarx::armem::error
diff --git a/source/RobotAPI/libraries/armem/core/error/ArMemError.h b/source/RobotAPI/libraries/armem/core/error/ArMemError.h
index 69ab7d4ddff8e22791272c520386e2fdff3d6e6f..67435f8d3c4142d3453fc6f6626e4e48ebb33cad 100644
--- a/source/RobotAPI/libraries/armem/core/error/ArMemError.h
+++ b/source/RobotAPI/libraries/armem/core/error/ArMemError.h
@@ -220,4 +220,15 @@ namespace armarx::armem::error
         static std::string makeMsg(const std::string& proxyName, const std::string& message = "");
     };
 
+    /**
+     * @brief Indicates that a ReadStream is already polling when a polling method was called.
+     */
+    class ReadStreamAlreadyPolling : public ArMemError
+    {
+    public:
+        ReadStreamAlreadyPolling(const MemoryID& queriedId, const std::string& calledFunction);
+
+        static std::string makeMsg(const MemoryID& queriedId, const std::string& calledFunction);
+    };
+
 } // namespace armarx::armem::error
diff --git a/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.cpp b/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.cpp
index efe2d01c13731c5c32ba876a3837b2e1816ea41a..6eafef5ed875232aa83ab237f058a3c29db08a60 100644
--- a/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.cpp
+++ b/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.cpp
@@ -3,29 +3,25 @@
 #include <mutex>
 #include <optional>
 
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/PackagePath.h>
+#include <ArmarXCore/core/logging/Logging.h>
 
+#include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/util/util.h>
-#include <RobotAPI/libraries/armem_robot/robot_conversions.h>
-#include <RobotAPI/libraries/armem_robot/aron_conversions.h>
-#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
 #include <RobotAPI/libraries/armem_objects/aron/Attachment.aron.generated.h>
 #include <RobotAPI/libraries/armem_objects/aron_conversions.h>
+#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
+#include <RobotAPI/libraries/armem_robot/aron_conversions.h>
+#include <RobotAPI/libraries/armem_robot/robot_conversions.h>
 #include <RobotAPI/libraries/aron/common/aron_conversions.h>
 
-
 namespace armarx::armem::grasping::known_grasps
 {
-    Reader::Reader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
-    {}
-
-    void Reader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+    void
+    Reader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
         ARMARX_DEBUG << "Reader: registerPropertyDefinitions";
 
@@ -38,8 +34,8 @@ namespace armarx::armem::grasping::known_grasps
                       "Name of the memory core segment to use for object instances.");
     }
 
-
-    void Reader::connect()
+    void
+    Reader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "Reader: Waiting for memory '" << properties.memoryName << "' ...";
@@ -55,7 +51,8 @@ namespace armarx::armem::grasping::known_grasps
         }
     }
 
-    std::optional<armem::grasping::arondto::KnownGraspInfo> Reader::queryKnownGraspInfo(const armem::wm::Memory& memory, const armem::Time&)
+    std::optional<armem::grasping::arondto::KnownGraspInfo>
+    Reader::queryKnownGraspInfo(const armem::wm::Memory& memory, const armem::Time&)
     {
         // clang-format off
         const armem::wm::CoreSegment& s = memory
@@ -63,8 +60,7 @@ namespace armarx::armem::grasping::known_grasps
         // clang-format on
 
         const armem::wm::EntityInstance* instance = nullptr;
-        s.forEachInstance([&instance](const wm::EntityInstance& i)
-                                        { instance = &i; });
+        s.forEachInstance([&instance](const wm::EntityInstance& i) { instance = &i; });
         if (instance == nullptr)
         {
             ARMARX_VERBOSE << "No entity snapshots found";
@@ -73,7 +69,9 @@ namespace armarx::armem::grasping::known_grasps
         return armem::grasping::arondto::KnownGraspInfo::FromAron(instance->data());
     }
 
-    std::optional<armarx::armem::grasping::arondto::KnownGraspInfo> Reader::queryKnownGraspInfoByEntityName(const std::string& entityName, const armem::Time& timestamp)
+    std::optional<armarx::armem::grasping::arondto::KnownGraspInfo>
+    Reader::queryKnownGraspInfoByEntityName(const std::string& entityName,
+                                            const armem::Time& timestamp)
     {
         // Query all entities from all provider.
         armem::client::query::Builder qb;
@@ -103,7 +101,8 @@ namespace armarx::armem::grasping::known_grasps
             auto split = simox::alg::split(entityName, "/");
             if (split.size() > 2) // there is more than just dataset/class
             {
-                ARMARX_INFO << "No grasp found for object entity " << entityName << ". Search for grasp without the index";
+                ARMARX_INFO << "No grasp found for object entity " << entityName
+                            << ". Search for grasp without the index";
                 return queryKnownGraspInfoByEntityName(split[0] + "/" + split[1], timestamp);
             }
         }
@@ -111,4 +110,4 @@ namespace armarx::armem::grasping::known_grasps
         return ret;
     }
 
-}  // namespace armarx::armem::attachment
+} // namespace armarx::armem::grasping::known_grasps
diff --git a/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.h b/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.h
index e421d4ee185b092ece8f81f3af45116e04c3d723..d0057afc8d23a30da6e5c6335143d58c638d0557 100644
--- a/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.h
+++ b/source/RobotAPI/libraries/armem_grasping/client/KnownGraspCandidateReader.h
@@ -28,38 +28,36 @@
 
 #include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
 #include <RobotAPI/libraries/armem/client/Reader.h>
-
 #include <RobotAPI/libraries/armem_grasping/aron/KnownGraspCandidate.aron.generated.h>
 
-
 namespace armarx::armem::grasping::known_grasps
 {
     class Reader
     {
     public:
-        Reader(armem::client::MemoryNameSystem& memoryNameSystem);
+        Reader() = default;
         virtual ~Reader() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
-        std::optional<armem::grasping::arondto::KnownGraspInfo> queryKnownGraspInfoByEntityName(const std::string&, const armem::Time&);
-        std::optional<armem::grasping::arondto::KnownGraspInfo> queryKnownGraspInfo(const armem::wm::Memory& memory, const armem::Time&);
+        std::optional<armem::grasping::arondto::KnownGraspInfo>
+        queryKnownGraspInfoByEntityName(const std::string&, const armem::Time&);
+        std::optional<armem::grasping::arondto::KnownGraspInfo>
+        queryKnownGraspInfo(const armem::wm::Memory& memory, const armem::Time&);
 
     private:
-
         struct Properties
         {
-            std::string memoryName                  = "Grasp";
-            std::string coreSegmentName             = "KnownGraspCandidate";
+            std::string memoryName = "Grasp";
+            std::string coreSegmentName = "KnownGraspCandidate";
         } properties;
 
         const std::string propertyPrefix = "mem.grasping.knowngrasps.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Reader memoryReader;
         mutable std::mutex memoryWriterMutex;
     };
 
 
-}  // namespace armarx::armem::attachment
+} // namespace armarx::armem::grasping::known_grasps
diff --git a/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.cpp b/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.cpp
index e7ceabba97898778af1c13d9ad9c805357f79ac2..359ad8e8d978d0bde3e480388e5ed2b1e7f39f30 100644
--- a/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.cpp
+++ b/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.cpp
@@ -44,16 +44,14 @@
 #include <RobotAPI/libraries/armem_laser_scans/aron_conversions.h>
 #include <RobotAPI/libraries/armem_laser_scans/types.h>
 
-
 namespace armarx::armem::laser_scans::client
 {
 
-    Reader::Reader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
+    Reader::Reader()
     {
     }
-    Reader::~Reader() = default;
 
+    Reader::~Reader() = default;
 
     void
     Reader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
@@ -64,7 +62,7 @@ namespace armarx::armem::laser_scans::client
     }
 
     void
-    Reader::connect()
+    Reader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "MappingDataReader: Waiting for memory '" << constants::memoryName
diff --git a/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.h b/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.h
index 55beab204b12a7f72432ef2e38789f1856058934..5bcfd2c63b9b8bc5682f2b58a2dfbebf7a78a56c 100644
--- a/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.h
+++ b/source/RobotAPI/libraries/armem_laser_scans/client/common/Reader.h
@@ -29,10 +29,9 @@
 
 #include "RobotAPI/libraries/armem_laser_scans/types.h"
 #include <RobotAPI/libraries/armem/client.h>
+#include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
 #include <RobotAPI/libraries/armem/client/Reader.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
-#include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
-
 
 namespace armarx
 {
@@ -62,11 +61,10 @@ namespace armarx::armem::laser_scans::client
     class Reader
     {
     public:
-
-        Reader(armem::client::MemoryNameSystem& memoryNameSystem);
+        Reader();
         virtual ~Reader();
 
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         struct Query
         {
@@ -99,12 +97,9 @@ namespace armarx::armem::laser_scans::client
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
 
-        armarx::armem::client::query::Builder
-        buildQuery(const Query& query) const;
+        armarx::armem::client::query::Builder buildQuery(const Query& query) const;
 
     private:
-
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Reader memoryReader;
 
         // Properties
@@ -113,7 +108,6 @@ namespace armarx::armem::laser_scans::client
         } properties;
 
         const std::string propertyPrefix = "mem.vision.laser_scans.";
-
     };
 
-} // namespace armarx::armem::vision::laser_scans::client
+} // namespace armarx::armem::laser_scans::client
diff --git a/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.cpp b/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.cpp
index 8b43cef166b729c2bb7a0bb3d64df74268d1975d..771f49c22a76585026dc735f7f9697e1b28abf7b 100644
--- a/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.cpp
+++ b/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.cpp
@@ -6,16 +6,14 @@
 #include <RobotAPI/libraries/armem_laser_scans/aron/LaserScan.aron.generated.h>
 #include <RobotAPI/libraries/armem_laser_scans/aron_conversions.h>
 
-
 namespace armarx::armem::laser_scans::client
 {
 
-    Writer::Writer(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
+    Writer::Writer()
     {
     }
-    Writer::~Writer() = default;
 
+    Writer::~Writer() = default;
 
     void
     Writer::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
@@ -23,11 +21,10 @@ namespace armarx::armem::laser_scans::client
         ARMARX_DEBUG << "LaserScansWriter: registerPropertyDefinitions";
 
         const std::string prefix = propertyPrefix;
-
     }
 
     void
-    Writer::connect()
+    Writer::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "LaserScansWriter: Waiting for memory '" << constants::memoryName
diff --git a/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.h b/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.h
index 6a75f24b53d13c0ba2d885c588b5c3e944388a57..8b5a90a1867da3d84a225c73e543c694e3d632f3 100644
--- a/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.h
+++ b/source/RobotAPI/libraries/armem_laser_scans/client/common/Writer.h
@@ -30,7 +30,6 @@
 #include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
 #include <RobotAPI/libraries/armem/client/Writer.h>
 
-
 namespace armarx::armem::laser_scans::client
 {
 
@@ -48,11 +47,11 @@ namespace armarx::armem::laser_scans::client
     class Writer
     {
     public:
-        Writer(armem::client::MemoryNameSystem& memoryNameSystem);
+        Writer();
         virtual ~Writer();
 
 
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         // MappingDataWriterInterface
         /// to be called in Component::onConnectComponent
@@ -67,7 +66,6 @@ namespace armarx::armem::laser_scans::client
                              const armem::Time& timestamp);
 
     private:
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Writer memoryWriter;
 
         // Properties
diff --git a/source/RobotAPI/libraries/armem_locations/client/Reader.cpp b/source/RobotAPI/libraries/armem_locations/client/Reader.cpp
index 0fd0c6a1b5258d7960e9179c649ab0286b26be5a..13cc8ff5a3e515e79e80838a875acad24a6186cd 100644
--- a/source/RobotAPI/libraries/armem_locations/client/Reader.cpp
+++ b/source/RobotAPI/libraries/armem_locations/client/Reader.cpp
@@ -10,13 +10,6 @@
 
 namespace armarx::armem::locations::client
 {
-    Reader::Reader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem),
-        objReader(memoryNameSystem),
-        robotReader(memoryNameSystem)
-    {
-    }
-
     void
     Reader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
@@ -28,7 +21,7 @@ namespace armarx::armem::locations::client
     }
 
     void
-    Reader::connect()
+    Reader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "Waiting for memory '" << p.memoryName << "' ...";
@@ -45,8 +38,8 @@ namespace armarx::armem::locations::client
             return;
         }
 
-        objReader.connect();
-        robotReader.connect();
+        objReader.connect(memoryNameSystem);
+        robotReader.connect(memoryNameSystem);
     }
 
     std::map<std::string, armarx::navigation::location::arondto::Location>
@@ -63,11 +56,11 @@ namespace armarx::armem::locations::client
                 {
                     auto i = e.findLatestInstance();
                     if (i)
-                      {
-                      auto loc = i->dataAs<armarx::navigation::location::arondto::Location>();
-                      ret[i->id().providerSegmentName + "/" + i->id().entityName] = loc;
+                    {
+                        auto loc = i->dataAs<armarx::navigation::location::arondto::Location>();
+                        ret[i->id().providerSegmentName + "/" + i->id().entityName] = loc;
                     }
-                  });
+                });
             return ret;
         }
 
@@ -83,7 +76,7 @@ namespace armarx::armem::locations::client
 
         for (auto& [locName, location] : locations)
         {
-            (void) locName;
+            (void)locName;
             if (location.framedPose.header.frame == armarx::GlobalFrame)
             {
                 location.framedPose.header.agent = ""; //sanity set
diff --git a/source/RobotAPI/libraries/armem_locations/client/Reader.h b/source/RobotAPI/libraries/armem_locations/client/Reader.h
index ad895c269e52fd2e4ec1b6e6bbda037fbefedb04..7a25269d181a9079ec0f770f27fd240d25d7a5af 100644
--- a/source/RobotAPI/libraries/armem_locations/client/Reader.h
+++ b/source/RobotAPI/libraries/armem_locations/client/Reader.h
@@ -23,11 +23,11 @@ namespace armarx::armem::locations::client
             std::string memoryName = "Navigation";
         };
 
-        Reader(armem::client::MemoryNameSystem& memoryNameSystem);
+        Reader() = default;
         virtual ~Reader() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         Properties
         getProperties()
@@ -44,7 +44,6 @@ namespace armarx::armem::locations::client
 
         const std::string propertyPrefix = "mem.nav.location";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armarx::armem::obj::instance::Reader objReader;
         armarx::armem::robot_state::RobotReader robotReader;
 
diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp
index ac01fb3b87a1dc4bc53b40982a38002a80cc0d23..4c9ec304ab9195abfd49fb5dcd2cadc18211fc88 100644
--- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp
+++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.cpp
@@ -5,19 +5,20 @@
 
 #include <Eigen/Geometry>
 
+#include <ArmarXCore/core/PackagePath.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <ArmarXCore/core/logging/Logging.h>
+
 #include "RobotAPI/libraries/armem/core/Commit.h"
 #include <RobotAPI/libraries/ArmarXObjects/ObjectInfo.h>
 #include <RobotAPI/libraries/ArmarXObjects/ObjectPose.h>
-#include <RobotAPI/libraries/ArmarXObjects/aron_conversions/objpose.h>
-#include <RobotAPI/libraries/armem_objects/aron_conversions.h>
-#include <ArmarXCore/core/PackagePath.h>
-#include <ArmarXCore/core/logging/Logging.h>
 #include <RobotAPI/libraries/ArmarXObjects/aron/ObjectPose.aron.generated.h>
+#include <RobotAPI/libraries/ArmarXObjects/aron_conversions/objpose.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem_objects/aron_conversions.h>
 #include <RobotAPI/libraries/armem_objects/constants.h>
 #include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot/aron_conversions.h>
@@ -30,20 +31,17 @@ namespace fs = ::std::filesystem;
 namespace armarx::armem::articulated_object
 {
 
-    Reader::Reader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
-    {
-    }
-
     void
-    Reader::connect()
+    Reader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
-        ARMARX_IMPORTANT << "Reader: Waiting for memory '" << objects::constants::MemoryName << "' ...";
+        ARMARX_IMPORTANT << "Reader: Waiting for memory '" << objects::constants::MemoryName
+                         << "' ...";
         try
         {
             memoryReader = memoryNameSystem.useReader(objects::constants::MemoryName);
-            ARMARX_IMPORTANT << "Reader: Connected to memory '" << objects::constants::MemoryName << "'";
+            ARMARX_IMPORTANT << "Reader: Connected to memory '" << objects::constants::MemoryName
+                             << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -96,7 +94,9 @@ namespace armarx::armem::articulated_object
     }
 
     std::optional<ArticulatedObject>
-    Reader::get(const std::string& name, const armem::Time& timestamp, const std::optional<std::string>& providerName)
+    Reader::get(const std::string& name,
+                const armem::Time& timestamp,
+                const std::optional<std::string>& providerName)
     {
         const auto splits = simox::alg::split(name, "/");
         ARMARX_CHECK_EQUAL(splits.size(), 3) << "`name` must be of form `DATASET/NAME/INSTANCE`";
@@ -118,7 +118,8 @@ namespace armarx::armem::articulated_object
     ArticulatedObject
     Reader::get(const ArticulatedObjectDescription& description,
                 const armem::Time& timestamp,
-                const std::string& instanceName, const std::optional<std::string>& providerName)
+                const std::string& instanceName,
+                const std::optional<std::string>& providerName)
     {
         ArticulatedObject obj{.description = description,
                               .instance = instanceName,
@@ -131,7 +132,9 @@ namespace armarx::armem::articulated_object
     }
 
     bool
-    Reader::synchronize(ArticulatedObject& obj, const armem::Time& timestamp, const std::optional<std::string>& providerName)
+    Reader::synchronize(ArticulatedObject& obj,
+                        const armem::Time& timestamp,
+                        const std::optional<std::string>& providerName)
     {
         ARMARX_CHECK_NOT_EMPTY(obj.instance) << "An instance name must be provided!";
 
@@ -148,7 +151,8 @@ namespace armarx::armem::articulated_object
     }
 
     std::vector<robot::RobotDescription>
-    Reader::queryDescriptions(const armem::Time& timestamp, const std::optional<std::string>& providerName)
+    Reader::queryDescriptions(const armem::Time& timestamp,
+                              const std::optional<std::string>& providerName)
     {
         // Query all entities from provider.
         armem::client::query::Builder qb;
@@ -174,12 +178,14 @@ namespace armarx::armem::articulated_object
     }
 
     std::optional<robot::RobotDescription>
-    Reader::queryDescription(const std::string& name, const armem::Time& timestamp, const std::optional<std::string>& providerName)
+    Reader::queryDescription(const std::string& name,
+                             const armem::Time& timestamp,
+                             const std::optional<std::string>& providerName)
     {
         // Query all entities from provider.
         armem::client::query::Builder qb;
 
-        if(providerName.has_value()) // query single provider
+        if (providerName.has_value()) // query single provider
         {
             // clang-format off
             qb
@@ -189,7 +195,7 @@ namespace armarx::armem::articulated_object
             .snapshots().beforeOrAtTime(timestamp);
             // clang-format on
         }
-        else // query all providers 
+        else // query all providers
         {
             // clang-format off
             qb
@@ -199,7 +205,7 @@ namespace armarx::armem::articulated_object
             .snapshots().beforeOrAtTime(timestamp);
             // clang-format on
         }
-        
+
 
         const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
 
@@ -215,7 +221,9 @@ namespace armarx::armem::articulated_object
     }
 
     std::optional<robot::RobotState>
-    Reader::queryState(const std::string& instanceName, const armem::Time& timestamp, const std::optional<std::string>& providerName)
+    Reader::queryState(const std::string& instanceName,
+                       const armem::Time& timestamp,
+                       const std::optional<std::string>& providerName)
     {
         // TODO(fabian.reister): how to deal with multiple providers?
 
@@ -242,7 +250,6 @@ namespace armarx::armem::articulated_object
         return getArticulatedObjectState(qResult.memory);
     }
 
-
     std::optional<robot::RobotState>
     convertToRobotState(const armem::wm::EntityInstance& instance)
     {
@@ -262,7 +269,8 @@ namespace armarx::armem::articulated_object
 
         robot::RobotState robotState{.timestamp = objectPose.timestamp,
                                      .globalPose = Eigen::Affine3f(objectPose.objectPoseGlobal),
-                                     .jointMap = objectPose.objectJointValues, .proprioception=std::nullopt};
+                                     .jointMap = objectPose.objectJointValues,
+                                     .proprioception = std::nullopt};
 
         return robotState;
     }
@@ -288,7 +296,6 @@ namespace armarx::armem::articulated_object
         return std::nullopt;
     }
 
-
     std::optional<robot::RobotDescription>
     Reader::getRobotDescription(const armarx::armem::wm::Memory& memory) const
     {
@@ -308,7 +315,6 @@ namespace armarx::armem::articulated_object
         return std::nullopt;
     }
 
-
     std::vector<robot::RobotDescription>
     Reader::getRobotDescriptions(const armarx::armem::wm::Memory& memory) const
     {
diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h
index fc8f1da389f443a90c12aa0c0fce70c24b53c3f1..0eb5bd104f4de49f3b7dfa6cc14ce232a99933fc 100644
--- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h
+++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Reader.h
@@ -39,11 +39,15 @@ namespace armarx::armem::articulated_object
     class Reader : virtual public ReaderInterface
     {
     public:
-        Reader(armem::client::MemoryNameSystem& memoryNameSystem);
+        Reader() = default;
         virtual ~Reader() = default;
 
-        void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def){}
-        void connect();
+        void
+        registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+        {
+        }
+
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         bool synchronize(ArticulatedObject& obj,
                          const armem::Time& timestamp,
@@ -88,8 +92,6 @@ namespace armarx::armem::articulated_object
 
         const std::string propertyPrefix = "mem.obj.articulated.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
-
         armem::client::Reader memoryReader;
         std::mutex memoryWriterMutex;
     };
diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp
index 20c3458aa7941cf7caa5a4a0dab9010f2267c035..b8755486996f7092e1687bcefc55f302566d62d2 100644
--- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp
+++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.cpp
@@ -22,15 +22,10 @@
 
 #include "utils.h"
 
-
 namespace armarx::armem::articulated_object
 {
-    Writer::Writer(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
-    {
-    }
-
-    void Writer::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+    void
+    Writer::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
         ARMARX_DEBUG << "Writer: registerPropertyDefinitions";
 
@@ -46,10 +41,12 @@ namespace armarx::armem::articulated_object
                       "Name of the memory core segment to use for object classes.");
 
         ARMARX_IMPORTANT << "Writer: add property '" << prefix << "ProviderName'";
-        def->required(properties.providerName, prefix + "write.ProviderName", "Name of this provider");
+        def->required(
+            properties.providerName, prefix + "write.ProviderName", "Name of this provider");
     }
 
-    void Writer::connect()
+    void
+    Writer::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "Writer: Waiting for memory '" << properties.memoryName << "' ...";
@@ -80,7 +77,8 @@ namespace armarx::armem::articulated_object
         memoryNameSystem.subscribe(id, this, &Writer::updateKnownObjects);
     }
 
-    void Writer::updateKnownObject(const armem::MemoryID& snapshotId)
+    void
+    Writer::updateKnownObject(const armem::MemoryID& snapshotId)
     {
         arondto::RobotDescription aronArticulatedObjectDescription;
         // aronArticulatedObjectDescription.fromAron(snapshotId.ent);
@@ -88,21 +86,24 @@ namespace armarx::armem::articulated_object
         // TODO(fabian.reister): implement
     }
 
-    void Writer::updateKnownObjects(const armem::MemoryID& subscriptionID,
-                                    const std::vector<armem::MemoryID>& snapshotIDs)
+    void
+    Writer::updateKnownObjects(const armem::MemoryID& subscriptionID,
+                               const std::vector<armem::MemoryID>& snapshotIDs)
     {
         ARMARX_INFO << "New objects available!";
         updateKnownObjects();
     }
 
-    void Writer::updateKnownObjects()
+    void
+    Writer::updateKnownObjects()
     {
         knownObjects = queryDescriptions(Time::Now());
 
         ARMARX_INFO << "Known articulated objects " << simox::alg::get_keys(knownObjects);
     }
 
-    std::optional<armem::MemoryID> Writer::storeOrGetClass(const ArticulatedObject& obj)
+    std::optional<armem::MemoryID>
+    Writer::storeOrGetClass(const ArticulatedObject& obj)
     {
         ARMARX_TRACE;
 
@@ -125,7 +126,8 @@ namespace armarx::armem::articulated_object
         return std::nullopt;
     }
 
-    std::optional<armem::MemoryID> Writer::storeClass(const ArticulatedObject& obj)
+    std::optional<armem::MemoryID>
+    Writer::storeClass(const ArticulatedObject& obj)
     {
         std::lock_guard g{memoryWriterMutex};
 
@@ -154,7 +156,7 @@ namespace armarx::armem::articulated_object
         toAron(aronArticulatedObjectDescription, obj.description);
 
         update.instancesData = {aronArticulatedObjectDescription.toAron()};
-        update.referencedTime   = timestamp;
+        update.referencedTime = timestamp;
 
         ARMARX_DEBUG << "Committing " << update << " at time " << timestamp;
         armem::EntityUpdateResult updateResult = memoryWriter.commit(update);
@@ -173,17 +175,20 @@ namespace armarx::armem::articulated_object
         return updateResult.snapshotID;
     }
 
-    std::string Writer::getProviderName() const
+    std::string
+    Writer::getProviderName() const
     {
         return properties.providerName;
     }
 
-    void Writer::setProviderName(const std::string& providerName)
+    void
+    Writer::setProviderName(const std::string& providerName)
     {
         this->properties.providerName = providerName;
     }
 
-    bool Writer::storeInstance(const ArticulatedObject& obj)
+    bool
+    Writer::storeInstance(const ArticulatedObject& obj)
     {
         std::lock_guard g{memoryWriterMutex};
 
@@ -192,12 +197,13 @@ namespace armarx::armem::articulated_object
         ARMARX_CHECK(not obj.instance.empty()) << "An object instance name must be provided!";
         const std::string entityName = obj.description.name + "/" + obj.instance;
 
-        ARMARX_DEBUG << "Storing articulated object instance '" << entityName << "' (provider '" << properties.providerName << "')";
+        ARMARX_DEBUG << "Storing articulated object instance '" << entityName << "' (provider '"
+                     << properties.providerName << "')";
 
         const auto providerId = armem::MemoryID()
-                                .withMemoryName(properties.memoryName)
-                                .withCoreSegmentName(properties.coreInstanceSegmentName)
-                                .withProviderSegmentName(properties.providerName);
+                                    .withMemoryName(properties.memoryName)
+                                    .withCoreSegmentName(properties.coreInstanceSegmentName)
+                                    .withProviderSegmentName(properties.providerName);
 
         armem::EntityUpdate update;
         update.entityID = providerId.withEntityName(entityName);
@@ -235,7 +241,7 @@ namespace armarx::armem::articulated_object
         objectInstance.pose.attachmentValid = false;
 
         update.instancesData = {objectInstance.toAron()};
-        update.referencedTime   = timestamp;
+        update.referencedTime = timestamp;
 
         ARMARX_DEBUG << "Committing " << update << " at time " << timestamp;
         armem::EntityUpdateResult updateResult = memoryWriter.commit(update);
@@ -250,7 +256,8 @@ namespace armarx::armem::articulated_object
         return updateResult.success;
     }
 
-    bool Writer::store(const ArticulatedObject& obj)
+    bool
+    Writer::store(const ArticulatedObject& obj)
     {
         const std::optional<armem::MemoryID> classId = storeOrGetClass(obj);
 
@@ -292,22 +299,23 @@ namespace armarx::armem::articulated_object
             memory.getCoreSegment(properties.coreClassSegmentName);
 
         std::unordered_map<std::string, armem::MemoryID> descriptions;
-        coreSegment.forEachEntity([&descriptions](const wm::Entity & entity)
-        {
-            if (entity.empty())
+        coreSegment.forEachEntity(
+            [&descriptions](const wm::Entity& entity)
             {
-                ARMARX_WARNING << "No entity found";
+                if (entity.empty())
+                {
+                    ARMARX_WARNING << "No entity found";
+                    return true;
+                }
+
+                const armem::wm::EntitySnapshot& sn = entity.getFirstSnapshot();
+                if (const auto robotDescription = convertRobotDescription(sn.getInstance(0)))
+                {
+                    const armem::MemoryID snapshotID(sn.id());
+                    descriptions.insert({robotDescription->name, snapshotID});
+                }
                 return true;
-            }
-
-            const armem::wm::EntitySnapshot& sn = entity.getFirstSnapshot();
-            if (const auto robotDescription = convertRobotDescription(sn.getInstance(0)))
-            {
-                const armem::MemoryID snapshotID(sn.id());
-                descriptions.insert({robotDescription->name, snapshotID});
-            }
-            return true;
-        });
+            });
 
         return descriptions;
     }
diff --git a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.h b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.h
index 3e827d66a496ddf8df4448788f39ca1c36722290..6245ef374edc289afa452900ee97e769ed4eae8b 100644
--- a/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.h
+++ b/source/RobotAPI/libraries/armem_objects/client/articulated_object/Writer.h
@@ -32,19 +32,17 @@
 
 #include "interfaces.h"
 
-
 namespace armarx::armem::articulated_object
 {
 
-    class Writer:
-        virtual public WriterInterface
+    class Writer : virtual public WriterInterface
     {
     public:
-        Writer(armem::client::MemoryNameSystem& memoryNameSystemopti);
+        Writer() = default;
         virtual ~Writer() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
 
         bool store(const ArticulatedObject& obj) override;
@@ -59,33 +57,33 @@ namespace armarx::armem::articulated_object
 
 
     private:
-
         std::optional<armem::MemoryID> storeOrGetClass(const ArticulatedObject& obj);
 
-        void updateKnownObjects(const armem::MemoryID& subscriptionID, const std::vector<armem::MemoryID>& snapshotIDs);
+        void updateKnownObjects(const armem::MemoryID& subscriptionID,
+                                const std::vector<armem::MemoryID>& snapshotIDs);
         void updateKnownObjects();
         void updateKnownObject(const armem::MemoryID& snapshotId);
 
         // TODO duplicate
-        std::unordered_map<std::string, armem::MemoryID> queryDescriptions(const armem::Time& timestamp);
-        std::optional<robot::RobotDescription> getRobotDescription(const armarx::armem::wm::Memory& memory) const;
-        std::unordered_map<std::string, armem::MemoryID> getRobotDescriptions(const armarx::armem::wm::Memory& memory) const;
-
+        std::unordered_map<std::string, armem::MemoryID>
+        queryDescriptions(const armem::Time& timestamp);
+        std::optional<robot::RobotDescription>
+        getRobotDescription(const armarx::armem::wm::Memory& memory) const;
+        std::unordered_map<std::string, armem::MemoryID>
+        getRobotDescriptions(const armarx::armem::wm::Memory& memory) const;
 
         struct Properties
         {
-            std::string memoryName              = "Object";
+            std::string memoryName = "Object";
             std::string coreInstanceSegmentName = "Instance";
-            std::string coreClassSegmentName    = "Class";
-            std::string providerName            = "";
+            std::string coreClassSegmentName = "Class";
+            std::string providerName = "";
 
-            bool allowClassCreation             = false;
+            bool allowClassCreation = false;
         } properties;
 
         const std::string propertyPrefix = "mem.obj.articulated.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
-
         armem::client::Writer memoryWriter;
         std::mutex memoryWriterMutex;
 
@@ -97,4 +95,4 @@ namespace armarx::armem::articulated_object
     };
 
 
-}  // namespace armarx::armem::articulated_object
+} // namespace armarx::armem::articulated_object
diff --git a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.cpp b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.cpp
index b2b740b735e933245a44bbfd3ce8d1c437ff30b2..399fce56d0cc22c10de24a8b1a4ab29eb6668581 100644
--- a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.cpp
+++ b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.cpp
@@ -21,11 +21,6 @@
 
 namespace armarx::armem::obj::instance
 {
-    Reader::Reader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
-    {
-    }
-
     void
     Reader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
@@ -35,7 +30,7 @@ namespace armarx::armem::obj::instance
     }
 
     void
-    Reader::connect()
+    Reader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "Waiting for memory '" << p.memoryName << "' ...";
@@ -48,8 +43,8 @@ namespace armarx::armem::obj::instance
             this->objPoseStorage =
                 objpose::ObjectPoseStorageInterfacePrx::checkedCast(r.readingPrx);
 
-            ARMARX_IMPORTANT << "Connected to Memory and ObjectPoseStorage '"
-                             << p.memoryName << "'";
+            ARMARX_IMPORTANT << "Connected to Memory and ObjectPoseStorage '" << p.memoryName
+                             << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -93,8 +88,6 @@ namespace armarx::armem::obj::instance
             return requestResult.results.at(requestObject).result.success;
         }
         return false;
-
-
     }
 
     std::optional<objpose::ObjectPose>
diff --git a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.h b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.h
index 81a0fc03092bbbe67c476d3e5f2146a28d62517a..18f52a6111d96525c0b5940b2e03084b8ff29a96 100644
--- a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.h
+++ b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectReader.h
@@ -45,11 +45,11 @@ namespace armarx::armem::obj::instance
             std::string memoryName = "Object";
         };
 
-        Reader(armem::client::MemoryNameSystem& memoryNameSystem);
+        Reader() = default;
         virtual ~Reader() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         // localization stuff. Requires an instance index to be set.
         std::map<std::string, bool> requestLocalization(const ObjectID& instanceId,
@@ -74,7 +74,8 @@ namespace armarx::armem::obj::instance
             return this->p;
         }
 
-        objpose::ObjectPoseStorageInterfacePrx getObjectPoseStorage() const
+        objpose::ObjectPoseStorageInterfacePrx
+        getObjectPoseStorage() const
         {
             return objPoseStorage;
         }
@@ -84,7 +85,6 @@ namespace armarx::armem::obj::instance
 
         const std::string propertyPrefix = "mem.obj.instance.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
         objpose::ObjectPoseStorageInterfacePrx objPoseStorage;
     };
 
diff --git a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.cpp b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.cpp
index 8ee596b27069f82c9ff19d63efcd40e7cc819699..80d1af5590886994c04a69adb025d2767b8f7ffb 100644
--- a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.cpp
+++ b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.cpp
@@ -3,29 +3,29 @@
 #include <mutex>
 #include <optional>
 
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/PackagePath.h>
+#include <ArmarXCore/core/logging/Logging.h>
 
+#include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/util/util.h>
-#include <RobotAPI/libraries/armem_robot/robot_conversions.h>
-#include <RobotAPI/libraries/armem_robot/aron_conversions.h>
-#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
 #include <RobotAPI/libraries/armem_objects/aron/Attachment.aron.generated.h>
 #include <RobotAPI/libraries/armem_objects/aron_conversions.h>
+#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
+#include <RobotAPI/libraries/armem_robot/aron_conversions.h>
+#include <RobotAPI/libraries/armem_robot/robot_conversions.h>
 #include <RobotAPI/libraries/aron/common/aron_conversions.h>
 
-
 namespace armarx::armem::obj::instance
 {
-    Writer::Writer(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
-    {}
+    Writer::Writer()
+    {
+    }
 
-    void Writer::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+    void
+    Writer::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
         ARMARX_DEBUG << "Writer: registerPropertyDefinitions";
 
@@ -38,8 +38,8 @@ namespace armarx::armem::obj::instance
                       "Name of the memory core segment to use for object instances.");
     }
 
-
-    void Writer::connect()
+    void
+    Writer::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "Writer: Waiting for memory '" << properties.memoryName << "' ...";
@@ -55,7 +55,10 @@ namespace armarx::armem::obj::instance
         }
     }
 
-    bool Writer::commitObject(const armem::arondto::ObjectInstance& inst, const std::string& provider, const armem::Time& t)
+    bool
+    Writer::commitObject(const armem::arondto::ObjectInstance& inst,
+                         const std::string& provider,
+                         const armem::Time& t)
     {
         armem::Commit c;
         auto& e = c.add();
@@ -63,19 +66,21 @@ namespace armarx::armem::obj::instance
         e.entityID.memoryName = properties.memoryName;
         e.entityID.coreSegmentName = properties.coreSegmentName;
         e.entityID.providerSegmentName = provider;
-        e.entityID.entityName = inst.pose.objectID.dataset + "/" + inst.pose.objectID.className + "/" + inst.pose.objectID.instanceName;
+        e.entityID.entityName = inst.pose.objectID.dataset + "/" + inst.pose.objectID.className +
+                                "/" + inst.pose.objectID.instanceName;
         e.referencedTime = t;
         e.sentTime = armem::Time::Now();
-        e.instancesData = { inst.toAron() };
+        e.instancesData = {inst.toAron()};
 
         auto res = memoryWriter.commit(c);
 
-        if(!res.allSuccess())
+        if (!res.allSuccess())
         {
-            ARMARX_ERROR << "Failed to commit an ObjectInstance to memory: " << res.allErrorMessages();
+            ARMARX_ERROR << "Failed to commit an ObjectInstance to memory: "
+                         << res.allErrorMessages();
             return false;
         }
         return true;
     }
 
-}  // namespace armarx::armem::instance
+} // namespace armarx::armem::obj::instance
diff --git a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.h b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.h
index 972227993aa5c6369ff656a594fa2e2005b0f9dd..d449502849b09de61e3abc65ab0364928502a083 100644
--- a/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.h
+++ b/source/RobotAPI/libraries/armem_objects/client/instance/ObjectWriter.h
@@ -28,40 +28,37 @@
 
 #include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
 #include <RobotAPI/libraries/armem/client/Writer.h>
-#include <RobotAPI/libraries/armem_objects/types.h>
-
 #include <RobotAPI/libraries/armem_objects/aron/ObjectInstance.aron.generated.h>
-
+#include <RobotAPI/libraries/armem_objects/types.h>
 
 namespace armarx::armem::obj::instance
 {
     class Writer
     {
     public:
-        Writer(armem::client::MemoryNameSystem& memoryNameSystem);
+        Writer();
         virtual ~Writer() = default;
 
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def);
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
-        bool commitObject(const armem::arondto::ObjectInstance& inst, const std::string& provider, const armem::Time&);
+        bool commitObject(const armem::arondto::ObjectInstance& inst,
+                          const std::string& provider,
+                          const armem::Time&);
 
 
     private:
-
-
         struct Properties
         {
-            std::string memoryName                  = "Object";
-            std::string coreSegmentName             = "Instance";
+            std::string memoryName = "Object";
+            std::string coreSegmentName = "Instance";
         } properties;
 
         const std::string propertyPrefix = "mem.obj.instance.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Writer memoryWriter;
         mutable std::mutex memoryWriterMutex;
     };
 
 
-}  // namespace armarx::armem::instance
+} // namespace armarx::armem::obj::instance
diff --git a/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml b/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml
index bfb14cb23d8dd6a169b5b9bd916723af9cbd6a2a..db6a0a9c5898f6332df65199da67c0b4b7b16c1c 100644
--- a/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml
+++ b/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml
@@ -267,6 +267,31 @@
                 </Dict>
             </ObjectChild>
 
+            <ObjectChild key="extraBools">
+                <Dict>
+                    <bool />
+                </Dict>
+            </ObjectChild>
+
+            <ObjectChild key="extraShorts">
+                <Dict>
+                    <int32 />
+                </Dict>
+            </ObjectChild>
+
+            <ObjectChild key="extraInts">
+                <Dict>
+                    <int32 />
+                </Dict>
+            </ObjectChild>
+
+            <ObjectChild key="extraBytes">
+                <Dict>
+                    <int32 />
+                </Dict>
+            </ObjectChild>
+
+
         </Object>
 
             
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp
index 5fb5004c926f4997a9b3e252e8a882c92d0462ea..a8280d7e93ee5513449571a8c13d8ee086c9843d 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp
@@ -31,10 +31,11 @@ namespace fs = ::std::filesystem;
 
 namespace armarx::armem::robot_state
 {
-
-
-    RobotReader::RobotReader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem), transformReader(memoryNameSystem)
+    RobotReader::RobotReader(const RobotReader& r) :
+        properties(r.properties),
+        propertyPrefix(r.propertyPrefix),
+        memoryReader(r.memoryReader),
+        transformReader(r.transformReader)
     {
     }
 
@@ -45,17 +46,16 @@ namespace armarx::armem::robot_state
     }
 
     void
-    RobotReader::connect()
+    RobotReader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
-        transformReader.connect();
+        transformReader.connect(memoryNameSystem);
 
         // Wait for the memory to become available and add it as dependency.
-        ARMARX_IMPORTANT << "RobotReader: Waiting for memory '" << constants::memoryName << "' ...";
+        ARMARX_INFO << "RobotReader: Waiting for memory '" << constants::memoryName << "' ...";
         try
         {
             memoryReader = memoryNameSystem.useReader(constants::memoryName);
-            ARMARX_IMPORTANT << "RobotReader: Connected to memory '" << constants::memoryName
-                             << "'";
+            ARMARX_INFO << "RobotReader: Connected to memory '" << constants::memoryName << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -86,7 +86,7 @@ namespace armarx::armem::robot_state
                            .config = {}, // will be populated by synchronize
                            .timestamp = timestamp};
 
-        synchronize(robot, timestamp);
+        ARMARX_CHECK(synchronize(robot, timestamp));
 
         return robot;
     }
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.h b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.h
index 6f90a9b249286efb7d1db277ef3df492e0dd8319..dbf81e69a9e4cbc8e488df482634d3542487376c 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.h
@@ -32,7 +32,6 @@
 #include <RobotAPI/libraries/armem_robot/types.h>
 #include <RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.h>
 
-
 namespace armarx::armem::robot_state
 {
     /**
@@ -44,14 +43,16 @@ namespace armarx::armem::robot_state
     class RobotReader : virtual public robot::ReaderInterface
     {
     public:
-        RobotReader(armem::client::MemoryNameSystem& memoryNameSystem);
+        RobotReader() = default;
+        RobotReader(const RobotReader&);
         virtual ~RobotReader() = default;
 
-        virtual void connect();
+        virtual void connect(armem::client::MemoryNameSystem& memoryNameSystem);
 
         virtual void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def);
 
-        [[nodiscard]] bool synchronize(robot::Robot& obj, const armem::Time& timestamp) const override;
+        [[nodiscard]] bool synchronize(robot::Robot& obj,
+                                       const armem::Time& timestamp) const override;
 
         std::optional<robot::Robot> get(const std::string& name,
                                         const armem::Time& timestamp) const override;
@@ -68,7 +69,7 @@ namespace armarx::armem::robot_state
 
         std::optional<armarx::armem::arondto::Proprioception>
         queryProprioception(const robot::RobotDescription& description,
-                        const armem::Time& timestamp) const;
+                            const armem::Time& timestamp) const;
 
         using JointTrajectory = std::map<armem::Time, robot::RobotState::JointMap>;
 
@@ -135,7 +136,8 @@ namespace armarx::armem::robot_state
         getRobotDescriptions(const armarx::armem::wm::Memory& memory) const;
 
         std::optional<armarx::armem::arondto::Proprioception>
-        getRobotProprioception(const armarx::armem::wm::Memory& memory, const std::string& name) const;
+        getRobotProprioception(const armarx::armem::wm::Memory& memory,
+                               const std::string& name) const;
 
         JointTrajectory getRobotJointStates(const armarx::armem::wm::Memory& memory,
                                             const std::string& name) const;
@@ -160,9 +162,8 @@ namespace armarx::armem::robot_state
 
         const std::string propertyPrefix = "mem.robot_state.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Reader memoryReader;
-        std::mutex memoryWriterMutex;
+        mutable std::mutex memoryWriterMutex;
 
         client::robot_state::localization::TransformReader transformReader;
     };
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.cpp
index f971c88c3e41bf962500a1ac49e0b5ad7e5a39be..e92e13d6421c71313bdd04a488e1f43397d1f222 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.cpp
@@ -34,21 +34,20 @@ namespace fs = ::std::filesystem;
 
 namespace armarx::armem::robot_state
 {
-    RobotWriter::~RobotWriter() = default;
-
-
-    RobotWriter::RobotWriter(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem)
+    RobotWriter::RobotWriter(const RobotWriter& r) :
+        properties(r.properties), propertyPrefix(r.propertyPrefix), memoryWriter(r.memoryWriter)
     {
     }
 
+    RobotWriter::~RobotWriter() = default;
+
     void
     RobotWriter::registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def)
     {
     }
 
     void
-    RobotWriter::connect()
+    RobotWriter::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
         ARMARX_IMPORTANT << "RobotWriter: Waiting for memory '" << constants::memoryName << "' ...";
@@ -65,7 +64,6 @@ namespace armarx::armem::robot_state
         }
     }
 
-
     bool
     RobotWriter::storeDescription(const robot::RobotDescription& description,
                                   const armem::Time& timestamp)
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.h b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.h
index f1e20614ee4ee45880e75d98ef223709b85932ae..d8ca351d6cf8643960f1707a49ef26b9697d4082 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotWriter.h
@@ -32,7 +32,6 @@
 #include <RobotAPI/libraries/armem_robot/types.h>
 #include <RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.h>
 
-
 namespace armarx::armem::robot_state
 {
     /**
@@ -44,10 +43,11 @@ namespace armarx::armem::robot_state
     class RobotWriter : virtual public robot::WriterInterface
     {
     public:
-        RobotWriter(armem::client::MemoryNameSystem& memoryNameSystem);
+        RobotWriter() = default;
+        RobotWriter(const RobotWriter&);
         ~RobotWriter() override;
 
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
         void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def);
 
 
@@ -72,7 +72,6 @@ namespace armarx::armem::robot_state
                                                const std::string& robotName,
                                                const armem::Time& timestamp);
 
-
         struct Properties
         {
 
@@ -80,9 +79,7 @@ namespace armarx::armem::robot_state
 
         const std::string propertyPrefix = "mem.robot_state.";
 
-        armem::client::MemoryNameSystem& memoryNameSystem;
-
-        std::mutex memoryWriterMutex;
+        mutable std::mutex memoryWriterMutex;
         armem::client::Writer memoryWriter;
     };
 
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp
index 0e972f79138fbfc973dbab543206d94965227f03..0effa5c23d6763ff984610100b1770024e452bee 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp
@@ -15,34 +15,28 @@
 
 namespace armarx::armem::robot_state
 {
-
-    VirtualRobotReader::VirtualRobotReader(armem::client::MemoryNameSystem& memoryNameSystem) :
-            RobotReader(memoryNameSystem)
-    {
-    }
-
-    void VirtualRobotReader::connect()
-    {
-        RobotReader::connect();
-    }
-
     // TODO(fabian.reister): register property defs
-    void VirtualRobotReader::registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def)
+    void
+    VirtualRobotReader::registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def)
     {
         RobotReader::registerPropertyDefinitions(def);
     }
 
-    bool VirtualRobotReader::synchronizeRobot(VirtualRobot::Robot& robot, const armem::Time& timestamp) const
+    bool
+    VirtualRobotReader::synchronizeRobot(VirtualRobot::Robot& robot,
+                                         const armem::Time& timestamp) const
     {
         // const static auto packages = armarx::CMakePackageFinder::FindAllArmarXSourcePackages();
         // const auto package = armarx::ArmarXDataPath::getProject(packages, robot.getFilename());
 
-        const robot::RobotDescription robotDescription{.name = robot.getName(), .xml = PackagePath{"", ""}};
+        const robot::RobotDescription robotDescription{.name = robot.getName(),
+                                                       .xml = PackagePath{"", ""}};
 
         const auto robotState = queryState(robotDescription, timestamp);
         if (not robotState)
         {
-            ARMARX_VERBOSE << deactivateSpam(5) << "Querying robot state failed for robot `" << robot.getName() << "` "
+            ARMARX_VERBOSE << deactivateSpam(5) << "Querying robot state failed for robot `"
+                           << robot.getName() << "` "
                            << "(type `" << robot.getType() << "`)!";
             return false;
         }
@@ -53,15 +47,19 @@ namespace armarx::armem::robot_state
         return true;
     }
 
-    VirtualRobot::RobotPtr VirtualRobotReader::getRobot(const std::string& name, const armem::Time& timestamp,
-                                                        const VirtualRobot::RobotIO::RobotDescription& loadMode)
+    VirtualRobot::RobotPtr
+    VirtualRobotReader::getRobot(const std::string& name,
+                                 const armem::Time& timestamp,
+                                 const VirtualRobot::RobotIO::RobotDescription& loadMode)
     {
-        ARMARX_VERBOSE << deactivateSpam(60) << "Querying robot description for robot '" << name << "'";
+        ARMARX_VERBOSE << deactivateSpam(60) << "Querying robot description for robot '" << name
+                       << "'";
         const auto description = queryDescription(name, timestamp);
 
         if (not description)
         {
-            ARMARX_VERBOSE << deactivateSpam(5) << "The description of robot `" << name << "` is not a available!";
+            ARMARX_VERBOSE << deactivateSpam(5) << "The description of robot `" << name
+                           << "` is not a available!";
 
             return nullptr;
         }
@@ -69,8 +67,8 @@ namespace armarx::armem::robot_state
         const std::string xmlFilename = description->xml.toSystemPath();
         ARMARX_CHECK(std::filesystem::exists(xmlFilename)) << xmlFilename;
 
-        ARMARX_VERBOSE << deactivateSpam(5) << "Loading (virtual) robot '" << description->name << "' from XML file '"
-                       << xmlFilename << "'";
+        ARMARX_VERBOSE << deactivateSpam(5) << "Loading (virtual) robot '" << description->name
+                       << "' from XML file '" << xmlFilename << "'";
 
         auto robot = VirtualRobot::RobotIO::loadRobot(xmlFilename, loadMode);
         ARMARX_CHECK_NOT_NULL(robot) << "Could not load robot from file `" << xmlFilename << "`";
@@ -80,24 +78,30 @@ namespace armarx::armem::robot_state
         return robot;
     }
 
-    VirtualRobot::RobotPtr VirtualRobotReader::getSynchronizedRobot(const std::string& name,
-                                                                    const VirtualRobot::BaseIO::RobotDescription& loadMode,
-                                                                    bool blocking)
+    VirtualRobot::RobotPtr
+    VirtualRobotReader::getSynchronizedRobot(const std::string& name,
+                                             const VirtualRobot::BaseIO::RobotDescription& loadMode,
+                                             bool blocking)
     {
         return _getSynchronizedRobot(name, armem::Time::Invalid(), loadMode, blocking);
     }
 
     VirtualRobot::RobotPtr
-    VirtualRobotReader::getSynchronizedRobot(const std::string& name, const armem::Time& timestamp,
-                                             const VirtualRobot::RobotIO::RobotDescription& loadMode,
-                                             const bool blocking)
+    VirtualRobotReader::getSynchronizedRobot(
+        const std::string& name,
+        const armem::Time& timestamp,
+        const VirtualRobot::RobotIO::RobotDescription& loadMode,
+        const bool blocking)
     {
         return _getSynchronizedRobot(name, timestamp, loadMode, blocking);
     }
 
-    VirtualRobot::RobotPtr VirtualRobotReader::_getSynchronizedRobot(const std::string& name, const Time& timestamp,
-                                                                     const VirtualRobot::BaseIO::RobotDescription& loadMode,
-                                                                     bool blocking)
+    VirtualRobot::RobotPtr
+    VirtualRobotReader::_getSynchronizedRobot(
+        const std::string& name,
+        const Time& timestamp,
+        const VirtualRobot::BaseIO::RobotDescription& loadMode,
+        bool blocking)
     {
         while (blocking)
         {
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h
index 7a2f39c17939d30b26ef75057e1c9d302b0f68a8..1d91f05829b1c49fc5a07782ecbead486e075a5c 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h
@@ -40,10 +40,10 @@ namespace armarx::armem::robot_state
     class VirtualRobotReader : virtual public RobotReader
     {
     public:
-        VirtualRobotReader(armem::client::MemoryNameSystem& memoryNameSystem);
+        using RobotReader::RobotReader;
+
         ~VirtualRobotReader() override = default;
 
-        void connect() override;
         void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def) override;
 
         [[nodiscard]] bool synchronizeRobot(VirtualRobot::Robot& robot,
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.cpp
index fc3aed1eea251e199077d92ccb615249b1777570..e7525729d3f6d59d4bb8c3feaf237f5ff34d18de 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.cpp
@@ -18,23 +18,15 @@
 
 #include "constants.h"
 
-
 namespace armarx::armem::robot_state
 {
 
-    VirtualRobotWriter::VirtualRobotWriter(armem::client::MemoryNameSystem& memoryNameSystem) :
-        RobotWriter(memoryNameSystem)
-    {
-    }
-
-
     VirtualRobotWriter::~VirtualRobotWriter() = default;
 
-
     void
-    VirtualRobotWriter::connect()
+    VirtualRobotWriter::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
-        RobotWriter::connect();
+        RobotWriter::connect(memoryNameSystem);
     }
 
     // TODO(fabian.reister): register property defs
@@ -70,12 +62,14 @@ namespace armarx::armem::robot_state
         const robot::RobotState robotState{.timestamp = timestamp,
                                            .globalPose =
                                                robot::RobotState::Pose(robot.getGlobalPose()),
-                                           .jointMap = robot.getJointValues(), .proprioception=std::nullopt};
-
-        return RobotWriter::storeState(robotState,
-                                       robot.getType(),
-                                       robot.getName(),
-                                       constants::robotRootNodeName /*robot.getRootNode()->getName()*/);
+                                           .jointMap = robot.getJointValues(),
+                                           .proprioception = std::nullopt};
+
+        return RobotWriter::storeState(
+            robotState,
+            robot.getType(),
+            robot.getName(),
+            constants::robotRootNodeName /*robot.getRootNode()->getName()*/);
     }
 
 
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.h b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.h
index 260032c62a1ec4db1a68e78e0660125ba7f37826..29a009714506d069ebd05dcbc988acc64eafe1de 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.h
@@ -29,7 +29,6 @@
 
 #include "RobotWriter.h"
 
-
 namespace armarx::armem::robot_state
 {
     /**
@@ -43,10 +42,10 @@ namespace armarx::armem::robot_state
     class VirtualRobotWriter : virtual public RobotWriter
     {
     public:
-        VirtualRobotWriter(armem::client::MemoryNameSystem& memoryNameSystem);
+        VirtualRobotWriter() = default;
         ~VirtualRobotWriter() override;
 
-        void connect();
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem);
         void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def);
 
         [[nodiscard]] bool storeDescription(const VirtualRobot::Robot& robot,
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.cpp b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.cpp
index 21b8e55a9fa9c74d63f61dc67aea86bce381c01f..51739021f56c5b87a47b930fa39cd51a8358607d 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.cpp
@@ -38,39 +38,31 @@
 #include <SimoxUtility/math/pose/interpolate.h>
 
 // ArmarX
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/time/CycleUtil.h>
 
 // this package
-#include <RobotAPI/libraries/core/FramedPose.h>
-
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
 #include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
-
-#include <RobotAPI/libraries/aron/core/type/variant/Factory.h>
-
-#include <RobotAPI/libraries/armem_robot_state/aron_conversions.h>
 #include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h>
-#include <RobotAPI/libraries/armem_robot_state/common/localization/types.h>
+#include <RobotAPI/libraries/armem_robot_state/aron_conversions.h>
 #include <RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h>
-
+#include <RobotAPI/libraries/armem_robot_state/common/localization/types.h>
+#include <RobotAPI/libraries/aron/core/type/variant/Factory.h>
+#include <RobotAPI/libraries/core/FramedPose.h>
 
 namespace armarx::armem::client::robot_state::localization
 {
-
-    TransformReader::TransformReader(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem) {}
-
     TransformReader::~TransformReader() = default;
 
-    void TransformReader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+    void
+    TransformReader::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
         ARMARX_DEBUG << "TransformReader: registerPropertyDefinitions";
 
@@ -83,15 +75,15 @@ namespace armarx::armem::client::robot_state::localization
         def->optional(properties.memoryName, prefix + "Memory");
     }
 
-    void TransformReader::connect()
+    void
+    TransformReader::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
-        ARMARX_IMPORTANT << "TransformReader: Waiting for memory '" << properties.memoryName
-                         << "' ...";
+        ARMARX_INFO << "TransformReader: Waiting for memory '" << properties.memoryName << "' ...";
         try
         {
             memoryReader = memoryNameSystem.useReader(properties.memoryName);
-            ARMARX_IMPORTANT << "TransformReader: Connected to memory '" << properties.memoryName;
+            ARMARX_INFO << "TransformReader: Connected to memory '" << properties.memoryName;
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -100,15 +92,15 @@ namespace armarx::armem::client::robot_state::localization
         }
     }
 
-    TransformResult TransformReader::getGlobalPose(const std::string& agentName,
-            const std::string& robotRootFrame,
-            const armem::Time& timestamp) const
+    TransformResult
+    TransformReader::getGlobalPose(const std::string& agentName,
+                                   const std::string& robotRootFrame,
+                                   const armem::Time& timestamp) const
     {
         const TransformQuery query{.header = {.parentFrame = GlobalFrame,
-                                              .frame       = robotRootFrame,
-                                              .agent       = agentName,
-                                              .timestamp   = timestamp
-                                             }};
+                                              .frame = robotRootFrame,
+                                              .agent = agentName,
+                                              .timestamp = timestamp}};
 
         return lookupTransform(query);
     }
@@ -135,13 +127,14 @@ namespace armarx::armem::client::robot_state::localization
     // }
 
 
-    TransformResult TransformReader::lookupTransform(const TransformQuery& query) const
+    TransformResult
+    TransformReader::lookupTransform(const TransformQuery& query) const
     {
         const auto& timestamp = query.header.timestamp;
         ARMARX_DEBUG << "Looking up transform at timestamp " << timestamp;
 
         const IceUtil::Time durationEpsilon = IceUtil::Time::milliSeconds(-1);
-        (void) durationEpsilon;
+        (void)durationEpsilon;
 
         // Query all entities from provider.
         armem::client::query::Builder qb;
@@ -159,22 +152,20 @@ namespace armarx::armem::client::robot_state::localization
 
         if (not qResult.success)
         {
-            return
-            {
-                .transform =
-                {
-                    .header = query.header,
-                },
-                .status       = TransformResult::Status::ErrorFrameNotAvailable,
-                .errorMessage = "Error in tf lookup '" + query.header.parentFrame + " -> " +
-                query.header.frame + "' : " + qResult.errorMessage
-            };
+            return {.transform =
+                        {
+                            .header = query.header,
+                        },
+                    .status = TransformResult::Status::ErrorFrameNotAvailable,
+                    .errorMessage = "Error in tf lookup '" + query.header.parentFrame + " -> " +
+                                    query.header.frame + "' : " + qResult.errorMessage};
         }
 
-        const auto& localizationCoreSegment = qResult.memory.getCoreSegment(properties.localizationSegment);
+        const auto& localizationCoreSegment =
+            qResult.memory.getCoreSegment(properties.localizationSegment);
 
         using armarx::armem::common::robot_state::localization::TransformHelper;
         return TransformHelper::lookupTransform(localizationCoreSegment, query);
     }
 
-}  // namespace armarx::armem::client::robot_state::localization
+} // namespace armarx::armem::client::robot_state::localization
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.h b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.h
index 433694ec819859bdcda209dd57aad21d22512116..4d9ee5983e783e41b7e24cbce982ca65e8ed7057 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformReader.h
@@ -40,15 +40,15 @@ namespace armarx::armem::client::robot_state::localization
     *
     * Detailed description of class ExampleClient.
     */
-    class TransformReader :
-        virtual public TransformReaderInterface
+    class TransformReader : virtual public TransformReaderInterface
     {
     public:
-        TransformReader(armem::client::MemoryNameSystem& memoryNameSystem);
+        TransformReader() = default;
+        TransformReader(const TransformReader&) = default;
 
         ~TransformReader() override;
 
-        void connect() override;
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem) override;
 
         TransformResult getGlobalPose(const std::string& agentName,
                                       const std::string& robotRootFrame,
@@ -59,18 +59,15 @@ namespace armarx::armem::client::robot_state::localization
         void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def) override;
 
     private:
-
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Reader memoryReader;
 
         // Properties
         struct Properties
         {
-            std::string memoryName             = "RobotState";
-            std::string localizationSegment    = "Localization";
+            std::string memoryName = "RobotState";
+            std::string localizationSegment = "Localization";
         } properties;
 
-
         const std::string propertyPrefix = "mem.robot_state.";
     };
-}  // namespace armarx::armem::client::robot_state::localization
+} // namespace armarx::armem::client::robot_state::localization
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.cpp b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.cpp
index 9f93ae53156e0da1e126ed7cc922905eb2f0796b..f01f8e9241a5ebc605c6b158f3256407a5e9bd17 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.cpp
@@ -21,45 +21,38 @@
 
 #include "TransformWriter.h"
 
-#include <optional>
 #include <algorithm>
 #include <iterator>
 #include <numeric>
+#include <optional>
 
 #include <Eigen/Geometry>
 
 #include <IceUtil/Time.h>
 
 #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/time/CycleUtil.h>
 
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
+#include <RobotAPI/libraries/armem/core/MemoryID.h>
+#include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
-#include <RobotAPI/libraries/aron/core/type/variant/Factory.h>
-#include <RobotAPI/libraries/core/FramedPose.h>
-
 #include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot_state/aron_conversions.h>
-#include <RobotAPI/libraries/armem/core/MemoryID.h>
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
+#include <RobotAPI/libraries/aron/core/type/variant/Factory.h>
+#include <RobotAPI/libraries/core/FramedPose.h>
 
 namespace armarx::armem::client::robot_state::localization
 {
-
-    TransformWriter::TransformWriter(armem::client::MemoryNameSystem& memoryNameSystem) :
-        memoryNameSystem(memoryNameSystem) {}
-
     TransformWriter::~TransformWriter() = default;
 
-    void TransformWriter::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
+    void
+    TransformWriter::registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def)
     {
         ARMARX_DEBUG << "TransformWriter: registerPropertyDefinitions";
 
@@ -69,15 +62,17 @@ namespace armarx::armem::client::robot_state::localization
                       "Name of the localization memory core segment to use.");
     }
 
-    void TransformWriter::connect()
+    void
+    TransformWriter::connect(armem::client::MemoryNameSystem& memoryNameSystem)
     {
         // Wait for the memory to become available and add it as dependency.
-        ARMARX_IMPORTANT << "TransformWriter: Waiting for memory '" << properties.coreSegmentID.memoryName
-                         << "' ...";
+        ARMARX_IMPORTANT << "TransformWriter: Waiting for memory '"
+                         << properties.coreSegmentID.memoryName << "' ...";
         try
         {
             memoryWriter = memoryNameSystem.useWriter(properties.coreSegmentID);
-            ARMARX_IMPORTANT << "TransformWriter: Connected to memory for '" << properties.coreSegmentID << "'";
+            ARMARX_IMPORTANT << "TransformWriter: Connected to memory for '"
+                             << properties.coreSegmentID << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -86,15 +81,17 @@ namespace armarx::armem::client::robot_state::localization
         }
     }
 
-    bool TransformWriter::commitTransform(const ::armarx::armem::robot_state::Transform& transform)
+    bool
+    TransformWriter::commitTransform(const ::armarx::armem::robot_state::Transform& transform)
     {
         std::lock_guard g{memoryWriterMutex};
 
-        const MemoryID providerId = properties.coreSegmentID.withProviderSegmentName(transform.header.agent);
+        const MemoryID providerId =
+            properties.coreSegmentID.withProviderSegmentName(transform.header.agent);
         // const auto& timestamp = transform.header.timestamp;
-        const MemoryID entityID = providerId.withEntityName(
-                                      transform.header.parentFrame + "," + transform.header.frame);
-        const Time timestamp = Time::Now();  // FIXME remove
+        const MemoryID entityID =
+            providerId.withEntityName(transform.header.parentFrame + "," + transform.header.frame);
+        const Time timestamp = Time::Now(); // FIXME remove
 
         armem::EntityUpdate update;
         update.entityID = entityID;
@@ -117,4 +114,4 @@ namespace armarx::armem::client::robot_state::localization
         return updateResult.success;
     }
 
-}  // namespace armarx::armem::client::robot_state::localization
+} // namespace armarx::armem::client::robot_state::localization
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.h b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.h
index e553b073464e5fcf1444e14a4fef48e2034e808c..182981846d14eb775256b3a29aeed9e2a4eb483b 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/localization/TransformWriter.h
@@ -29,7 +29,6 @@
 
 #include "interfaces.h"
 
-
 namespace armarx::armem::client::robot_state::localization
 {
 
@@ -44,17 +43,15 @@ namespace armarx::armem::client::robot_state::localization
     *
     * Detailed description of class ExampleClient.
     */
-    class TransformWriter :
-        virtual public TransformWriterInterface
+    class TransformWriter : virtual public TransformWriterInterface
     {
     public:
-
-        TransformWriter(armem::client::MemoryNameSystem& memoryNameSystem);
+        TransformWriter() = default;
         ~TransformWriter() override;
 
         // TransformWriterInterface
         /// to be called in Component::onConnectComponent
-        void connect() override;
+        void connect(armem::client::MemoryNameSystem& memoryNameSystem) override;
 
         /// to be called in Component::addPropertyDefinitions
         void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr& def) override;
@@ -63,18 +60,16 @@ namespace armarx::armem::client::robot_state::localization
 
 
     private:
-
-        armem::client::MemoryNameSystem& memoryNameSystem;
         armem::client::Writer memoryWriter;
         std::mutex memoryWriterMutex;
 
         // Properties
         struct Properties
         {
-            MemoryID coreSegmentID { "RobotState", "Localization" };
+            MemoryID coreSegmentID{"RobotState", "Localization"};
         } properties;
 
         const std::string propertyPrefix = "mem.robot_state.";
     };
 
-}  // namespace armarx::armem::client::robot_state::localization
+} // namespace armarx::armem::client::robot_state::localization
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/localization/interfaces.h b/source/RobotAPI/libraries/armem_robot_state/client/localization/interfaces.h
index ae35822c6080701195c0e6d7d8b6c8c4ad282684..5689058cc27f39dbe86b0e5e1b3171466407ac50 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/localization/interfaces.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/localization/interfaces.h
@@ -26,6 +26,7 @@
 
 #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 
+#include <RobotAPI/libraries/armem/client/MemoryNameSystem.h>
 #include <RobotAPI/libraries/armem_robot_state/common/localization/types.h>
 #include <RobotAPI/libraries/armem_robot_state/types.h>
 
@@ -41,7 +42,7 @@ namespace armarx::armem::client::robot_state::localization
         virtual ~TransformInterface() = default;
 
         virtual void registerPropertyDefinitions(PropertyDefinitionsPtr& def) = 0;
-        virtual void connect()                                                = 0;
+        virtual void connect(armem::client::MemoryNameSystem& memoryNameSystem) = 0;
     };
 
     class TransformReaderInterface : virtual public TransformInterface
@@ -65,4 +66,4 @@ namespace armarx::armem::client::robot_state::localization
         virtual bool commitTransform(const ::armarx::armem::robot_state::Transform& transform) = 0;
     };
 
-} // namespace armarx::armem::client::robot_state::localization
\ No newline at end of file
+} // namespace armarx::armem::client::robot_state::localization
diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/Armar6Converter.cpp b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/Armar6Converter.cpp
index 4dda540b2596801f1492c4ae8ac532455af002a4..dcbe1b7783190849e6a5d8d442a0124ca22c1b4c 100644
--- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/Armar6Converter.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/Armar6Converter.cpp
@@ -1,8 +1,10 @@
 #include "Armar6Converter.h"
+#include <cstddef>
 
 #include <SimoxUtility/algorithm/get_map_keys_values.h>
 #include <SimoxUtility/algorithm/advanced.h>
 
+#include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h>
 #include <RobotAPI/libraries/RobotUnitDataStreamingReceiver/RobotUnitDataStreamingReceiver.h>
 #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
 
@@ -86,6 +88,18 @@ namespace armarx::armem::server::robot_state::proprioception
                     case RobotUnitDataStreaming::NodeTypeLong:
                         dto.extraLongs[key] = getValueAs<long>(value);
                         break;
+                    case RobotUnitDataStreaming::NodeTypeBool:
+                        dto.extraBools[key] = getValueAs<bool>(value);
+                        break;
+                    case RobotUnitDataStreaming::NodeTypeInt:
+                        dto.extraInts[key] = getValueAs<int>(value);
+                        break;
+                    case RobotUnitDataStreaming::NodeTypeShort:
+                        dto.extraShorts[key] = getValueAs<Ice::Short>(value);
+                        break;
+                    case RobotUnitDataStreaming::NodeTypeByte:
+                        dto.extraBytes[key] = getValueAs<Ice::Byte>(value);
+                        break;
                     default:
                         ARMARX_DEBUG << "Cannot handle extra field '" << key << "' of type "
                                      << RobotUnitDataStreaming::DataEntryNames.to_name(value.entry.type);
diff --git a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
index 85bf523195f80698abf478bd23382f2845344354..9b247cb3973cf28befe37289a3ff42160133f21b 100644
--- a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
+++ b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
@@ -66,11 +66,11 @@ The memory should look like the following:
                 <Duration />
             </ObjectChild>
 
-            <ObjectChild key='acceptedType'>
+            <ObjectChild key='parametersType'>
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
 
-            <ObjectChild key='returnType'>
+            <ObjectChild key='resultType'>
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
 
@@ -95,12 +95,12 @@ The memory should look like the following:
                 <String />
             </ObjectChild>
 
-            <ObjectChild key='params'>
+            <ObjectChild key='parameters'>
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
         </Object>
 
-        <Object name='armarx::skills::arondto::SkillExecutionEvent'>
+        <Object name='armarx::skills::arondto::SkillStatusUpdate'>
 
             <ObjectChild key='skillId'>
                 <armarx::skills::arondto::SkillID />
@@ -118,11 +118,11 @@ The memory should look like the following:
                 <String />
             </ObjectChild>
 
-            <ObjectChild key='params'>
+            <ObjectChild key='parameters'>
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
 
-            <ObjectChild key='data'>
+            <ObjectChild key='result'>
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
         </Object>
diff --git a/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp b/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp
index 4bb6f1f5128de5c8afd422114e92530ddba8bce2..3b1d8925fc6694ba7117a4ce3e0db07ecab68586 100644
--- a/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp
+++ b/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp
@@ -133,7 +133,7 @@ namespace armarx::armem
     fromAron(const armarx::skills::arondto::SkillID& dto, skills::SkillID& bo)
     {
         bo.skillName = dto.skillName;
-        bo.providerId = skills::ProviderID(skills::SkillID::UNKNOWN);
+        bo.providerId = skills::ProviderID{.providerName = ""};
         fromAron(dto.providerId, *bo.providerId);
     }
 
@@ -154,8 +154,8 @@ namespace armarx::armem
         fromAron(dto.skillId, bo.skillId);
         bo.description = dto.description;
         bo.timeout = dto.timeout;
-        bo.rootProfileParameterization = dto.rootProfileParameterization;
-        if (dto.acceptedType)
+        bo.rootProfileDefaults = dto.rootProfileParameterization;
+        if (dto.parametersType)
         {
             throw armarx::LocalException("Not implemented yet");
         }
@@ -167,13 +167,13 @@ namespace armarx::armem
         toAron(dto.skillId, bo.skillId);
         dto.description = bo.description;
         dto.timeout = bo.timeout;
-        dto.rootProfileParameterization = bo.rootProfileParameterization;
-        if (bo.acceptedType)
+        dto.rootProfileParameterization = bo.rootProfileDefaults;
+        if (bo.parametersType)
         {
             aron::type::converter::AronDatatypeConverterVisitor c;
-            aron::type::visit(c, bo.acceptedType);
+            aron::type::visit(c, bo.parametersType);
 
-            dto.acceptedType = aron::data::Dict::DynamicCastAndCheck(c.latest);
+            dto.parametersType = aron::data::Dict::DynamicCastAndCheck(c.latest);
         }
     }
 
@@ -183,7 +183,7 @@ namespace armarx::armem
     {
         fromAron(dto.skillId, bo.skillId);
         bo.executorName = dto.executorName;
-        bo.params = dto.params;
+        bo.parameters = dto.parameters;
     }
 
     void
@@ -192,11 +192,11 @@ namespace armarx::armem
     {
         toAron(dto.skillId, bo.skillId);
         dto.executorName = bo.executorName;
-        dto.params = bo.params;
+        dto.parameters = bo.parameters;
     }
 
     void
-    fromAron(const armarx::skills::arondto::SkillExecutionEvent& dto, skills::SkillStatusUpdate& bo)
+    fromAron(const armarx::skills::arondto::SkillStatusUpdate& dto, skills::SkillStatusUpdate& bo)
     {
         static std::map<std::string, skills::SkillStatus> map{
             {"Constructing", skills::SkillStatus::Constructing},
@@ -210,13 +210,13 @@ namespace armarx::armem
         fromAron(dto.skillId, bo.executionId.skillId);
         bo.executionId.executionStartedTime = dto.executionStartedTimestamp;
         bo.executionId.executorName = dto.executorName;
-        bo.usedParameterization.parameterization = dto.params;
-        bo.data = dto.data;
+        bo.parameters = dto.parameters;
+        bo.result = dto.result;
         bo.status = map.at(dto.status);
     }
 
     void
-    toAron(armarx::skills::arondto::SkillExecutionEvent& dto, const skills::SkillStatusUpdate& bo)
+    toAron(armarx::skills::arondto::SkillStatusUpdate& dto, const skills::SkillStatusUpdate& bo)
     {
         static std::map<skills::SkillStatus, std::string> map{
             {skills::SkillStatus::Constructing, "Constructing"},
@@ -230,8 +230,8 @@ namespace armarx::armem
         toAron(dto.skillId, bo.executionId.skillId);
         dto.executorName = bo.executionId.executorName;
         dto.executionStartedTimestamp = bo.executionId.executionStartedTime;
-        dto.params = bo.usedParameterization.parameterization;
-        dto.data = bo.data;
+        dto.parameters = bo.parameters;
+        dto.result = bo.result;
         dto.status = map.at(bo.status);
     }
 } // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem_skills/aron_conversions.h b/source/RobotAPI/libraries/armem_skills/aron_conversions.h
index 57b7dd312183e38714b77f695c8dd5318fca6e60..38ffbe0c43ecc492cf76398abdd2f3cad122db7c 100644
--- a/source/RobotAPI/libraries/armem_skills/aron_conversions.h
+++ b/source/RobotAPI/libraries/armem_skills/aron_conversions.h
@@ -40,8 +40,8 @@ namespace armarx::armem
     void toAron(armarx::skills::arondto::SkillExecutionRequest& dto,
                 const skills::SkillExecutionRequest& bo);
 
-    void fromAron(const armarx::skills::arondto::SkillExecutionEvent& dto,
+    void fromAron(const armarx::skills::arondto::SkillStatusUpdate& dto,
                   skills::SkillStatusUpdate& bo);
-    void toAron(armarx::skills::arondto::SkillExecutionEvent& dto,
+    void toAron(armarx::skills::arondto::SkillStatusUpdate& dto,
                 const skills::SkillStatusUpdate& bo);
 } // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
index 6328e6d734c9cb454d301875a399cbc097d20a12..11dc8d0dfb40953de6acc8f81921884808339376 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
@@ -33,7 +33,7 @@ namespace armarx::skills::segment
     SkillEventCoreSegment::addSkillUpdateEvent(const skills::SkillStatusUpdate& update)
     {
         // create commit about new update
-        armarx::skills::arondto::SkillExecutionEvent event;
+        armarx::skills::arondto::SkillStatusUpdate event;
         armem::toAron(event, update);
 
         armem::MemoryID commitId = id();
@@ -53,40 +53,58 @@ namespace armarx::skills::segment
     }
 
     std::map<skills::SkillExecutionID, skills::SkillStatusUpdate>
-    SkillEventCoreSegment::getLatestSkillEvents(int n)
+    SkillEventCoreSegment::getSkillStatusUpdates()
     {
         std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> ret;
         auto coreSegment = this->segmentPtr;
         ARMARX_CHECK(coreSegment);
 
-        // 1. get all events and sort them by timestamp.
-        std::vector<skills::SkillStatusUpdate> sorted;
         coreSegment->forEachInstance(
-            [&sorted](const armem::wm::EntityInstance& i)
+            [&](const armem::wm::EntityInstance& i)
             {
-                auto event = i.dataAs<armarx::skills::arondto::SkillExecutionEvent>();
-                skills::SkillStatusUpdate up({{{""}, ""}, "", armarx::core::time::DateTime::Now()},
-                                             {nullptr, nullptr});
+                auto event = i.dataAs<armarx::skills::arondto::SkillStatusUpdate>();
+                skills::SkillStatusUpdate up;
                 armem::fromAron(event, up);
-                sorted.emplace_back(std::move(up));
+
+                if (auto it = ret.find(up.executionId); it != ret.end() && up < it->second)
+                {
+                    return;
+                }
+
+                // set or replace
+                ret[up.executionId] = up;
             });
 
-        std::sort(sorted.begin(),
-                  sorted.end(),
-                  [](const skills::SkillStatusUpdate& a, const skills::SkillStatusUpdate& b)
-                  { return b < a; });
+        //        for (const auto& [k, v] : ret)
+        //        {
+        //            ARMARX_IMPORTANT << "Skill " << k.skillId << " has stati: " << int(v.status);
+        //        }
 
-        for (const auto& el : sorted)
-        {
-            if (ret.size() >= (size_t)n)
-            {
-                break;
-            }
+        return ret;
+    }
 
-            ret.emplace(
-                std::piecewise_construct, std::make_tuple(el.executionId), std::make_tuple(el));
-        }
+    std::optional<skills::SkillStatusUpdate>
+    SkillEventCoreSegment::getSkillStatusUpdate(const skills::SkillExecutionID& id)
+    {
+        std::optional<skills::SkillStatusUpdate> ret = std::nullopt;
+        auto coreSegment = this->segmentPtr;
+        ARMARX_CHECK(coreSegment);
+
+        coreSegment->forEachInstance(
+            [&](const armem::wm::EntityInstance& i)
+            {
+                auto event = i.dataAs<armarx::skills::arondto::SkillStatusUpdate>();
+                skills::SkillStatusUpdate up;
+                armem::fromAron(event, up);
 
+                if (up.executionId == id)
+                {
+                    if (!ret || (ret.has_value() && *ret < up))
+                    {
+                        ret = up;
+                    }
+                }
+            });
         return ret;
     }
 } // namespace armarx::skills::segment
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h
index 492c26090479a2be9c80442aeddc814378975486..0537cbdbdf97d80649e10baa30786d2d1fb5870c 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h
@@ -27,7 +27,10 @@ namespace armarx::skills::segment
 
         void addSkillUpdateEvent(const skills::SkillStatusUpdate& update);
 
-        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> getLatestSkillEvents(int n);
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> getSkillStatusUpdates();
+
+        std::optional<skills::SkillStatusUpdate>
+        getSkillStatusUpdate(const skills::SkillExecutionID& id);
 
     private:
     };
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp
index 4b57e0b44f8b9f2626514c94dd757407506efb57..833deb3f68144a10a71812f9eb39dbec455d9c0c 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp
@@ -39,7 +39,9 @@ namespace armarx::skills::segment
         skills::arondto::SkillExecutionRequest request;
         request.fromAron(commitDataAron);
 
-        skills::SkillExecutionRequest info({{""}, ""}, "", nullptr);
+        skills::SkillExecutionRequest info{
+            .skillId = SkillID{.providerId = ProviderID{.providerName = ""}, .skillName = ""},
+            .executorName = ""};
         armem::fromAron(request, info);
         return info;
     }
diff --git a/source/RobotAPI/libraries/aron/common/CMakeLists.txt b/source/RobotAPI/libraries/aron/common/CMakeLists.txt
index f8109b4a31f9aa10cfb3caae5b557e4a0c96a391..36cbeb1f837f96ea05b131a843654481b5195bb9 100644
--- a/source/RobotAPI/libraries/aron/common/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/common/CMakeLists.txt
@@ -28,6 +28,7 @@ armarx_add_library(
         aron_conversions/eigen.h
 
         json_conversions/armarx.h
+        json_conversions/framed.h
 
         rw/time.h
         rw/eigen.h
@@ -47,6 +48,7 @@ armarx_add_library(
         aron_conversions/eigen.cpp
 
         json_conversions/armarx.cpp
+        json_conversions/framed.cpp
 
         rw/time.cpp
         rw/eigen.cpp
diff --git a/source/RobotAPI/libraries/aron/common/forward_declarations.h b/source/RobotAPI/libraries/aron/common/forward_declarations.h
index 626147c3fc35e827a7b905c8a8b0e76babf3f25e..d3c7df9f82d251032ed5f1e49180f74f30cf223f 100644
--- a/source/RobotAPI/libraries/aron/common/forward_declarations.h
+++ b/source/RobotAPI/libraries/aron/common/forward_declarations.h
@@ -1,13 +1,14 @@
 #pragma once
 
-
 namespace simox::arondto
 {
     class AxisAlignedBoundingBox;
     class Color;
     class OrientedBox;
-}
+} // namespace simox::arondto
+
 namespace armarx::arondto
 {
     class Names;
-}
+    class FrameID;
+} // namespace armarx::arondto
diff --git a/source/RobotAPI/libraries/aron/common/json_conversions.h b/source/RobotAPI/libraries/aron/common/json_conversions.h
index a56bd44287eb16161f84e5d1ef0f5496903e2669..b29300e6cf827cfd0908521a3b9fa040b3b32a3d 100644
--- a/source/RobotAPI/libraries/aron/common/json_conversions.h
+++ b/source/RobotAPI/libraries/aron/common/json_conversions.h
@@ -1,3 +1,4 @@
 #pragma once
 
 #include "json_conversions/armarx.h"
+#include "json_conversions/framed.h"
diff --git a/source/RobotAPI/libraries/aron/common/json_conversions/framed.cpp b/source/RobotAPI/libraries/aron/common/json_conversions/framed.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa1cf6ae4237e505e00d8ac069824a0004a66e16
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/common/json_conversions/framed.cpp
@@ -0,0 +1,17 @@
+#include "framed.h"
+
+#include <RobotAPI/libraries/aron/common/aron/framed.aron.generated.h>
+
+void
+armarx::arondto::to_json(nlohmann::json& j, const FrameID& bo)
+{
+    j["agent"] = bo.agent;
+    j["frame"] = bo.frame;
+}
+
+void
+armarx::arondto::from_json(const nlohmann::json& j, FrameID& bo)
+{
+    j.at("agent").get_to(bo.agent);
+    j.at("frame").get_to(bo.frame);
+}
diff --git a/source/RobotAPI/libraries/aron/common/json_conversions/framed.h b/source/RobotAPI/libraries/aron/common/json_conversions/framed.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb7314e83628ab4ddf951766139fedeee731a0e9
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/common/json_conversions/framed.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <SimoxUtility/json/json.h>
+
+#include <RobotAPI/libraries/aron/common/forward_declarations.h>
+
+namespace armarx::arondto
+{
+    void to_json(nlohmann::json& j, const FrameID& bo);
+    void from_json(const nlohmann::json& j, FrameID& bo);
+
+} // namespace armarx::arondto
diff --git a/source/RobotAPI/libraries/skills/core/CMakeLists.txt b/source/RobotAPI/libraries/skills/core/CMakeLists.txt
index 66795b7ecdf0b0aa0897a07f5e47e5f5d489d4a1..29145e60e305fa10decf06200685dcb99ec6a3d5 100644
--- a/source/RobotAPI/libraries/skills/core/CMakeLists.txt
+++ b/source/RobotAPI/libraries/skills/core/CMakeLists.txt
@@ -24,6 +24,7 @@ armarx_add_library(
         SkillPreparationInput.cpp
         SkillParameterization.cpp
         Skill.cpp
+        SkillProxy.cpp
         SkillDescription.cpp
     HEADERS
         error/Exception.h
@@ -36,6 +37,7 @@ armarx_add_library(
         SkillPreparationInput.h
         SkillParameterization.h
         Skill.h
+        SkillProxy.h
         SkillDescription.h
 )
 
diff --git a/source/RobotAPI/libraries/skills/core/ProviderID.cpp b/source/RobotAPI/libraries/skills/core/ProviderID.cpp
index 83330c897d05a6e47def33f19f1b8bddefcd7b90..53d6aad6807a7002a80a097d94b1e1fb5ec9f864 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderID.cpp
+++ b/source/RobotAPI/libraries/skills/core/ProviderID.cpp
@@ -6,20 +6,10 @@ namespace armarx
 {
     namespace skills
     {
-        ProviderID::ProviderID(const std::string& pname) : providerName(pname)
-        {
-        }
-
-        ProviderID::ProviderID(const skills::SkillID& skillid)
-        {
-            ARMARX_CHECK(skillid.providerId.has_value());
-            providerName = skillid.providerId->providerName;
-        }
-
         bool
         ProviderID::operator==(const ProviderID& other) const
         {
-            return providerName == other.providerName;
+            return toString() == other.toString();
         }
 
         bool
@@ -34,16 +24,22 @@ namespace armarx
             return toString() < other.toString();
         }
 
+        bool
+        ProviderID::operator<=(const ProviderID& other) const
+        {
+            return toString() <= other.toString();
+        }
+
         ProviderID
         ProviderID::FromIce(const manager::dto::ProviderID& s)
         {
-            return ProviderID(s.providerName);
+            return ProviderID{.providerName = s.providerName};
         }
 
         ProviderID
         ProviderID::FromIce(const callback::dto::ProviderID& s)
         {
-            return ProviderID(s.providerName);
+            return ProviderID{.providerName = s.providerName};
         }
 
         manager::dto::ProviderID
@@ -59,9 +55,9 @@ namespace armarx
         }
 
         std::string
-        ProviderID::toString(const std::string& prefix) const
+        ProviderID::toString() const
         {
-            return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) + providerName;
+            return providerName;
         }
     } // namespace skills
 
diff --git a/source/RobotAPI/libraries/skills/core/ProviderID.h b/source/RobotAPI/libraries/skills/core/ProviderID.h
index 0e0159d9db863364bd40f2c4be9c0aca1d7f92a3..5687f649185fa472d0afe1b7a60e6eb2eba46d34 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderID.h
+++ b/source/RobotAPI/libraries/skills/core/ProviderID.h
@@ -15,17 +15,10 @@ namespace armarx
         class ProviderID
         {
         public:
-            static const constexpr char* PREFIX_SEPARATOR = "->";
-
-            std::string providerName;
-
-            ProviderID() = delete;
-            ProviderID(const skills::SkillID& skillid);
-            ProviderID(const std::string& pName);
-
             bool operator==(const ProviderID& other) const;
             bool operator!=(const ProviderID& other) const;
             bool operator<(const ProviderID& other) const;
+            bool operator<=(const ProviderID& other) const;
 
             manager::dto::ProviderID toManagerIce() const;
             callback::dto::ProviderID toCallbackIce() const;
@@ -33,7 +26,9 @@ namespace armarx
             static ProviderID FromIce(const manager::dto::ProviderID&);
             static ProviderID FromIce(const callback::dto::ProviderID&);
 
-            std::string toString(const std::string& prefix = "") const;
+            std::string toString() const;
+
+            std::string providerName;
         };
 
         std::ostream& operator<<(std::ostream& os, const ProviderID& id);
diff --git a/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp b/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
index 7ae36dbfa185225e13853229790465692501a78f..135b81c594aaf004d65170c81f65a1a6b9529a07 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
+++ b/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
@@ -4,13 +4,6 @@ namespace armarx
 {
     namespace skills
     {
-        ProviderInfo::ProviderInfo(const ProviderID& pid,
-                                   const provider::dti::SkillProviderInterfacePrx& i,
-                                   const std::map<SkillID, SkillDescription>& skills) :
-            providerId(pid), providerInterface(i), providedSkills(skills)
-        {
-        }
-
         skills::manager::dto::ProviderInfo
         ProviderInfo::toIce() const
         {
@@ -33,7 +26,7 @@ namespace armarx
             {
                 m.insert({skills::SkillID::FromIce(k), skills::SkillDescription::FromIce(v)});
             }
-            return ProviderInfo(skills::ProviderID::FromIce(i.providerId), i.providerInterface, m);
+            return ProviderInfo{skills::ProviderID::FromIce(i.providerId), i.providerInterface, m};
         }
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/ProviderInfo.h b/source/RobotAPI/libraries/skills/core/ProviderInfo.h
index 92c5484c327f7f5766d406c3ce383e34ee15c246..438a2cf9d894f25f97150dc10ab6c5d9538cdc1e 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderInfo.h
+++ b/source/RobotAPI/libraries/skills/core/ProviderInfo.h
@@ -23,11 +23,6 @@ namespace armarx
             provider::dti::SkillProviderInterfacePrx providerInterface;
             std::map<SkillID, SkillDescription> providedSkills;
 
-            ProviderInfo() = delete;
-            ProviderInfo(const ProviderID& pid,
-                         const provider::dti::SkillProviderInterfacePrx& i,
-                         const std::map<SkillID, SkillDescription>& skills);
-
             skills::manager::dto::ProviderInfo toIce() const;
 
             static ProviderInfo FromIce(const manager::dto::ProviderInfo&);
diff --git a/source/RobotAPI/libraries/skills/core/Skill.cpp b/source/RobotAPI/libraries/skills/core/Skill.cpp
index 19169d62783970774c350a94aabbb355d580e8b5..7d94de3e90815a156289948fae26463ce5f28247 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.cpp
+++ b/source/RobotAPI/libraries/skills/core/Skill.cpp
@@ -4,7 +4,7 @@ namespace armarx
 {
     namespace skills
     {
-        Skill::Skill(const SkillDescription& desc) : description(desc)
+        Skill::Skill(const SkillDescription& desc) : description(desc), constructing(true)
         {
             // replace constructor if you want to have a specific logging tag
             Logging::setTag("armarx::skills::" + description.skillId.toString());
@@ -14,17 +14,74 @@ namespace armarx
         void
         Skill::installConditionWithCallback(std::function<bool()>&& f, std::function<void()>&& cb)
         {
-            std::lock_guard l(conditionCallbacksMutex);
+            std::scoped_lock l(conditionCallbacksMutex);
             conditionCallbacks.push_back({f, cb});
         }
 
+        std::optional<TerminatedSkillStatusUpdate>
+        Skill::callSubskill(const SkillProxy& prx, const aron::data::DictPtr& params)
+        {
+            auto eid = callSubskillAsync(prx, params);
+            auto ret = prx.join(eid);
+            return ret;
+        }
+
+        skills::SkillExecutionID
+        Skill::callSubskillAsync(const skills::SkillProxy& prx, const aron::data::DictPtr& params)
+        {
+            std::unique_lock l(subskillsMutex);
+
+            std::string executorHistory = this->executorName + "->" + getSkillId().toString();
+            auto eid = prx.executeSkillAsync(executorHistory, params);
+            this->subskills.push_back(eid);
+            return eid;
+        }
+
+        void
+        Skill::updateParameters(const aron::data::DictPtr& d)
+        {
+            std::scoped_lock l(this->parametersMutex);
+            if (this->parameters == nullptr)
+            {
+                // set params as there has been no update before.
+                this->parameters = d;
+            }
+            else
+            {
+                // merge params into existing. Note that this may update already set params.
+                this->parameters->mergeAndReplaceCopy(d);
+            }
+        }
+
+        void
+        Skill::setParameters(const aron::data::DictPtr& d)
+        {
+            // we only set the params if the skill is not already running
+            if (running or exiting or finished)
+            {
+                return;
+            }
+
+            std::scoped_lock l(this->parametersMutex);
+            this->parameters = d;
+        }
+
+        aron::data::DictPtr
+        Skill::getParameters() const
+        {
+            return this->parameters;
+        }
+
         Skill::InitResult
         Skill::_init()
         {
             //ARMARX_IMPORTANT << "Initializing skill '" << description.skillName << "'";
-            conditionCallbacks.clear();
-            running = true;
-            started = armarx::core::time::DateTime::Now();
+            this->initializing = true;
+            this->constructing = false;
+            this->preparing = false;
+            this->running = false;
+            this->exiting = false;
+            this->finished = false;
 
             // install timeout condition
             installConditionWithCallback(
@@ -37,7 +94,8 @@ namespace armarx
                 [&]()
                 {
                     armarx::core::time::Metronome metronome(conditionCheckingThreadFrequency);
-                    while (running) // when the skill ends/aborts this variable will be set to false
+                    while (initializing or preparing or
+                           running) // when the skill ends/aborts this variable will be set to false
                     {
                         {
                             std::scoped_lock l(conditionCallbacksMutex);
@@ -51,13 +109,15 @@ namespace armarx
                                 }
                             }
                         }
+
                         const auto sleepDuration = metronome.waitForNextTick();
                         if (not sleepDuration.isPositive())
                         {
-                            ARMARX_WARNING
-                                << deactivateSpam() << "PeriodicSkill: execution took too long ("
-                                << -sleepDuration << " vs "
-                                << conditionCheckingThreadFrequency.toCycleDuration() << ")";
+                            ARMARX_WARNING << deactivateSpam()
+                                           << "ConditionCheckingThread: execution took too long ("
+                                           << -sleepDuration << " vs "
+                                           << conditionCheckingThreadFrequency.toCycleDuration()
+                                           << ")";
                         }
                     }
                 });
@@ -67,18 +127,24 @@ namespace armarx
         Skill::PrepareResult
         Skill::_prepare()
         {
-            if (checkWhetherSkillShouldStopASAP())
+            this->preparing = true;
+            this->initializing = false;
+            this->constructing = false;
+            this->running = false;
+            this->exiting = false;
+            this->finished = false;
+
+            if (shouldSkillTerminate())
             {
                 return {.status = ActiveOrTerminatedSkillStatus::Aborted};
             }
 
             // Default nothing to prepare
-            std::scoped_lock l(parametersMutex);
-            if (not description.acceptedType)
+            if (not description.parametersType)
             {
                 return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
             }
-            if (this->parameters && this->parameters->fullfillsType(description.acceptedType))
+            if (this->parameters && this->parameters->fullfillsType(description.parametersType))
             {
                 // wait until parameters fulfill type
                 return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
@@ -91,7 +157,12 @@ namespace armarx
         Skill::MainResult
         Skill::_main()
         {
-            // Nothing here yet...
+            this->running = true;
+            this->initializing = false;
+            this->constructing = false;
+            this->preparing = false;
+            this->exiting = false;
+            this->finished = false;
             return {.status = TerminatedSkillStatus::Succeeded};
         }
 
@@ -99,78 +170,174 @@ namespace armarx
         Skill::_exit()
         {
             // ARMARX_IMPORTANT << "Exiting Skill '" << description.skillName << "'";
-            running = false; // stop checking conditions
+            this->exiting = true;
+            this->running = false;
+            this->initializing = false;
+            this->constructing = false;
+            this->preparing = false;
+            this->finished = false;
 
             if (conditionCheckingThread.joinable())
             {
                 conditionCheckingThread.join();
             }
             exited = armarx::core::time::DateTime::Now();
+
+            this->finished = true;
+            this->exiting = false;
             return {.status = TerminatedSkillStatus::Succeeded};
         }
 
         Skill::InitResult
         Skill::initSkill()
         {
+            std::scoped_lock l(parametersMutex);
             auto _res = this->_init();
             auto res = this->init();
-            return {.status = skills::MergeSkillStatus(_res.status, res.status)};
+            return {.status = skills::mergeSkillStatuseses(_res.status, res.status)};
         }
 
         Skill::PrepareResult
         Skill::prepareSkill()
         {
+            std::scoped_lock l(parametersMutex);
             auto _res = this->_prepare();
             auto res = this->prepare();
-            return {.status = skills::MergeSkillStatus(_res.status, res.status)};
+            return {.status = skills::mergeSkillStatuseses(_res.status, res.status)};
         }
 
         Skill::MainResult
         Skill::mainOfSkill()
         {
+            std::scoped_lock l(parametersMutex);
             auto _res = this->_main();
             auto res = this->main();
-            return {.status = skills::MergeSkillStatus(_res.status, res.status), .data = res.data};
+            return {.status = skills::mergeSkillStatuseses(_res.status, res.status),
+                    .data = res.data};
         }
 
         Skill::ExitResult
         Skill::exitSkill()
         {
+            std::scoped_lock l(parametersMutex);
             auto res = this->exit();
             auto _res = this->_exit();
-            return {.status = skills::MergeSkillStatus(_res.status, res.status)};
+            return {.status = skills::mergeSkillStatuseses(_res.status, res.status)};
         }
 
         void
-        Skill::notifyTimeoutReached()
+        Skill::throwIfSkillShouldTerminate(const std::function<void()>& do_before,
+                                           const std::string& abortedMessage)
         {
-            timeoutReached = true;
-            onTimeoutReached();
+            if (shouldSkillTerminate())
+            {
+                do_before();
+                throwIfSkillShouldTerminate(abortedMessage);
+            }
+        }
+
+        void
+        Skill::throwIfSkillShouldTerminate(const std::string& abortedMessage)
+        {
+            if (stopped)
+            {
+                std::string message =
+                    std::string("The skill '" + getSkillId().toString() + "' was asked to stop.");
+                message += abortedMessage.empty() ? "" : " Additional message: " + abortedMessage;
+
+                throw error::SkillAbortedException(message);
+                return;
+            }
+
+            if (timeoutReached)
+            {
+                std::string message =
+                    std::string("The skill '" + getSkillId().toString() + "' reached timeout.");
+                message += abortedMessage.empty() ? "" : " Additional message: " + abortedMessage;
+
+                ARMARX_WARNING << message;
+                throw error::SkillFailedException(message);
+            }
         }
 
         Skill::MainResult
-        Skill::MakeAbortedResult(aron::data::DictPtr data)
+        Skill::MakeSucceededResult(aron::data::DictPtr data)
         {
             return MainResult{
-                .status = TerminatedSkillStatus::Aborted,
+                .status = TerminatedSkillStatus::Succeeded,
                 .data = data,
             };
         }
 
+        Skill::MainResult
+        Skill::MakeFailedResult()
+        {
+            return MainResult{
+                .status = TerminatedSkillStatus::Failed,
+                .data = nullptr,
+            };
+        }
+
+        Skill::MainResult
+        Skill::MakeAbortedResult()
+        {
+            return MainResult{
+                .status = TerminatedSkillStatus::Aborted,
+                .data = nullptr,
+            };
+        }
+
         void
-        Skill::notifySkillToStopASAP()
+        Skill::notifySkillToStop()
         {
+            std::scoped_lock l(subskillsMutex);
             stopped = true;
+            _onStopRequested();
             onStopRequested();
         }
 
+        void
+        Skill::notifyTimeoutReached()
+        {
+            std::scoped_lock l(subskillsMutex);
+            timeoutReached = true;
+            _onTimeoutReached();
+            onTimeoutReached();
+        }
+
         bool
-        Skill::checkWhetherSkillShouldStopASAP() const
+        Skill::shouldSkillTerminate() const
         {
             return stopped || timeoutReached;
         }
 
         // condition effects
+        void
+        Skill::_onTimeoutReached()
+        {
+            if (!manager)
+            {
+                return;
+            }
+            for (const auto& execId : subskills)
+            {
+                manager->abortSkillAsync(execId.toManagerIce());
+            }
+        }
+
+        void
+        Skill::_onStopRequested()
+        {
+            if (!manager)
+            {
+                return;
+            }
+            for (const auto& execId : subskills)
+            {
+                manager->abortSkillAsync(execId.toManagerIce());
+            }
+        }
+
         void
         Skill::onTimeoutReached()
         {
diff --git a/source/RobotAPI/libraries/skills/core/Skill.h b/source/RobotAPI/libraries/skills/core/Skill.h
index b147e455f07039d430ab3113e8fec18298c09458..5ec80e77d9956e8516ae84ffec16313bab0c9206 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.h
+++ b/source/RobotAPI/libraries/skills/core/Skill.h
@@ -19,6 +19,7 @@
 #include "SkillDescription.h"
 #include "SkillID.h"
 #include "SkillPreparationInput.h"
+#include "SkillProxy.h"
 #include "SkillStatusUpdate.h"
 #include "error/Exception.h"
 
@@ -32,108 +33,136 @@ namespace armarx
             using CallbackT =
                 std::function<void(const SkillStatus s, const armarx::aron::data::DictPtr&)>;
 
+            /// A result struct for skill initialization
             struct InitResult
             {
                 TerminatedSkillStatus status;
             };
 
+            /// A result struct for skill preparing
             struct PrepareResult
             {
                 ActiveOrTerminatedSkillStatus status;
             };
 
+            /// A result struct for th main method of a skill
             struct MainResult
             {
                 TerminatedSkillStatus status;
                 aron::data::DictPtr data = nullptr;
             };
 
+            /// A result struct for skill exit function
             struct ExitResult
             {
                 TerminatedSkillStatus status;
             };
 
+            /// We completely remove the default constructor! A skill without a desciption cannot exist
             Skill() = delete;
+
+            /// Constructor of a skill for inheritance. Every skill must have a skill description
             Skill(const SkillDescription&);
-            virtual ~Skill() = default;
 
-            /// The id of the skill (combination of provider and name must be unique).
+            /// Virtual destructor of a skill
+            virtual ~Skill()
+            {
+                //ARMARX_IMPORTANT << "DESTROY SKILL " << getSkillId();
+            }
+
+            /// Get the id of the skill
             SkillID
             getSkillId() const
             {
                 return description.skillId;
             }
 
+            /// Get the description of a skill
             SkillDescription
             getSkillDescription() const
             {
                 return description;
             }
 
+            /// Set the provider id of the description of the skill.
+            /// This method is called when creating a skill in a skill provider
             void
             setProviderId(const skills::ProviderID& pid)
             {
                 description.skillId.providerId = pid;
             }
 
+            void
+            setCallback(const CallbackT& callback)
+            {
+                this->callback = callback;
+            }
+
+            void
+            setManager(const manager::dti::SkillManagerInterfacePrx& manager)
+            {
+                this->manager = manager;
+            }
+
+            void
+            setExecutorName(const std::string& executorName)
+            {
+                this->executorName = executorName;
+            }
+
+            /// Prepare a skill once. This method is called in a loop as long as it returns RUNNING
+            /// If the loop does not terminate with SUCCEDED the skill execution is failed.
             PrepareResult prepareSkill();
 
+            /// Initialization of a skill. Called directly after construction.
+            /// If this method does not return SUCCEEDED the skill execution is failed.
             InitResult initSkill();
 
+            /// Main method of a skill.
             MainResult mainOfSkill();
 
+            /// Exit method of a skill. It is guaranteed that exit is always called
+            /// (unless there is a segfault or similar)
             ExitResult exitSkill();
 
-            // Condition listeners
-            // used to notify the skill from extern to stop
-            void notifySkillToStopASAP();
+            /// Notify the skill from extern to stop
+            void notifySkillToStop();
 
-            // returns whether the skill should terminate as soon as possible
-            bool checkWhetherSkillShouldStopASAP() const;
+            /// Returns whether the skill should terminate as soon as possible
+            bool shouldSkillTerminate() const;
 
-            // merge parameters to the local parameters of the skill
-            void
-            addParameters(const aron::data::DictPtr& d)
-            {
-                std::scoped_lock l(this->parametersMutex);
-                if (this->parameters == nullptr)
-                {
-                    this->parameters = d;
-                }
-                else
-                {
-                    this->parameters->mergeAndReplaceCopy(d);
-                }
-            }
+            /// Merge parameters to the local parameters of the skill
+            void updateParameters(const aron::data::DictPtr& d);
 
-            // hard set the parameters, ignoring everything that has been set or merged before
-            void
-            setParameters(const aron::data::DictPtr& d)
-            {
-                std::scoped_lock l(this->parametersMutex);
-                this->parameters = d;
-            }
+            /// Hard set the parameters, ignoring everything that has been set or merged before
+            void setParameters(const aron::data::DictPtr& d);
 
-            // get the parameters
-            aron::data::DictPtr
-            getParameters() const
-            {
-                std::scoped_lock l(this->parametersMutex);
-                return this->parameters;
-            }
+            /// Get the parameters of a skill that have been set so far
+            aron::data::DictPtr getParameters() const;
 
         protected:
-            static MainResult MakeAbortedResult(aron::data::DictPtr data = nullptr);
+            void throwIfSkillShouldTerminate(const std::string& abortedMessage = "");
+            void throwIfSkillShouldTerminate(const std::function<void()>& do_before,
+                                             const std::string& abortedMessage = "");
+
+            static MainResult MakeSucceededResult(aron::data::DictPtr data = nullptr);
+            static MainResult MakeFailedResult();
+            static MainResult MakeAbortedResult();
 
             // fires if the skill reaches timeout
             void notifyTimeoutReached();
 
+        private:
             // helper methods to do all the static initialization stuff
             InitResult _init();
             PrepareResult _prepare();
             MainResult _main();
             ExitResult _exit();
 
+            void _onTimeoutReached();
+            void _onStopRequested();
+
+        protected:
             /// Override this method with the actual implementation.
             virtual InitResult init();
 
@@ -146,7 +175,7 @@ namespace armarx
             /// Override this method with the actual implementation.
             virtual ExitResult exit();
 
-        private:
+        protected:
             /// Override these methods if you want to do something special when notification comes
             virtual void onTimeoutReached();
             virtual void onStopRequested();
@@ -156,42 +185,59 @@ namespace armarx
             void installConditionWithCallback(std::function<bool()>&& f,
                                               std::function<void()>&& cb);
 
+            /// call a subskill and block until the subskill terminates.
+            /// If you call a subskill this way it will be stopped if the current skill stops.
+            std::optional<TerminatedSkillStatusUpdate>
+            callSubskill(const skills::SkillProxy& prx, const aron::data::DictPtr& = nullptr);
+
+            /// Similar to callSubskill but non-blocking
+            skills::SkillExecutionID callSubskillAsync(const skills::SkillProxy& prx,
+                                                       const aron::data::DictPtr& = nullptr);
+
         public:
             // running params
-            armarx::core::time::DateTime started = armarx::core::time::DateTime::Invalid();
+            armarx::core::time::DateTime started = armarx::core::time::DateTime::Now();
             armarx::core::time::DateTime exited = armarx::core::time::DateTime::Invalid();
 
-            // parameterization. Will be set from implementation wrapper.
-            // const params after initialization!!
-            CallbackT callback;
+        protected:
+            // parameterization. Will be set from implementation wrapper. No getters available
+            // const after construction!!
+            CallbackT callback = CallbackT();
             manager::dti::SkillManagerInterfacePrx manager = nullptr;
-            std::string executorName = "INVALID EXECUTOR NAME";
+            std::string executorName = "";
 
         protected:
-            // non-const params
+            // non-const params. Const after preparation. Getters are available
             mutable std::mutex parametersMutex;
             armarx::aron::data::DictPtr parameters = nullptr;
 
             // The descripion of the skill
             SkillDescription description;
 
-            // active conditions. First is condition (bool return func)
-            mutable std::mutex conditionCallbacksMutex;
-            std::vector<std::pair<std::function<bool()>, std::function<void()>>>
-                conditionCallbacks = {};
-
-
-            /// Use conditions this way
+            // Status variables
+            std::atomic_bool constructing = true;
             std::atomic_bool initializing = false;
             std::atomic_bool preparing = false;
             std::atomic_bool running = false;
+            std::atomic_bool exiting = false;
+            std::atomic_bool finished = false;
+
+            // Conditionals to indicate that an event has occured. Use conditions this way
             std::atomic_bool stopped = false;
             std::atomic_bool timeoutReached = false;
 
 
         private:
-            std::thread conditionCheckingThread; // A therad that checks the conditions frequently
+            // active conditions. First is condition (bool return func)
+            mutable std::mutex conditionCallbacksMutex;
+            std::vector<std::pair<std::function<bool()>, std::function<void()>>>
+                conditionCallbacks = {};
+
+            std::thread conditionCheckingThread; // A thread that checks the conditions frequently
             armarx::Frequency conditionCheckingThreadFrequency = armarx::Frequency::Hertz(20);
+
+            mutable std::mutex subskillsMutex;
+            std::vector<skills::SkillExecutionID> subskills;
         };
 
         template <class T>
diff --git a/source/RobotAPI/libraries/skills/core/SkillDescription.cpp b/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
index 6b51a08843a699d765124b2f59468227707c2778..2fa37b33ceab97b944e55644c99c530ba3f371c3 100644
--- a/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
@@ -7,31 +7,15 @@ namespace armarx
 {
     namespace skills
     {
-
-        SkillDescription::SkillDescription(const SkillID& id,
-                                           const std::string& desc,
-                                           const aron::data::DictPtr& data,
-                                           const armarx::core::time::Duration& timeout,
-                                           const aron::type::ObjectPtr& acceptedType,
-                                           const aron::type::ObjectPtr& returnType) :
-            skillId(id),
-            description(desc),
-            rootProfileParameterization(data),
-            timeout(timeout),
-            acceptedType(acceptedType),
-            returnType(returnType)
-        {
-        }
-
         provider::dto::SkillDescription
         SkillDescription::toProviderIce() const
         {
             provider::dto::SkillDescription ret;
-            ret.acceptedType = aron::type::Object::ToAronObjectDTO(acceptedType);
-            ret.returnType = aron::type::Object::ToAronObjectDTO(returnType);
+            ret.parametersType = aron::type::Object::ToAronObjectDTO(parametersType);
+            ret.resultType = aron::type::Object::ToAronObjectDTO(resultType);
             ret.description = description;
             ret.skillId = skillId.toProviderIce();
-            ret.rootProfileDefaults = aron::data::Dict::ToAronDictDTO(rootProfileParameterization);
+            ret.rootProfileDefaults = aron::data::Dict::ToAronDictDTO(rootProfileDefaults);
 
             armarx::core::time::toIce(ret.timeout, timeout);
             return ret;
@@ -41,11 +25,11 @@ namespace armarx
         SkillDescription::toManagerIce() const
         {
             manager::dto::SkillDescription ret;
-            ret.acceptedType = aron::type::Object::ToAronObjectDTO(acceptedType);
-            ret.returnType = aron::type::Object::ToAronObjectDTO(returnType);
+            ret.parametersType = aron::type::Object::ToAronObjectDTO(parametersType);
+            ret.resultType = aron::type::Object::ToAronObjectDTO(resultType);
             ret.description = description;
             ret.skillId = skillId.toManagerIce();
-            ret.rootProfileDefaults = aron::data::Dict::ToAronDictDTO(rootProfileParameterization);
+            ret.rootProfileDefaults = aron::data::Dict::ToAronDictDTO(rootProfileDefaults);
 
             armarx::core::time::toIce(ret.timeout, timeout);
             return ret;
@@ -57,13 +41,14 @@ namespace armarx
         {
             armarx::core::time::Duration _d;
             armarx::core::time::fromIce(i.timeout, _d);
-            return SkillDescription(
-                SkillID::FromIce(i.skillId, pid),
-                i.description,
-                armarx::aron::data::Dict::FromAronDictDTO(i.rootProfileDefaults),
-                _d,
-                armarx::aron::type::Object::FromAronObjectDTO(i.acceptedType),
-                armarx::aron::type::Object::FromAronObjectDTO(i.returnType));
+            return SkillDescription{
+                .skillId = SkillID::FromIce(i.skillId, pid),
+                .description = i.description,
+                .rootProfileDefaults =
+                    armarx::aron::data::Dict::FromAronDictDTO(i.rootProfileDefaults),
+                .timeout = _d,
+                .parametersType = armarx::aron::type::Object::FromAronObjectDTO(i.parametersType),
+                .resultType = armarx::aron::type::Object::FromAronObjectDTO(i.resultType)};
         }
 
         SkillDescription
@@ -71,13 +56,14 @@ namespace armarx
         {
             armarx::core::time::Duration _d;
             armarx::core::time::fromIce(i.timeout, _d);
-            return SkillDescription(
-                SkillID::FromIce(i.skillId),
-                i.description,
-                armarx::aron::data::Dict::FromAronDictDTO(i.rootProfileDefaults),
-                _d,
-                armarx::aron::type::Object::FromAronObjectDTO(i.acceptedType),
-                armarx::aron::type::Object::FromAronObjectDTO(i.returnType));
+            return SkillDescription{
+                .skillId = SkillID::FromIce(i.skillId),
+                .description = i.description,
+                .rootProfileDefaults =
+                    armarx::aron::data::Dict::FromAronDictDTO(i.rootProfileDefaults),
+                .timeout = _d,
+                .parametersType = armarx::aron::type::Object::FromAronObjectDTO(i.parametersType),
+                .resultType = armarx::aron::type::Object::FromAronObjectDTO(i.resultType)};
         }
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillDescription.h b/source/RobotAPI/libraries/skills/core/SkillDescription.h
index 429af240e75b267f9f9a0d103d1d9a9c5836be4a..4bc8a3cd8fe92f7ebdf13c32b1e812be8596fbbd 100644
--- a/source/RobotAPI/libraries/skills/core/SkillDescription.h
+++ b/source/RobotAPI/libraries/skills/core/SkillDescription.h
@@ -17,24 +17,12 @@ namespace armarx
     {
         struct SkillDescription
         {
-            SkillDescription() = delete;
-            SkillDescription(const SkillDescription&) = default;
-            SkillDescription(const SkillID& id,
-                             const std::string& desc,
-                             const aron::data::DictPtr& data = nullptr,
-                             const armarx::core::time::Duration& timeout =
-                                 armarx::core::time::Duration::MilliSeconds(-1),
-                             const aron::type::ObjectPtr& acceptedType = nullptr,
-                             const aron::type::ObjectPtr& returnType = nullptr);
-
-            SkillDescription& operator=(const SkillDescription&) = default;
-
             SkillID skillId;
-            std::string description;
-            aron::data::DictPtr rootProfileParameterization;
-            armarx::core::time::Duration timeout;
-            aron::type::ObjectPtr acceptedType;
-            aron::type::ObjectPtr returnType;
+            std::string description = "";
+            aron::data::DictPtr rootProfileDefaults = nullptr;
+            armarx::core::time::Duration timeout = armarx::core::time::Duration::MilliSeconds(-1);
+            aron::type::ObjectPtr parametersType = nullptr;
+            aron::type::ObjectPtr resultType = nullptr;
 
             provider::dto::SkillDescription toProviderIce() const;
             manager::dto::SkillDescription toManagerIce() const;
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp b/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
index 3c52c6be7ba8f52f8a6b023e65c23f897225910e..bb2494ac219fb656fb8383d151dba7b7cfe187cc 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
@@ -4,13 +4,6 @@ namespace armarx
 {
     namespace skills
     {
-        SkillExecutionID::SkillExecutionID(const SkillID& id,
-                                           const std::string& executorName,
-                                           const armarx::core::time::DateTime& time) :
-            skillId(id), executorName(executorName), executionStartedTime(time)
-        {
-        }
-
         skills::manager::dto::SkillExecutionID
         SkillExecutionID::toManagerIce() const
         {
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionID.h b/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
index bd1bfb326f466f499174182f87540fd7276ca016..474eef2f6df424780006dbd3bb51348136de63ef 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
@@ -35,26 +35,26 @@ namespace armarx
             bool
             operator==(const SkillExecutionID& other) const
             {
-                if (skillId != other.skillId)
-                {
-                    return false;
-                }
-                if (executionStartedTime != other.executionStartedTime)
-                {
-                    return false;
-                }
-                if (executorName != other.executorName)
-                {
-                    return false;
-                }
-                return true;
+                return this->toString() == other.toString();
             }
 
             bool
             operator<(const SkillExecutionID& other) const
             {
-                // We explicitly do not compare skillIds as we ONLY want to bring the executionids in some (temporal) order
-                return executionStartedTime < other.executionStartedTime;
+                return this->toString() < other.toString();
+            }
+
+            bool
+            operator<=(const SkillExecutionID& other) const
+            {
+                return this->toString() <= other.toString();
+            }
+
+            std::string
+            toString() const
+            {
+                return skillId.toString() + " requested by " + executorName + " at " +
+                       executionStartedTime.toDateTimeString();
             }
 
             skills::manager::dto::SkillExecutionID toManagerIce() const;
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
index 91fca69cae13c465c68a6bf2a7553f42b1b39304..2d6a0181bbbb8990f44ada113c55a69a532ee99f 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
@@ -4,22 +4,13 @@ namespace armarx
 {
     namespace skills
     {
-        SkillExecutionRequest::SkillExecutionRequest(
-            const skills::SkillID& skill,
-            const std::string executorName,
-            const armarx::aron::data::DictPtr& params,
-            const callback::dti::SkillProviderCallbackInterfacePrx& callback) :
-            skillId(skill), executorName(executorName), params(params), callbackInterface(callback)
-        {
-        }
-
         manager::dto::SkillExecutionRequest
         SkillExecutionRequest::toManagerIce() const
         {
             manager::dto::SkillExecutionRequest ret;
             ret.skillId = skillId.toManagerIce();
             ret.executorName = executorName;
-            ret.params = armarx::aron::data::Dict::ToAronDictDTO(params);
+            ret.parameters = armarx::aron::data::Dict::ToAronDictDTO(parameters);
             return ret;
         }
 
@@ -29,7 +20,7 @@ namespace armarx
             provider::dto::SkillExecutionRequest ret;
             ret.skillId = skillId.toProviderIce();
             ret.executorName = executorName;
-            ret.params = armarx::aron::data::Dict::ToAronDictDTO(params);
+            ret.parameters = armarx::aron::data::Dict::ToAronDictDTO(parameters);
             ret.callbackInterface = callbackInterface;
             return ret;
         }
@@ -39,7 +30,7 @@ namespace armarx
         {
             return {skills::SkillID::FromIce(req.skillId),
                     req.executorName,
-                    armarx::aron::data::Dict::FromAronDictDTO(req.params),
+                    armarx::aron::data::Dict::FromAronDictDTO(req.parameters),
                     nullptr};
         }
 
@@ -49,7 +40,7 @@ namespace armarx
         {
             return {skills::SkillID::FromIce(req.skillId, providerId),
                     req.executorName,
-                    armarx::aron::data::Dict::FromAronDictDTO(req.params),
+                    armarx::aron::data::Dict::FromAronDictDTO(req.parameters),
                     req.callbackInterface};
         }
 
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
index 9eaa00791ddfb4cf3f100e793f713fa828d314e5..d1f5bbcdd175f9f3516d45856186d453af2f987e 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
@@ -21,18 +21,6 @@ namespace armarx
         class SkillExecutionRequest
         {
         public:
-            skills::SkillID skillId;
-            std::string executorName;
-            armarx::aron::data::DictPtr params;
-            callback::dti::SkillProviderCallbackInterfacePrx callbackInterface;
-
-            SkillExecutionRequest() = delete;
-            SkillExecutionRequest(
-                const skills::SkillID& skill,
-                const std::string executorName,
-                const armarx::aron::data::DictPtr& params,
-                const callback::dti::SkillProviderCallbackInterfacePrx& callback = nullptr);
-
             manager::dto::SkillExecutionRequest toManagerIce() const;
             provider::dto::SkillExecutionRequest toProviderIce() const;
 
@@ -40,6 +28,12 @@ namespace armarx
             static SkillExecutionRequest
             FromIce(const provider::dto::SkillExecutionRequest&,
                     const std::optional<skills::ProviderID>& providerId = std::nullopt);
+
+
+            skills::SkillID skillId;
+            std::string executorName;
+            armarx::aron::data::DictPtr parameters = nullptr;
+            callback::dti::SkillProviderCallbackInterfacePrx callbackInterface = nullptr;
         };
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillID.cpp b/source/RobotAPI/libraries/skills/core/SkillID.cpp
index 9bb0b36a881642fbbdb7c21841dc5597e050fe7b..ece268aeeec9234a8dd4b2dcaa437d616988317e 100644
--- a/source/RobotAPI/libraries/skills/core/SkillID.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillID.cpp
@@ -4,37 +4,10 @@ namespace armarx
 {
     namespace skills
     {
-        SkillID::SkillID(const std::string& skillName) :
-            providerId(std::nullopt), skillName(skillName)
-        {
-        }
-
-        SkillID::SkillID(const ProviderID& providerId, const std::string& skillName) :
-            providerId(providerId), skillName(skillName)
-        {
-            if (simox::alg::contains(providerId.providerName, NAME_SEPARATOR) ||
-                simox::alg::contains(skillName, NAME_SEPARATOR))
-            {
-                throw error::SkillException(
-                    __PRETTY_FUNCTION__,
-                    std::string("A skill provider or a skill contains the blacklisted token '") +
-                        NAME_SEPARATOR + "'.");
-            }
-
-            if (simox::alg::contains(providerId.providerName, PREFIX_SEPARATOR) ||
-                simox::alg::contains(skillName, PREFIX_SEPARATOR))
-            {
-                throw error::SkillException(
-                    __PRETTY_FUNCTION__,
-                    std::string("A skill provider or a skill contains the blacklisted token '") +
-                        PREFIX_SEPARATOR + "'.");
-            }
-        }
-
         bool
         SkillID::operator==(const SkillID& other) const
         {
-            return providerId == other.providerId && skillName == other.skillName;
+            return this->toString() == other.toString();
         }
 
         bool
@@ -49,10 +22,18 @@ namespace armarx
             return toString() < other.toString();
         }
 
+        bool
+        SkillID::operator<=(const SkillID& other) const
+        {
+            return toString() <= other.toString();
+        }
+
         SkillID
         SkillID::FromIce(const manager::dto::SkillID& s)
         {
-            return SkillID(s.providerId.providerName, s.skillName);
+            return SkillID{.providerId =
+                               skills::ProviderID{.providerName = s.providerId.providerName},
+                           .skillName = s.skillName};
         }
 
         SkillID
@@ -61,15 +42,15 @@ namespace armarx
         {
             if (providerId.has_value())
             {
-                return SkillID(*providerId, s.skillName);
+                return SkillID{.providerId = *providerId, .skillName = s.skillName};
             }
-            return SkillID(s.skillName);
+            return SkillID{.skillName = s.skillName};
         }
 
         manager::dto::SkillID
         SkillID::toManagerIce() const
         {
-            ARMARX_CHECK(fullySpecified());
+            ARMARX_CHECK(isFullySpecified());
             return {providerId->toManagerIce(), skillName};
         }
 
@@ -80,15 +61,13 @@ namespace armarx
         }
 
         std::string
-        SkillID::toString(const std::string& prefix) const
+        SkillID::toString() const
         {
             if (providerId.has_value())
             {
-                return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) +
-                       providerId->providerName + NAME_SEPARATOR + skillName;
+                return providerId->providerName + NAME_SEPARATOR + skillName;
             }
-            return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) + UNKNOWN +
-                   NAME_SEPARATOR + skillName;
+            return NAME_SEPARATOR + skillName;
         }
     } // namespace skills
 
diff --git a/source/RobotAPI/libraries/skills/core/SkillID.h b/source/RobotAPI/libraries/skills/core/SkillID.h
index 39561595db477c926f809bc5a51644510f8da484..e611a82828442ad378dde77d4d90edf477b5e5f1 100644
--- a/source/RobotAPI/libraries/skills/core/SkillID.h
+++ b/source/RobotAPI/libraries/skills/core/SkillID.h
@@ -17,41 +17,33 @@ namespace armarx
         class SkillID
         {
         public:
-            static const constexpr char* PREFIX_SEPARATOR = "->";
             static const constexpr char* NAME_SEPARATOR = "/";
-            static const constexpr char* UNKNOWN = "UNKNOWN";
-
-            std::optional<ProviderID> providerId;
-            std::string skillName;
-
-            SkillID() = delete;
-            SkillID(const std::string& skillName);
-            SkillID(const ProviderID& providerId, const std::string& skillName);
 
             bool operator==(const SkillID& other) const;
             bool operator!=(const SkillID& other) const;
             bool operator<(const SkillID& other) const;
+            bool operator<=(const SkillID& other) const;
 
             bool
-            fullySpecified() const
+            isFullySpecified() const
             {
-                return skillSpecified() && providerSpecified();
+                return isSkillSpecified() and isProviderSpecified();
             }
 
             bool
-            skillSpecified() const
+            isSkillSpecified() const
             {
-                return skillName != UNKNOWN;
+                return not skillName.empty();
             }
 
             bool
-            providerSpecified() const
+            isProviderSpecified() const
             {
                 if (not providerId.has_value())
                 {
                     return false;
                 }
-                return providerId->providerName != UNKNOWN;
+                return not providerId->providerName.empty();
             }
 
             manager::dto::SkillID toManagerIce() const;
@@ -61,7 +53,10 @@ namespace armarx
             static SkillID FromIce(const provider::dto::SkillID&,
                                    const std::optional<ProviderID>& providerId = std::nullopt);
 
-            std::string toString(const std::string& prefix = "") const;
+            std::string toString() const;
+
+            std::optional<ProviderID> providerId = std::nullopt;
+            std::string skillName;
         };
 
         std::ostream& operator<<(std::ostream& os, const SkillID& id);
diff --git a/source/RobotAPI/libraries/skills/core/SkillParameterization.h b/source/RobotAPI/libraries/skills/core/SkillParameterization.h
index 5358eafa7591ad2ea7331b65427f0be062d1d194..9b54b3fff3bfe0aaedcb79d9c275165aefe5a37d 100644
--- a/source/RobotAPI/libraries/skills/core/SkillParameterization.h
+++ b/source/RobotAPI/libraries/skills/core/SkillParameterization.h
@@ -10,25 +10,5 @@ namespace armarx
 {
     namespace skills
     {
-        struct SkillParameterization
-        {
-            SkillParameterization() = delete;
-
-            SkillParameterization(const aron::data::DictPtr& params,
-                                  const callback::dti::SkillProviderCallbackInterfacePrx& i) :
-                parameterization(params), callbackInterface(i)
-            {
-            }
-
-            static SkillParameterization
-            FromIce(const armarx::aron::data::dto::DictPtr& params,
-                    const callback::dti::SkillProviderCallbackInterfacePrx& i)
-            {
-                return SkillParameterization(armarx::aron::data::Dict::FromAronDictDTO(params), i);
-            }
-
-            aron::data::DictPtr parameterization;
-            callback::dti::SkillProviderCallbackInterfacePrx callbackInterface;
-        };
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillProxy.cpp b/source/RobotAPI/libraries/skills/core/SkillProxy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f73c43dfd152c756f80e5ac3e83e901fe59e8ee1
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillProxy.cpp
@@ -0,0 +1,118 @@
+#include "SkillProxy.h"
+
+#include <chrono>
+#include <thread>
+
+namespace armarx
+{
+    namespace skills
+    {
+        SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
+                               const SkillID& skillId) :
+            manager(manager)
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            skillDescription = SkillDescription::FromIce(
+                manager->getSkillDescription(skillId.toManagerIce()).value());
+            ARMARX_CHECK(skillDescription.skillId.isFullySpecified());
+        }
+
+        SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
+                               const SkillDescription& skillDesc) :
+            manager(manager), skillDescription(skillDesc)
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            ARMARX_CHECK(skillDesc.skillId.isFullySpecified());
+        }
+
+        SkillDescription
+        SkillProxy::getSkillDescription() const
+        {
+            return skillDescription;
+        }
+
+        SkillID
+        SkillProxy::getSkillId() const
+        {
+            return skillDescription.skillId;
+        }
+
+        TerminatedSkillStatusUpdate
+        SkillProxy::executeSkill(const std::string& executorName,
+                                 const aron::data::DictPtr& params) const
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            skills::manager::dto::SkillExecutionRequest req;
+            req.executorName = executorName;
+            req.parameters = aron::data::Dict::ToAronDictDTO(params);
+            req.skillId = skillDescription.skillId.toManagerIce();
+
+            auto terminatingUpdateIce = manager->executeSkill(req);
+            return TerminatedSkillStatusUpdate::FromIce(terminatingUpdateIce);
+        }
+
+        SkillExecutionID
+        SkillProxy::executeSkillAsync(const std::string& executorName,
+                                      const aron::data::DictPtr& params) const
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            skills::manager::dto::SkillExecutionRequest req;
+            req.executorName = executorName;
+            req.parameters = aron::data::Dict::ToAronDictDTO(params);
+            req.skillId = skillDescription.skillId.toManagerIce();
+
+            auto execIdIce = manager->executeSkillAsync(req);
+            return SkillExecutionID::FromIce(execIdIce);
+        }
+
+        std::optional<TerminatedSkillStatusUpdate>
+        SkillProxy::join(const SkillExecutionID& executionId) const
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            auto s = this->manager->getSkillExecutionStatus(executionId.toManagerIce());
+
+            while (s)
+            {
+                auto statusUpdate = skills::SkillStatusUpdate::FromIce(*s);
+
+                if (statusUpdate.hasBeenTerminated())
+                {
+                    break;
+                }
+
+                std::this_thread::sleep_for(std::chrono::milliseconds(50));
+                s = this->manager->getSkillExecutionStatus(executionId.toManagerIce());
+            }
+
+            if (!s)
+            {
+                // Either the manager already removed the result (then it is unknown) or the execution id does not exist.
+                return std::nullopt;
+            }
+
+            return TerminatedSkillStatusUpdate::FromIce(*s);
+        }
+
+        bool
+        SkillProxy::abortSkill(const SkillExecutionID& id) const
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            auto r = manager->abortSkill(id.toManagerIce());
+            return r.success;
+        }
+
+        bool
+        SkillProxy::abortSkillAsync(const SkillExecutionID& id) const
+        {
+            ARMARX_CHECK_NOT_NULL(manager);
+            auto r = manager->abortSkillAsync(id.toManagerIce());
+            return r.success;
+        }
+
+        aron::data::DictPtr
+        SkillProxy::getRootProfileParameters() const
+        {
+            return skillDescription.rootProfileDefaults;
+        }
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillProxy.h b/source/RobotAPI/libraries/skills/core/SkillProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..e20ca01a0bc4b6de877e34a3ad6bc0edcbaa4689
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillProxy.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <RobotAPI/libraries/skills/core/SkillDescription.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
+
+namespace armarx
+{
+    namespace skills
+    {
+        /* Manages the remote execution of a skill and converts the ice types */
+        class SkillProxy : public armarx::Logging
+        {
+        public:
+            /// We remove the default constructor as every skill proxy requires a manager
+            SkillProxy() = delete;
+
+            /// set the skill proxy using a skillId. Queries the manager to get the description.
+            SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
+                       const SkillID& skillId);
+
+            /// set the proxy using a skill description
+            SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
+                       const SkillDescription& skillDesc);
+
+            /// copy ctor
+            SkillProxy(const SkillProxy& o) = default;
+
+            /// get the skill description
+            SkillDescription getSkillDescription() const;
+
+            /// get the skill id from the skill description
+            SkillID getSkillId() const;
+
+            // Provide a similar API as the skillprovider
+            /// execute a skill and block until skill terminates
+            TerminatedSkillStatusUpdate
+            executeSkill(const std::string& executorName,
+                         const aron::data::DictPtr& params = nullptr) const;
+
+            /// execute a skill. Do not block during execution
+            SkillExecutionID executeSkillAsync(const std::string& executorName,
+                                               const aron::data::DictPtr& params = nullptr) const;
+
+            /// poll execution status and block until its null or terminated
+            std::optional<TerminatedSkillStatusUpdate>
+            join(const SkillExecutionID& executionId) const;
+
+            /// ask skill to abort ASAP. Blocks until skill stopped
+            bool abortSkill(const SkillExecutionID& executionId) const;
+
+            /// ask skill to abort ASAP
+            bool abortSkillAsync(const SkillExecutionID& executionId) const;
+
+            // Utiliy methods
+            /// get the default parameters of the skill. TODO: Skill profiles in memory!
+            aron::data::DictPtr getRootProfileParameters() const;
+
+        protected:
+            manager::dti::SkillManagerInterfacePrx manager;
+            SkillDescription skillDescription;
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
index 36ac32ed7ca1217e63f41329bb3a199269a95989..986aab1bc9be867aa918c14e4471ac9fe3e7cf3f 100644
--- a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
@@ -37,7 +37,7 @@ namespace armarx
         }
 
         TerminatedSkillStatus
-        MergeSkillStatus(const TerminatedSkillStatus t1, const TerminatedSkillStatus t2)
+        mergeSkillStatuseses(const TerminatedSkillStatus t1, const TerminatedSkillStatus t2)
         {
             // if both are equal
             if (t1 == t2)
@@ -56,8 +56,8 @@ namespace armarx
         }
 
         ActiveOrTerminatedSkillStatus
-        MergeSkillStatus(const ActiveOrTerminatedSkillStatus t1,
-                         const ActiveOrTerminatedSkillStatus t2)
+        mergeSkillStatuseses(const ActiveOrTerminatedSkillStatus t1,
+                             const ActiveOrTerminatedSkillStatus t2)
         {
             // if both are equal
             if (t1 == t2)
@@ -239,12 +239,6 @@ namespace armarx
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
-        SkillStatusUpdateBase::SkillStatusUpdateBase(const SkillExecutionID& exec,
-                                                     const SkillParameterization& param) :
-            executionId(exec), usedParameterization(param)
-        {
-        }
-
         manager::dto::SkillStatusUpdate
         SkillStatusUpdateBase::toManagerIce() const
         {
@@ -253,9 +247,9 @@ namespace armarx
             ret.executionId.executorName = executionId.executorName;
             armarx::core::time::toIce(ret.executionId.executionStartedTime,
                                       executionId.executionStartedTime);
-            ret.usedParams = aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
-            ret.usedCallbackInterface = usedParameterization.callbackInterface;
-            ret.data = aron::data::Dict::ToAronDictDTO(data);
+            ret.parameters = aron::data::Dict::ToAronDictDTO(parameters);
+            ret.callbackInterface = callbackInterface;
+            ret.result = aron::data::Dict::ToAronDictDTO(result);
             return ret;
         }
 
@@ -267,9 +261,9 @@ namespace armarx
             ret.executionId.executorName = executionId.executorName;
             armarx::core::time::toIce(ret.executionId.executionStartedTime,
                                       executionId.executionStartedTime);
-            ret.usedParams = aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
-            ret.usedCallbackInterface = usedParameterization.callbackInterface;
-            ret.data = aron::data::Dict::ToAronDictDTO(data);
+            ret.parameters = aron::data::Dict::ToAronDictDTO(parameters);
+            ret.callbackInterface = callbackInterface;
+            ret.result = aron::data::Dict::ToAronDictDTO(result);
             return ret;
         }
 
@@ -324,9 +318,10 @@ namespace armarx
         TerminatedSkillStatusUpdate
         TerminatedSkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            TerminatedSkillStatusUpdate ret(skills::SkillExecutionID::FromIce(update.executionId),
-                                            skills::SkillParameterization::FromIce(
-                                                update.usedParams, update.usedCallbackInterface));
+            TerminatedSkillStatusUpdate ret{
+                {.executionId = skills::SkillExecutionID::FromIce(update.executionId),
+                 .parameters = armarx::aron::data::Dict::FromAronDictDTO(update.parameters),
+                 .callbackInterface = update.callbackInterface}};
             skills::fromIce(update.status, ret.status);
             return ret;
         }
@@ -335,10 +330,10 @@ namespace armarx
         TerminatedSkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
                                              const std::optional<skills::ProviderID>& providerId)
         {
-            TerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionID::FromIce(update.executionId, providerId),
-                skills::SkillParameterization::FromIce(update.usedParams,
-                                                       update.usedCallbackInterface));
+            TerminatedSkillStatusUpdate ret{
+                {.executionId = skills::SkillExecutionID::FromIce(update.executionId, providerId),
+                 .parameters = armarx::aron::data::Dict::FromAronDictDTO(update.parameters),
+                 .callbackInterface = update.callbackInterface}};
             skills::fromIce(update.status, ret.status);
             return ret;
         }
@@ -346,9 +341,10 @@ namespace armarx
         SkillStatusUpdate
         SkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            SkillStatusUpdate ret(skills::SkillExecutionID::FromIce(update.executionId),
-                                  skills::SkillParameterization::FromIce(
-                                      update.usedParams, update.usedCallbackInterface));
+            SkillStatusUpdate ret{
+                {.executionId = skills::SkillExecutionID::FromIce(update.executionId),
+                 .parameters = armarx::aron::data::Dict::FromAronDictDTO(update.parameters),
+                 .callbackInterface = update.callbackInterface}};
             skills::fromIce(update.status, ret.status);
             return ret;
         }
@@ -357,9 +353,10 @@ namespace armarx
         SkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
                                    const std::optional<skills::ProviderID>& providerId)
         {
-            SkillStatusUpdate ret(skills::SkillExecutionID::FromIce(update.executionId, providerId),
-                                  skills::SkillParameterization::FromIce(
-                                      update.usedParams, update.usedCallbackInterface));
+            SkillStatusUpdate ret{
+                {.executionId = skills::SkillExecutionID::FromIce(update.executionId, providerId),
+                 .parameters = armarx::aron::data::Dict::FromAronDictDTO(update.parameters),
+                 .callbackInterface = update.callbackInterface}};
             skills::fromIce(update.status, ret.status);
             return ret;
         }
@@ -367,10 +364,10 @@ namespace armarx
         ActiveOrTerminatedSkillStatusUpdate
         ActiveOrTerminatedSkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            ActiveOrTerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionID::FromIce(update.executionId),
-                skills::SkillParameterization::FromIce(update.usedParams,
-                                                       update.usedCallbackInterface));
+            ActiveOrTerminatedSkillStatusUpdate ret{
+                {.executionId = skills::SkillExecutionID::FromIce(update.executionId),
+                 .parameters = armarx::aron::data::Dict::FromAronDictDTO(update.parameters),
+                 .callbackInterface = update.callbackInterface}};
             skills::fromIce(update.status, ret.status);
             return ret;
         }
@@ -380,10 +377,10 @@ namespace armarx
             const provider::dto::SkillStatusUpdate& update,
             const std::optional<skills::ProviderID>& providerId)
         {
-            ActiveOrTerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionID::FromIce(update.executionId, providerId),
-                skills::SkillParameterization::FromIce(update.usedParams,
-                                                       update.usedCallbackInterface));
+            ActiveOrTerminatedSkillStatusUpdate ret{
+                {.executionId = skills::SkillExecutionID::FromIce(update.executionId, providerId),
+                 .parameters = armarx::aron::data::Dict::FromAronDictDTO(update.parameters),
+                 .callbackInterface = update.callbackInterface}};
             skills::fromIce(update.status, ret.status);
             return ret;
         }
diff --git a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
index 368dbe8b4a806b74698448099298d35802242658..ace31510a8a362ed45289c4facdd51c97ba22fbb 100644
--- a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
+++ b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
@@ -55,23 +55,20 @@ namespace armarx
                      ActiveOrTerminatedSkillStatus& ret);
         void fromIce(const core::dto::Execution::Status& status, SkillStatus& ret);
 
-        TerminatedSkillStatus MergeSkillStatus(const TerminatedSkillStatus t1,
-                                               const TerminatedSkillStatus t2);
-        ActiveOrTerminatedSkillStatus MergeSkillStatus(const ActiveOrTerminatedSkillStatus t1,
-                                                       const ActiveOrTerminatedSkillStatus t2);
+        TerminatedSkillStatus mergeSkillStatuseses(const TerminatedSkillStatus t1,
+                                                   const TerminatedSkillStatus t2);
+        ActiveOrTerminatedSkillStatus mergeSkillStatuseses(const ActiveOrTerminatedSkillStatus t1,
+                                                           const ActiveOrTerminatedSkillStatus t2);
 
         struct SkillStatusUpdateBase
         {
             // header
             SkillExecutionID executionId;
-            SkillParameterization usedParameterization;
-
-            SkillStatusUpdateBase() = delete;
-            SkillStatusUpdateBase(const SkillExecutionID& exec, const SkillParameterization& param);
-            SkillStatusUpdateBase(const SkillStatusUpdateBase&) = default;
+            aron::data::DictPtr parameters;
+            callback::dti::SkillProviderCallbackInterfacePrx callbackInterface;
 
             // data
-            aron::data::DictPtr data = nullptr;
+            aron::data::DictPtr result = nullptr;
 
             manager::dto::SkillStatusUpdate toManagerIce() const;
 
@@ -83,14 +80,18 @@ namespace armarx
         {
             TerminatedSkillStatus status = TerminatedSkillStatus::Failed;
 
-            using SkillStatusUpdateBase::SkillStatusUpdateBase;
-
             bool
             hasBeenTerminated() const
             {
                 return true;
             }
 
+            bool
+            hasBeenSucceeded() const
+            {
+              return status == TerminatedSkillStatus::Succeeded;
+            }
+
             manager::dto::SkillStatusUpdate toManagerIce() const;
 
             provider::dto::SkillStatusUpdate toProviderIce() const;
@@ -108,8 +109,6 @@ namespace armarx
         {
             ActiveOrTerminatedSkillStatus status = ActiveOrTerminatedSkillStatus::Failed;
 
-            using SkillStatusUpdateBase::SkillStatusUpdateBase;
-
             bool
             hasBeenTerminated() const
             {
@@ -118,6 +117,12 @@ namespace armarx
                        status == ActiveOrTerminatedSkillStatus::Aborted;
             }
 
+            bool
+            hasBeenSucceeded() const
+            {
+              return status == ActiveOrTerminatedSkillStatus::Succeeded;
+            }
+
             manager::dto::SkillStatusUpdate toManagerIce() const;
 
             provider::dto::SkillStatusUpdate toProviderIce() const;
@@ -135,8 +140,6 @@ namespace armarx
         {
             SkillStatus status = SkillStatus::Constructing;
 
-            using SkillStatusUpdateBase::SkillStatusUpdateBase;
-
             bool
             operator<(const SkillStatusUpdate& o) const
             {
@@ -204,6 +207,12 @@ namespace armarx
                        status == SkillStatus::Aborted;
             }
 
+            bool
+            hasBeenSucceeded() const
+            {
+              return status == SkillStatus::Succeeded;
+            }
+
             manager::dto::SkillStatusUpdate toManagerIce() const;
 
             provider::dto::SkillStatusUpdate toProviderIce() const;
diff --git a/source/RobotAPI/libraries/skills/core/error/Exception.h b/source/RobotAPI/libraries/skills/core/error/Exception.h
index b73ccbf1e0271f82cf95107bd6beaecdcb4440a8..5e10baed1e9af3131226320397c11919d7a826e0 100644
--- a/source/RobotAPI/libraries/skills/core/error/Exception.h
+++ b/source/RobotAPI/libraries/skills/core/error/Exception.h
@@ -24,42 +24,71 @@
 #pragma once
 
 // STD/STL
+#include <map>
 #include <string>
 #include <vector>
-#include <map>
 
 // ArmarX
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/core/exceptions/Exception.h>
-
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
 namespace armarx::skills::error
 {
     /**
-     * @brief A base class for aron exceptions. All aron exceptions inherit from this class
+     * @brief A base class for skill exceptions. All skill exceptions inherit from this class
      */
-    class SkillException :
-        public armarx::LocalException
+    class SkillException : public armarx::LocalException
     {
     public:
         SkillException() = delete;
+
         SkillException(const std::string& prettymethod, const std::string& reason) :
             LocalException(prettymethod + ": " + reason + ".")
         {
         }
     };
 
+    class SkillAbortedException : public armarx::LocalException
+    {
+    public:
+        SkillAbortedException() = delete;
+
+        SkillAbortedException(const std::string& reason) : LocalException(reason)
+        {
+        }
+
+        SkillAbortedException(const std::string& prettymethod, const std::string& reason) :
+            LocalException(prettymethod + ": " + reason + ".")
+        {
+        }
+    };
+
+    class SkillFailedException : public armarx::LocalException
+    {
+    public:
+        SkillFailedException() = delete;
+
+        SkillFailedException(const std::string& reason) : LocalException(reason)
+        {
+        }
+
+        SkillFailedException(const std::string& prettymethod, const std::string& reason) :
+            LocalException(prettymethod + ": " + reason + ".")
+        {
+        }
+    };
+
     /**
      * @brief The NotImplementedYetException class
      */
-    class NotImplementedYetException :
-        public SkillException
+    class NotImplementedYetException : public SkillException
     {
     public:
         NotImplementedYetException() = delete;
+
         NotImplementedYetException(const std::string& prettymethod) :
             SkillException(prettymethod, "This method is not yet implemented!")
         {
         }
     };
-}
+} // namespace armarx::skills::error
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 51694c8d9f2ff130f0684a0c0dda268e40c09979..3999c956b3ec3d85be444e7b27d56c27fbc2d98e 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -49,12 +49,11 @@ namespace armarx::plugins
     SkillManagerComponentPlugin::addProvider(const skills::ProviderInfo& providerInfo)
     {
         std::scoped_lock l(skillProviderMapMutex);
-        if (skillProviderMap.find(providerInfo.providerId.providerName) == skillProviderMap.end())
+        if (skillProviderMap.find(providerInfo.providerId) == skillProviderMap.end())
         {
             ARMARX_INFO << "Adding a provider with name '" << providerInfo.providerId.providerName
                         << "'.";
-            skillProviderMap.insert(
-                {providerInfo.providerId.providerName, providerInfo.providerInterface});
+            skillProviderMap.insert({providerInfo.providerId, providerInfo.providerInterface});
         }
         else
         {
@@ -62,7 +61,7 @@ namespace armarx::plugins
                         << providerInfo.providerId.providerName
                         << "' but the provider already exists. "
                         << "Overwriting the old provider info.";
-            skillProviderMap[providerInfo.providerId.providerName] = providerInfo.providerInterface;
+            skillProviderMap[providerInfo.providerId] = providerInfo.providerInterface;
         }
     }
 
@@ -70,7 +69,7 @@ namespace armarx::plugins
     SkillManagerComponentPlugin::removeProvider(const skills::ProviderID& providerId)
     {
         std::scoped_lock l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(providerId.providerName); it != skillProviderMap.end())
+        if (auto it = skillProviderMap.find(providerId); it != skillProviderMap.end())
         {
             ARMARX_INFO << "Removing a provider with name '" << providerId.providerName << "'.";
             skillProviderMap.erase(it);
@@ -85,16 +84,16 @@ namespace armarx::plugins
     skills::SkillStatusUpdate
     SkillManagerComponentPlugin::executeSkill(const skills::SkillExecutionRequest& executionRequest)
     {
-        ARMARX_CHECK(executionRequest.skillId.fullySpecified());
+        ARMARX_CHECK(executionRequest.skillId.isFullySpecified());
 
         std::unique_lock l(skillProviderMapMutex);
 
-        skills::ProviderID provderId(executionRequest.skillId);
+        skills::ProviderID provderId(*executionRequest.skillId.providerId);
 
         // TODO: Really support regexes!
         if (executionRequest.skillId.providerId->providerName == "*")
         {
-            provderId = getFirstProviderNameThatHasSkill(executionRequest.skillId.skillName);
+            provderId = getFirstProviderNameThatHasSkill(executionRequest.skillId);
         }
 
 
@@ -116,11 +115,11 @@ namespace armarx::plugins
 
             try
             {
-                skills::SkillExecutionRequest provider_executionRequest(
-                    executionRequest.skillId,
-                    executionRequest.executorName,
-                    executionRequest.params,
-                    myPrx);
+                skills::SkillExecutionRequest provider_executionRequest{
+                    .skillId = executionRequest.skillId,
+                    .executorName = executionRequest.executorName,
+                    .parameters = executionRequest.parameters,
+                    .callbackInterface = myPrx};
 
                 auto async =
                     provider->begin_executeSkill(provider_executionRequest.toProviderIce());
@@ -158,16 +157,16 @@ namespace armarx::plugins
     SkillManagerComponentPlugin::executeSkillAsync(
         const skills::SkillExecutionRequest& executionRequest)
     {
-        ARMARX_CHECK(executionRequest.skillId.fullySpecified());
+        ARMARX_CHECK(executionRequest.skillId.isFullySpecified());
 
         std::unique_lock l(skillProviderMapMutex);
 
-        skills::ProviderID provderId(executionRequest.skillId);
+        skills::ProviderID provderId(*executionRequest.skillId.providerId);
 
         // TODO: Really support regexes!
         if (executionRequest.skillId.providerId->providerName == "*")
         {
-            provderId = getFirstProviderNameThatHasSkill(executionRequest.skillId.skillName);
+            provderId = getFirstProviderNameThatHasSkill(executionRequest.skillId);
         }
 
 
@@ -189,11 +188,11 @@ namespace armarx::plugins
 
             try
             {
-                skills::SkillExecutionRequest provider_executionRequest(
-                    executionRequest.skillId,
-                    executionRequest.executorName,
-                    executionRequest.params,
-                    myPrx);
+                skills::SkillExecutionRequest provider_executionRequest{
+                    .skillId = executionRequest.skillId,
+                    .executorName = executionRequest.executorName,
+                    .parameters = executionRequest.parameters,
+                    .callbackInterface = myPrx};
 
                 auto async =
                     provider->begin_executeSkillAsync(provider_executionRequest.toProviderIce());
@@ -228,11 +227,11 @@ namespace armarx::plugins
         }
     }
 
-    void
-    SkillManagerComponentPlugin::addSkillParameters(const skills::SkillExecutionID& executionId,
-                                                    const aron::data::DictPtr& data)
+    bool
+    SkillManagerComponentPlugin::updateSkillParameters(const skills::SkillExecutionID& executionId,
+                                                       const aron::data::DictPtr& data)
     {
-        ARMARX_CHECK(executionId.skillId.fullySpecified());
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
 
         std::unique_lock l(skillProviderMapMutex);
         if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
@@ -246,29 +245,34 @@ namespace armarx::plugins
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
                                << providerId << "'. Removing it from skills.";
                 skillProviderMap.erase(it);
-                return;
+                return false;
             }
 
             try
             {
-                auto async = provider->begin_addSkillParameters(executionId.toProviderIce(),
-                                                                data->toAronDictDTO());
+                auto async = provider->begin_updateSkillParameters(executionId.toProviderIce(),
+                                                                   data->toAronDictDTO());
                 l.unlock(); // allow parallel e.g. stopping
-                provider->end_addSkillParameters(async);
-                return;
+                auto r = provider->end_updateSkillParameters(async);
+                return r.success;
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
                                << providerId << "'. Removing it from skills on next execute.";
+                return false;
             }
         }
+        else
+        {
+            return false;
+        }
     }
 
-    void
+    bool
     SkillManagerComponentPlugin::abortSkill(const skills::SkillExecutionID& executionId)
     {
-        ARMARX_CHECK(executionId.skillId.fullySpecified());
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
 
         std::unique_lock l(skillProviderMapMutex);
         if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
@@ -282,28 +286,71 @@ namespace armarx::plugins
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
                                << providerId << "'. Removing it from skills.";
                 skillProviderMap.erase(it);
-                return;
+                return false;
             }
 
             try
             {
                 auto async = provider->begin_abortSkill(executionId.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
-                provider->end_abortSkill(async);
-                return;
+                auto r = provider->end_abortSkill(async);
+                return r.success;
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
                                << providerId << "'. Removing it from skills on next execute.";
+                return false;
             }
         }
+        else
+        {
+            return false;
+        }
+    }
+
+    bool
+    SkillManagerComponentPlugin::abortSkillAsync(const skills::SkillExecutionID& executionId)
+    {
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
+
+        std::unique_lock l(skillProviderMapMutex);
+        if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
+            it != skillProviderMap.end())
+        {
+            const auto& providerId = it->first;
+            const auto& provider = it->second;
+
+            if (!provider)
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
+                               << providerId << "'. Removing it from skills.";
+                skillProviderMap.erase(it);
+                return false;
+            }
+
+            try
+            {
+                auto async = provider->begin_abortSkill(executionId.toProviderIce());
+                return true;
+            }
+            catch (...)
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
+                               << providerId << "'. Removing it from skills on next execute.";
+                return false;
+            }
+        }
+        else
+        {
+            return false;
+        }
     }
 
     std::optional<skills::SkillDescription>
     SkillManagerComponentPlugin::getSkillDescription(const skills::SkillID& skillId)
     {
-        ARMARX_CHECK(skillId.fullySpecified());
+        ARMARX_CHECK(skillId.isFullySpecified());
 
         std::unique_lock l(skillProviderMapMutex);
         if (auto it = skillProviderMap.find(*skillId.providerId); it != skillProviderMap.end())
@@ -406,7 +453,7 @@ namespace armarx::plugins
     SkillManagerComponentPlugin::getSkillExecutionStatus(
         const skills::SkillExecutionID& executionId)
     {
-        ARMARX_CHECK(executionId.skillId.fullySpecified());
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
 
         std::unique_lock l(skillProviderMapMutex);
         if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
@@ -532,9 +579,6 @@ namespace armarx
         this->plugin->removeProvider(i);
     }
 
-    using SkillProviderInterfacePrxMap =
-        std::map<std::string, skills::provider::dti::SkillProviderInterfacePrx>;
-
     skills::manager::dto::SkillStatusUpdate
     SkillManagerComponentPluginUser::executeSkill(
         const skills::manager::dto::SkillExecutionRequest& info,
@@ -553,23 +597,38 @@ namespace armarx
         return this->plugin->executeSkillAsync(e).toManagerIce();
     }
 
-    void
-    SkillManagerComponentPluginUser::addSkillParameters(
+    skills::provider::dto::ParameterUpdateResult
+    SkillManagerComponentPluginUser::updateSkillParameters(
         const skills::manager::dto::SkillExecutionID& info,
         const aron::data::dto::DictPtr& params,
         const Ice::Current& current)
     {
+        skills::provider::dto::ParameterUpdateResult ret;
         auto a = armarx::aron::data::Dict::FromAronDictDTO(params);
         auto e = skills::SkillExecutionID::FromIce(info);
-        this->plugin->addSkillParameters(e, a);
+        ret.success = this->plugin->updateSkillParameters(e, a);
+        return ret;
     }
 
-    void
+    skills::provider::dto::AbortSkillResult
     SkillManagerComponentPluginUser::abortSkill(const skills::manager::dto::SkillExecutionID& id,
                                                 const Ice::Current& current)
     {
+        skills::provider::dto::AbortSkillResult ret;
         auto i = skills::SkillExecutionID::FromIce(id);
-        this->plugin->abortSkill(i);
+        ret.success = this->plugin->abortSkill(i);
+        return ret;
+    }
+
+    skills::provider::dto::AbortSkillResult
+    SkillManagerComponentPluginUser::abortSkillAsync(
+        const skills::manager::dto::SkillExecutionID& id,
+        const Ice::Current& /*unused*/)
+    {
+        skills::provider::dto::AbortSkillResult ret;
+        auto i = skills::SkillExecutionID::FromIce(id);
+        ret.success = this->plugin->abortSkillAsync(i);
+        return ret;
     }
 
     void
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
index 57b0250a1aecf9216c34ec8d76933a59d00cb9aa..8aeea6f1ab7d387ce6c46e4212e1455c1c2a9435 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
@@ -37,10 +37,12 @@ namespace armarx::plugins
 
         skills::SkillExecutionID executeSkillAsync(const skills::SkillExecutionRequest& req);
 
-        void addSkillParameters(const skills::SkillExecutionID& id,
-                                const aron::data::DictPtr& data);
+        bool updateSkillParameters(const skills::SkillExecutionID& id,
+                                   const aron::data::DictPtr& data);
 
-        void abortSkill(const skills::SkillExecutionID& id);
+        bool abortSkill(const skills::SkillExecutionID& id);
+
+        bool abortSkillAsync(const skills::SkillExecutionID& id);
 
         std::optional<skills::SkillDescription> getSkillDescription(const skills::SkillID& id);
 
@@ -86,17 +88,24 @@ namespace armarx
         executeSkillAsync(const skills::manager::dto::SkillExecutionRequest& skillExecutionRequest,
                           const Ice::Current& current) override;
 
-        void addSkillParameters(const skills::manager::dto::SkillExecutionID& executionId,
-                                const aron::data::dto::DictPtr& params,
-                                const Ice::Current& current) override;
+        skills::provider::dto::ParameterUpdateResult
+        updateSkillParameters(const skills::manager::dto::SkillExecutionID& executionId,
+                              const aron::data::dto::DictPtr& params,
+                              const Ice::Current& current) override;
 
         void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
                                   const skills::callback::dto::ProviderID& id,
                                   const Ice::Current& current) override;
 
-        void abortSkill(const skills::manager::dto::SkillExecutionID& id,
+        skills::provider::dto::AbortSkillResult
+        abortSkill(const skills::manager::dto::SkillExecutionID& id,
+                   const Ice::Current& current) override;
+
+        skills::provider::dto::AbortSkillResult
+        abortSkillAsync(const skills::manager::dto::SkillExecutionID& id,
                         const Ice::Current& current) override;
 
+
         skills::manager::dto::SkillDescriptionMap
         getSkillDescriptions(const Ice::Current& current) override;
 
diff --git a/source/RobotAPI/libraries/skills/provider/CMakeLists.txt b/source/RobotAPI/libraries/skills/provider/CMakeLists.txt
index e5df870817e13549d985ae816081e5e989c79ee8..9cb59c319fdf937ee9eb341610071f44114de3c1 100644
--- a/source/RobotAPI/libraries/skills/provider/CMakeLists.txt
+++ b/source/RobotAPI/libraries/skills/provider/CMakeLists.txt
@@ -21,7 +21,9 @@ armarx_add_library(
         LambdaSkill.cpp
         SimpleSkill.cpp
         SimpleSpecializedSkill.cpp
-        SkillProxy.cpp
+        SimplePeriodicSpecializedSkill.cpp
+        SimplePeriodicSkill.cpp
+        SpecializedSkillProxy.cpp
         PeriodicSkill.cpp
         SpecializedSkill.cpp
         PeriodicSpecializedSkill.cpp
@@ -35,7 +37,9 @@ armarx_add_library(
         LambdaSkill.h
         SimpleSkill.h
         SimpleSpecializedSkill.h
-        SkillProxy.h
+        SimplePeriodicSpecializedSkill.h
+        SimplePeriodicSkill.h
+        SpecializedSkillProxy.h
         PeriodicSkill.h
         SpecializedSkill.h
         PeriodicSpecializedSkill.h
diff --git a/source/RobotAPI/libraries/skills/provider/LambdaSkill.h b/source/RobotAPI/libraries/skills/provider/LambdaSkill.h
index dda6c472c711f9cae1c3d6ac396218ef10f50ca5..16d39dd39578e25ecb901815e10311e7e57bab72 100644
--- a/source/RobotAPI/libraries/skills/provider/LambdaSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/LambdaSkill.h
@@ -9,16 +9,16 @@ namespace armarx
         class LambdaSkill : public Skill
         {
         public:
-            using FunT = std::function<TerminatedSkillStatus()>;
+            using FunctionType = std::function<TerminatedSkillStatus()>;
 
             LambdaSkill() = delete;
-            LambdaSkill(const SkillDescription& desc, const FunT& f) : Skill(desc), fun(f){};
+            LambdaSkill(const SkillDescription& desc, const FunctionType& f) : Skill(desc), fun(f){};
 
         private:
             MainResult main() override;
 
         private:
-            FunT fun;
+            FunctionType fun;
         };
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
index 56994fb334ee2129dd2ad3cec995308ac14b6124..fa354d03d242c9e19b95a4a846309227503ae182 100644
--- a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
@@ -36,53 +36,39 @@ namespace armarx::skills
     {
     }
 
-    PeriodicSkill::StepResult
-    PeriodicSkill::stepOfSkill()
-    {
-        return this->step();
-    }
-
     Skill::MainResult
     PeriodicSkill::main()
     {
         armarx::core::time::Metronome metronome(frequency);
 
-        while (not Skill::checkWhetherSkillShouldStopASAP())
+        while (true)
         {
-            const auto res = stepOfSkill();
+            this->throwIfSkillShouldTerminate();
+
+            const auto res = step();
             switch (res.status)
             {
                 case ActiveOrTerminatedSkillStatus::Running:
                     // nothing to do here
                     break;
                 case ActiveOrTerminatedSkillStatus::Aborted:
-                    return {TerminatedSkillStatus::Aborted, res.data};
+                    return MakeAbortedResult();
                 case ActiveOrTerminatedSkillStatus::Succeeded:
-                    return {TerminatedSkillStatus::Succeeded, res.data};
+                    return MakeSucceededResult(res.data);
                 case ActiveOrTerminatedSkillStatus::Failed:
-                    return {TerminatedSkillStatus::Failed, res.data};
+                    return MakeFailedResult();
             }
 
             const auto sleepDuration = metronome.waitForNextTick();
             if (not sleepDuration.isPositive())
             {
-                ARMARX_INFO << deactivateSpam() << "PeriodicSkill: execution took too long ("
-                            << -sleepDuration << " too long. Expected "
-                            << frequency.toCycleDuration() << ")";
+                ARMARX_INFO << deactivateSpam() << __PRETTY_FUNCTION__
+                            << ": execution took too long (" << -sleepDuration
+                            << " too long. Expected " << frequency.toCycleDuration() << ")";
             }
         }
 
-        if (stopped)
-        {
-            return {TerminatedSkillStatus::Aborted, nullptr};
-        }
-
-        if (timeoutReached)
-        {
-            ARMARX_WARNING << "The skill " << getSkillId().toString() << " reached timeout!";
-            return {TerminatedSkillStatus::Failed, nullptr};
-        }
-
+        // never happens
         throw skills::error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
     }
 
diff --git a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
index b11239dcf8074c8e53383137b0744bd720f802ff..aff91f19677f0ec362fbd7ca34ab2f3976661b96 100644
--- a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
@@ -41,8 +41,6 @@ namespace armarx::skills
 
         PeriodicSkill(const SkillDescription& skillDescription, const armarx::Frequency& frequency);
 
-        StepResult stepOfSkill();
-
     protected:
         /// Do not use anymore
         Skill::MainResult main() final;
diff --git a/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
index 1c98f112680263ac1bfb3006d8eb9be28f8e901c..914c6da0221973624309a57666064669e05de14a 100644
--- a/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
@@ -50,12 +50,6 @@ namespace armarx::skills
         {
         }
 
-        StepResult
-        stepOfSkill()
-        {
-            return this->step();
-        }
-
     protected:
         /// Do not use anymore
         Skill::MainResult
@@ -63,42 +57,33 @@ namespace armarx::skills
         {
             armarx::core::time::Metronome metronome(frequency);
 
-            while (not Skill::checkWhetherSkillShouldStopASAP())
+            while (true)
             {
-                const auto statusUpdate = stepOfSkill();
-                switch (statusUpdate.status)
+                this->throwIfSkillShouldTerminate();
+
+                const auto res = step();
+                switch (res.status)
                 {
                     case ActiveOrTerminatedSkillStatus::Running:
-                        // nothing to do here
+                        // nothing to do here. break switch
                         break;
                     case ActiveOrTerminatedSkillStatus::Aborted:
-                        return {TerminatedSkillStatus::Aborted, statusUpdate.data};
+                        return Skill::MakeAbortedResult();
                     case ActiveOrTerminatedSkillStatus::Succeeded:
-                        return {TerminatedSkillStatus::Succeeded, statusUpdate.data};
+                        return Skill::MakeSucceededResult(res.data);
                     case ActiveOrTerminatedSkillStatus::Failed:
-                        return {TerminatedSkillStatus::Failed, statusUpdate.data};
+                        return Skill::MakeFailedResult();
                 }
 
                 const auto sleepDuration = metronome.waitForNextTick();
                 if (not sleepDuration.isPositive())
                 {
-                    ARMARX_INFO << deactivateSpam() << "PeriodicSkill: execution took too long ("
-                                << -sleepDuration << " too long. Expected "
-                                << frequency.toCycleDuration() << ")";
+                    ARMARX_INFO << deactivateSpam() << __PRETTY_FUNCTION__
+                                << ": execution took too long (" << -sleepDuration
+                                << " too long. Expected " << frequency.toCycleDuration() << ")";
                 }
             }
 
-            if (stopped)
-            {
-                return {TerminatedSkillStatus::Aborted, nullptr};
-            }
-
-            if (timeoutReached)
-            {
-                ARMARX_WARNING << "The skill " << getSkillId().toString() << " reached timeout!";
-                return {TerminatedSkillStatus::Failed, nullptr};
-            }
-
             throw skills::error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
@@ -111,10 +96,6 @@ namespace armarx::skills
             return {ActiveOrTerminatedSkillStatus::Succeeded, nullptr};
         }
 
-    private:
-        using Skill::stopped;
-        using Skill::timeoutReached;
-
     protected:
         const armarx::Frequency frequency;
     };
diff --git a/source/RobotAPI/libraries/skills/provider/SimplePeriodicSkill.cpp b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSkill.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..33a6475b3a9e2e01a30c40f4cee60e304a600b40
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSkill.cpp
@@ -0,0 +1,54 @@
+#include "SimplePeriodicSkill.h"
+
+namespace armarx::skills
+{
+    SimplePeriodicSkill::SimplePeriodicSkill(const SkillDescription& skillDescription,
+                                             const armarx::Frequency& frequency) :
+        SimpleSkill(skillDescription), frequency(frequency)
+    {
+    }
+
+    Skill::MainResult
+    SimplePeriodicSkill::main(const MainInput& in)
+    {
+        armarx::core::time::Metronome metronome(frequency);
+
+        while (true)
+        {
+            this->throwIfSkillShouldTerminate();
+
+            const auto res = step(in);
+            switch (res.status)
+            {
+                case ActiveOrTerminatedSkillStatus::Running:
+                    // nothing to do here. break switch
+                    break;
+                case ActiveOrTerminatedSkillStatus::Aborted:
+                    return MakeAbortedResult();
+                case ActiveOrTerminatedSkillStatus::Succeeded:
+                    return MakeSucceededResult(res.data);
+                case ActiveOrTerminatedSkillStatus::Failed:
+                    return MakeFailedResult();
+            }
+
+            const auto sleepDuration = metronome.waitForNextTick();
+            if (not sleepDuration.isPositive())
+            {
+                ARMARX_INFO << deactivateSpam() << __PRETTY_FUNCTION__
+                            << ": execution took too long (" << -sleepDuration
+                            << " too long. Expected " << frequency.toCycleDuration() << ")";
+            }
+        }
+
+        // never happens
+        throw skills::error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
+    }
+
+    SimplePeriodicSkill::StepResult
+    SimplePeriodicSkill::step(const MainInput& in)
+    {
+        ARMARX_IMPORTANT << "Dummy executing once skill '" << description.skillId
+                         << "'. Please overwrite this method!";
+        return {ActiveOrTerminatedSkillStatus::Succeeded, nullptr};
+    }
+} // namespace armarx::skills
diff --git a/source/RobotAPI/libraries/skills/provider/SimplePeriodicSkill.h b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSkill.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ca70d213277e50fd5350458e62b8c8428050b52
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSkill.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "PeriodicSkill.h"
+#include "SimpleSkill.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        class SimplePeriodicSkill : public SimpleSkill
+        {
+        public:
+            using Base = SimpleSkill;
+
+            using Base::Base;
+
+            using StepResult = PeriodicSkill::StepResult;
+
+            SimplePeriodicSkill(const SkillDescription& skillDescription,
+                                const armarx::Frequency& frequency);
+
+        protected:
+            /// Do not use anymore
+            Skill::MainResult main(const MainInput& in) final;
+
+            /// Override this method with your own step function
+            virtual StepResult step(const MainInput& in);
+
+        protected:
+            const armarx::Frequency frequency;
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SimplePeriodicSpecializedSkill.cpp b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSpecializedSkill.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a04c2b3d821e7e821dd2158a98a636d9b3338b03
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSpecializedSkill.cpp
@@ -0,0 +1,6 @@
+#include "SimplePeriodicSpecializedSkill.h"
+
+namespace armarx::skills
+{
+
+}
diff --git a/source/RobotAPI/libraries/skills/provider/SimplePeriodicSpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSpecializedSkill.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce3c968f587a7984fb606e8485297aa56ffff04a
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SimplePeriodicSpecializedSkill.h
@@ -0,0 +1,79 @@
+#pragma once
+
+#include "PeriodicSkill.h"
+#include "SimpleSpecializedSkill.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        template <class AronT>
+        class SimplePeriodicSpecializedSkill : public SimpleSpecializedSkill<AronT>
+        {
+
+        public:
+            using Base = SimpleSpecializedSkill<AronT>;
+            using ParamType = AronT;
+
+            using Base::Base;
+
+            using StepResult = PeriodicSkill::StepResult;
+
+            SimplePeriodicSpecializedSkill(const SkillDescription& skillDescription,
+                                           const armarx::Frequency& frequency) :
+                Base(skillDescription), frequency(frequency)
+            {
+            }
+
+        protected:
+            /// Do not use anymore
+            Skill::MainResult
+            main(const typename Base::SpecializedMainInput& in) final
+            {
+                armarx::core::time::Metronome metronome(frequency);
+
+                while (true)
+                {
+                    this->throwIfSkillShouldTerminate();
+
+                    const auto res = step(in);
+                    switch (res.status)
+                    {
+                        case ActiveOrTerminatedSkillStatus::Running:
+                            // nothing to do here. break switch
+                            break;
+                        case ActiveOrTerminatedSkillStatus::Aborted:
+                            return Skill::MakeAbortedResult();
+                        case ActiveOrTerminatedSkillStatus::Succeeded:
+                            return Skill::MakeSucceededResult(res.data);
+                        case ActiveOrTerminatedSkillStatus::Failed:
+                            return Skill::MakeFailedResult();
+                    }
+
+                    const auto sleepDuration = metronome.waitForNextTick();
+                    if (not sleepDuration.isPositive())
+                    {
+                        ARMARX_INFO << deactivateSpam() << __PRETTY_FUNCTION__
+                                    << ": execution took too long (" << -sleepDuration
+                                    << " too long. Expected " << frequency.toCycleDuration() << ")";
+                    }
+                }
+
+                // never happens
+                throw skills::error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
+            }
+
+            /// Override this method with your own step function
+            virtual StepResult
+            step(const typename Base::SpecializedMainInput& in)
+            {
+                ARMARX_IMPORTANT << "Dummy executing once skill '" << this->description.skillId
+                                 << "'. Please overwrite this method!";
+                return {ActiveOrTerminatedSkillStatus::Succeeded, nullptr};
+            }
+
+        protected:
+            const armarx::Frequency frequency;
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SimpleSkill.cpp b/source/RobotAPI/libraries/skills/provider/SimpleSkill.cpp
index 96ec8391771ba52b6a5d6d813f3692a3116e12b0..b6e834b4cf3114bd0938328482d00a2d243eb60e 100644
--- a/source/RobotAPI/libraries/skills/provider/SimpleSkill.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SimpleSkill.cpp
@@ -3,42 +3,42 @@
 namespace armarx::skills
 {
     Skill::InitResult
-    SimpleSKill::init()
+    SimpleSkill::init()
     {
         InitInput i;
         i.executorName = this->executorName;
-        i.params = this->parameters;
+        i.parameters = this->parameters;
         return this->init(i);
     }
 
     Skill::MainResult
-    SimpleSKill::main()
+    SimpleSkill::main()
     {
         MainInput i;
         i.executorName = this->executorName;
-        i.params = this->parameters;
+        i.parameters = this->parameters;
         i.callback = this->callback;
         return this->main(i);
     }
 
     Skill::ExitResult
-    SimpleSKill::exit()
+    SimpleSkill::exit()
     {
         ExitInput i;
         i.executorName = this->executorName;
-        i.params = this->parameters;
+        i.parameters = this->parameters;
         return this->exit(i);
     }
 
     Skill::InitResult
-    SimpleSKill::init(const InitInput& in)
+    SimpleSkill::init(const InitInput& in)
     {
         // Default nothing to init
         return {.status = TerminatedSkillStatus::Succeeded};
     }
 
     Skill::MainResult
-    SimpleSKill::main(const MainInput& in)
+    SimpleSkill::main(const MainInput& in)
     {
         // This is just a dummy implementation
         ARMARX_IMPORTANT << "Dummy executing skill '" << description.skillId
@@ -47,7 +47,7 @@ namespace armarx::skills
     }
 
     Skill::ExitResult
-    SimpleSKill::exit(const ExitInput& in)
+    SimpleSkill::exit(const ExitInput& in)
     {
         // Default nothing to exit
         return {.status = TerminatedSkillStatus::Succeeded};
diff --git a/source/RobotAPI/libraries/skills/provider/SimpleSkill.h b/source/RobotAPI/libraries/skills/provider/SimpleSkill.h
index c4b736dfb0b96f12fb42ffcf6eb6d0218252daa2..45e4715d8bfaf4cc06c98199c67679396c071674 100644
--- a/source/RobotAPI/libraries/skills/provider/SimpleSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/SimpleSkill.h
@@ -6,28 +6,30 @@ namespace armarx
 {
     namespace skills
     {
-        class SimpleSKill : public Skill
+        class SimpleSkill : public Skill
         {
         public:
-            using Skill::Skill;
+            using Base = Skill;
+
+            using Base::Base;
 
             struct InitInput
             {
                 std::string executorName;
-                aron::data::DictPtr params;
+                aron::data::DictPtr parameters;
             };
 
             struct MainInput
             {
                 std::string executorName;
-                aron::data::DictPtr params;
+                aron::data::DictPtr parameters;
                 CallbackT callback;
             };
 
             struct ExitInput
             {
                 std::string executorName;
-                aron::data::DictPtr params;
+                aron::data::DictPtr parameters;
             };
 
 
diff --git a/source/RobotAPI/libraries/skills/provider/SimpleSpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/SimpleSpecializedSkill.h
index a62ca4ae5c7a2aa54c231beb6805a1b71d044f7a..c134754888f6749a834ffdd1e256b0aed9660562 100644
--- a/source/RobotAPI/libraries/skills/provider/SimpleSpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/SimpleSpecializedSkill.h
@@ -1,95 +1,88 @@
 #pragma once
 
-#include <RobotAPI/libraries/skills/core/Skill.h>
+#include <RobotAPI/libraries/skills/provider/SpecializedSkill.h>
 
 namespace armarx
 {
     namespace skills
     {
         template <class AronT>
-        class SimpleSpecializedSkill : public Skill
+        class SimpleSpecializedSkill : public SpecializedSkill<AronT>
         {
         public:
+            using Base = SpecializedSkill<AronT>;
             using ParamType = AronT;
-            using Skill::Skill;
+
+            using Base::Base;
 
             struct SpecializedInitInput
             {
                 std::string executorName;
-                AronT params;
+                AronT parameters;
             };
 
             struct SpecializedMainInput
             {
                 std::string executorName;
-                AronT params;
-                CallbackT callback;
+                AronT parameters;
+                Skill::CallbackT callback;
             };
 
             struct SpecializedExitInput
             {
                 std::string executorName;
-                AronT params;
+                AronT parameters;
             };
 
 
         protected:
             // legacy methods
-            virtual InitResult
+            virtual Skill::InitResult
             init(const SpecializedInitInput& in)
             {
-                return InitResult{.status = TerminatedSkillStatus::Succeeded};
+                return Skill::InitResult{.status = TerminatedSkillStatus::Succeeded};
             }
 
-            virtual MainResult
+            virtual Skill::MainResult
             main(const SpecializedMainInput& in)
             {
-                ARMARX_IMPORTANT << "Dummy executing skill '" << description.skillId
+                ARMARX_IMPORTANT << "Dummy executing skill '" << this->description.skillId
                                  << "'. Please overwrite this method.";
                 return Skill::MainResult{.status = TerminatedSkillStatus::Succeeded,
                                          .data = nullptr};
             }
 
-            virtual ExitResult
+            virtual Skill::ExitResult
             exit(const SpecializedExitInput& in)
             {
-                return ExitResult{.status = TerminatedSkillStatus::Succeeded};
+                return Skill::ExitResult{.status = TerminatedSkillStatus::Succeeded};
             }
 
-            InitResult
+            Skill::InitResult
             init() final
             {
-                AronT p;
-                p.fromAron(this->parameters);
-
                 SpecializedInitInput i;
                 i.executorName = this->executorName;
-                i.params = p;
+                i.parameters = this->getParameters();
                 return this->init(i);
             }
 
-            MainResult
+            Skill::MainResult
             main() final
             {
-                AronT p;
-                p.fromAron(this->parameters);
-
                 SpecializedMainInput i;
                 i.executorName = this->executorName;
                 i.callback = this->callback;
-                i.params = p;
+                i.parameters = this->getParameters();
                 return this->main(i);
             }
 
-            ExitResult
+            Skill::ExitResult
             exit() final
             {
-                AronT p;
-                p.fromAron(this->parameters);
-
                 SpecializedExitInput i;
                 i.executorName = this->executorName;
-                i.params = p;
+                i.parameters = this->getParameters();
                 return this->exit(i);
             }
         };
diff --git a/source/RobotAPI/libraries/skills/provider/SkillContext.h b/source/RobotAPI/libraries/skills/provider/SkillContext.h
index df5a90eb7abf887c0c262794f52aee9016095120..a5efb050b3e3e2fa005f20b5f6690026ddcb8573 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillContext.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillContext.h
@@ -7,7 +7,9 @@ namespace armarx
 {
     namespace skills
     {
-        /* A virtual base class for skill contexts. It is not required to use a context for skills but it eases the management of dependencies and properties for providers */
+        /* A virtual base class for skill contexts.
+         * It is not required to use a context for skills but it eases the management of
+         * dependencies and properties for providers */
         class SkillContext
         {
         public:
diff --git a/source/RobotAPI/libraries/skills/provider/SkillFactory.h b/source/RobotAPI/libraries/skills/provider/SkillFactory.h
index ea4cd5edbff7130b560e7725fc57cda70841612d..1e3b40e3daf092e9214fc65846ec1c58b57e2b52 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillFactory.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillFactory.h
@@ -8,35 +8,43 @@ namespace armarx
 {
     namespace skills
     {
-        class SkillFactory
+        class SkillBlueprint
         {
         public:
-            using FunTSkill = std::function<std::unique_ptr<Skill>()>;
+            using FunctionTypeToCreateSkill = std::function<std::unique_ptr<Skill>()>;
 
-            SkillFactory(const FunTSkill& s) : createS(s)
+            SkillBlueprint(const FunctionTypeToCreateSkill& s) : _createSkill(s)
             {
             }
 
+            SkillBlueprint(FunctionTypeToCreateSkill&& s) : _createSkill(std::move(s))
+            {
+            }
+
+            SkillBlueprint(const SkillBlueprint&) = default;
+
+            virtual ~SkillBlueprint() = default;
+
             template <class _Skill, class... Args>
             requires isSkill<_Skill>
 
-            static std::unique_ptr<SkillFactory>
+            static std::unique_ptr<SkillBlueprint>
             ForSkill(Args&&... args)
-
             {
-                // capture params in new lambda
-                // (https://stackoverflow.com/questions/47496358/c-lambdas-how-to-capture-variadic-parameter-pack-from-the-upper-scope)
-                auto createS = [... args = std::forward<Args>(args)]()
-                { return std::make_unique<_Skill>(std::forward<Args>(args)...); };
+                auto _createSkill = [=]()
+                {
+                    auto ptr = std::make_unique<_Skill>(args...);
+                    return ptr;
+                };
 
-                auto ret = std::make_unique<SkillFactory>(createS);
+                auto ret = std::make_unique<SkillBlueprint>(std::move(_createSkill));
                 return ret;
             }
 
             virtual std::unique_ptr<Skill>
             createSkill(const skills::ProviderID& pid) const
             {
-                auto s = createS();
+                auto s = _createSkill();
                 s->setProviderId(pid);
                 return s;
             }
@@ -50,11 +58,11 @@ namespace armarx
 
 
         protected:
-            FunTSkill createS;
+            FunctionTypeToCreateSkill _createSkill;
         };
 
         template <class T>
-        concept isSkillFactory = std::is_base_of<SkillFactory, T>::value;
+        concept isSkillBlueprint = std::is_base_of<SkillBlueprint, T>::value;
 
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
index d24535a2241afc4493ab354968313151217e5105..a42d7808284d958d965cfba0dd70aa866a47cc17 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
@@ -26,7 +26,9 @@ namespace armarx::plugins
         const std::string providerName = p.getName();
 
         // register self to manager
-        skills::ProviderInfo i(skills::ProviderID(providerName), myPrx, getSkillDescriptions());
+        skills::ProviderInfo i{.providerId = skills::ProviderID{.providerName = providerName},
+                               .providerInterface = myPrx,
+                               .providedSkills = getSkillDescriptions()};
 
         ARMARX_INFO << "Adding provider to manager: " << i.providerId;
         manager->addProvider(i.toIce()); // add provider info to manager
@@ -54,7 +56,7 @@ namespace armarx::plugins
     }
 
     void
-    SkillProviderComponentPlugin::addSkillFactory(std::unique_ptr<skills::SkillFactory>&& fac)
+    SkillProviderComponentPlugin::addSkillFactory(std::unique_ptr<skills::SkillBlueprint>&& fac)
     {
         if (!fac)
         {
@@ -90,18 +92,18 @@ namespace armarx::plugins
         //        }
     }
 
-    skills::SkillFactory*
+    skills::SkillBlueprint*
     SkillProviderComponentPlugin::addSkillFactory(const skills::SkillDescription& desc,
-                                                  const skills::LambdaSkill::FunT& f)
+                                                  const skills::LambdaSkill::FunctionType& f)
     {
         return addSkillFactory<skills::LambdaSkill>(desc, f);
     }
 
-    skills::SkillFactory*
+    skills::SkillBlueprint*
     SkillProviderComponentPlugin::getSkillFactory(const armarx::skills::SkillID& skillId)
     {
         // NON BLOCKING: WE ASSERT THAT THE LOCK IS ALREADY TAKEN
-        ARMARX_CHECK(skillId.fullySpecified());
+        ARMARX_CHECK(skillId.isFullySpecified());
 
         if (skillFactories.count(skillId) == 0)
         {
@@ -110,17 +112,17 @@ namespace armarx::plugins
         }
 
         auto* facPtr = skillFactories.at(skillId).get();
-        return static_cast<skills::SkillFactory*>(facPtr);
+        return static_cast<skills::SkillBlueprint*>(facPtr);
     }
 
     std::optional<skills::SkillStatusUpdate>
     SkillProviderComponentPlugin::getSkillExecutionStatus(
         const skills::SkillExecutionID& execId) const
     {
-        ARMARX_CHECK(execId.skillId.skillSpecified());
+        ARMARX_CHECK(execId.skillId.isSkillSpecified());
 
         const std::unique_lock l(skillExecutionsMutex);
-        if (skillExecutions.find(execId) != skillExecutions.end())
+        if (skillExecutions.find(execId) == skillExecutions.end())
         {
             ARMARX_WARNING << "Skill execution for skill '" + execId.skillId.toString() +
                                   "' not found!";
@@ -147,12 +149,22 @@ namespace armarx::plugins
     std::optional<skills::SkillDescription>
     SkillProviderComponentPlugin::getSkillDescription(const skills::SkillID& skillId) const
     {
-        ARMARX_CHECK(skillId.fullySpecified());
+        ARMARX_CHECK(skillId.isFullySpecified());
 
         const std::unique_lock l(skillFactoriesMutex);
-        if (skillFactories.find(skillId) != skillFactories.end())
+        if (skillFactories.find(skillId) == skillFactories.end())
         {
-            ARMARX_WARNING << "Skill description for skill '" + skillId.toString() + "' not found!";
+            std::stringstream ss;
+            ss << "Skill description for skill '" + skillId.toString() +
+                      "' not found! Found instead: {"
+               << "\n";
+            for (const auto& [k, _] : skillFactories)
+            {
+                ss << "\t" << k.toString() << "\n";
+            }
+            ss << "}";
+            ARMARX_WARNING << ss.str();
+
             return std::nullopt;
         }
 
@@ -166,7 +178,7 @@ namespace armarx::plugins
         const std::unique_lock l(skillFactoriesMutex);
         for (const auto& [key, fac] : skillFactories)
         {
-            ARMARX_CHECK(key.fullySpecified());
+            ARMARX_CHECK(key.isFullySpecified());
             skillDesciptions.insert({key, fac->createSkillDescription(*key.providerId)});
         }
         return skillDesciptions;
@@ -176,66 +188,56 @@ namespace armarx::plugins
     SkillProviderComponentPlugin::executeSkill(
         const skills::SkillExecutionRequest& executionRequest)
     {
-        ARMARX_CHECK(executionRequest.skillId.fullySpecified());
+        ARMARX_CHECK(executionRequest.skillId.isFullySpecified());
 
-        // The skill will be executed in a seperate thread
-        std::thread execution;
+        skills::SkillExecutionID executionId{.skillId = executionRequest.skillId,
+                                             .executorName = executionRequest.executorName,
+                                             .executionStartedTime =
+                                                 armarx::core::time::DateTime::Now()};
 
-        // setup input args for skill execution
-        skills::SkillParameterization usedParameterization{executionRequest.params,
-                                                           executionRequest.callbackInterface};
+        skills::SkillStatusUpdate ret{
+            {executionId, executionRequest.parameters, executionRequest.callbackInterface}};
 
-        skills::SkillExecutionID executionId(executionRequest.skillId,
-                                             executionRequest.executorName,
-                                             armarx::core::time::DateTime::Now());
-
-        skills::SkillStatusUpdate ret{executionId, usedParameterization};
+        skills::detail::SkillRuntime* wrapper;
         {
             auto l1 = std::unique_lock{skillFactoriesMutex};
 
-            const auto& fac = getSkillFactory(executionRequest.skillId);
-            ARMARX_CHECK(fac) << "Could not find a factory for skill " << executionRequest.skillId;
+            const auto& fac = getSkillFactory(executionId.skillId);
+            ARMARX_CHECK(fac) << "Could not find a factory for skill " << executionId.skillId;
+
+            {
+                const std::unique_lock l2{skillExecutionsMutex};
+                auto it =
+                    skillExecutions.emplace(std::piecewise_construct,
+                                            std::make_tuple(executionId),
+                                            std::make_tuple(*fac,
+                                                            executionId,
+                                                            executionRequest.parameters,
+                                                            executionRequest.callbackInterface));
+                wrapper = &it.first->second;
+            }
 
             // async start execution. But we wait for the execution to finish at the end of this method
-            execution = std::thread(
+            wrapper->execution = std::thread(
                 [&]()
                 {
-                    skills::detail::SkillImplementationWrapper* wrapper;
-                    {
-                        const std::unique_lock l2{skillExecutionsMutex};
-                        auto it = skillExecutions.emplace(
-                            std::piecewise_construct,
-                            std::make_tuple(executionId),
-                            std::make_tuple(*fac, executionId, usedParameterization));
-
-                        ARMARX_CHECK(it.second)
-                            << "For some reason a skill '" << executionId.skillId.toString()
-                            << "' execution failed when instantiating the "
-                               "wrapper class and adding it to the internally used map. This "
-                               "should "
-                               "not happen!!";
-
-                        wrapper = &it.first->second;
-                    }
-
-
                     // execute waits until the previous execution finishes.
                     auto x = wrapper->executeSkill();
-                    ret.data = x.data;
+                    ret.result = x.result;
                     ret.status = armarx::skills::toSkillStatus(x.status);
                 });
         } // release lock. We don't know how long the skill needs to finish and we have to release the lock for being able to abort the execution
 
-        if (execution.joinable())
+        if (wrapper && wrapper->execution.joinable())
         {
-            execution.join();
+            wrapper->execution.join();
 
             // tidy up map of executions
-            const std::unique_lock l2{skillExecutionsMutex};
-            if (auto it = skillExecutions.find(executionId); it != skillExecutions.end())
-            {
-                skillExecutions.erase(it);
-            }
+            //            const std::unique_lock l2{skillExecutionsMutex};
+            //            if (auto it = skillExecutions.find(executionId); it != skillExecutions.end())
+            //            {
+            //                skillExecutions.erase(it);
+            //            }
         }
         return ret;
     }
@@ -244,62 +246,62 @@ namespace armarx::plugins
     SkillProviderComponentPlugin::executeSkillAsync(
         const skills::SkillExecutionRequest& executionRequest)
     {
-        ARMARX_CHECK(executionRequest.skillId.fullySpecified());
-
-        // The skill will be executed in a seperate thread
-        std::thread execution;
-
-        // setup input args for skill execution
-        skills::SkillParameterization usedParameterization{executionRequest.params,
-                                                           executionRequest.callbackInterface};
+        ARMARX_CHECK(executionRequest.skillId.isFullySpecified());
 
-        skills::SkillExecutionID executionId(executionRequest.skillId,
+        skills::SkillExecutionID executionId{executionRequest.skillId,
                                              executionRequest.executorName,
-                                             armarx::core::time::DateTime::Now());
+                                             armarx::core::time::DateTime::Now()};
 
+        skills::detail::SkillRuntime* wrapper;
         {
             auto l1 = std::unique_lock{skillFactoriesMutex};
 
-            const auto& fac = getSkillFactory(executionRequest.skillId);
-            ARMARX_CHECK(fac) << "Could not find a factory for skill " << executionRequest.skillId;
+            const auto& fac = getSkillFactory(executionId.skillId);
+            ARMARX_CHECK(fac) << "Could not find a factory for skill " << executionId.skillId;
 
-            // async start execution. But we wait for the execution to finish at the end of this method
-            execution = std::thread(
+            {
+                const std::unique_lock l2{skillExecutionsMutex};
+                auto it =
+                    skillExecutions.emplace(std::piecewise_construct,
+                                            std::make_tuple(executionId),
+                                            std::make_tuple(*fac,
+                                                            executionId,
+                                                            executionRequest.parameters,
+                                                            executionRequest.callbackInterface));
+                wrapper = &it.first->second;
+            }
+
+            wrapper->execution = std::thread(
                 [&]()
                 {
-                    skills::detail::SkillImplementationWrapper* wrapper;
-                    {
-                        const std::unique_lock l2{skillExecutionsMutex};
-                        auto it = skillExecutions.emplace(
-                            std::piecewise_construct,
-                            std::make_tuple(executionId),
-                            std::make_tuple(*fac, executionId, usedParameterization));
-
-                        ARMARX_CHECK(it.second)
-                            << "For some reason a skill '" << executionId.skillId.toString()
-                            << "' execution failed when instantiating the "
-                               "wrapper class and adding it to the internally used map. This "
-                               "should "
-                               "not happen!!";
-
-                        wrapper = &it.first->second;
-                    }
-
-
                     // execute waits until the previous execution finishes.
                     auto x = wrapper->executeSkill();
                 });
-        } // release lock. We don't know how long the skill needs to finish and we have to release the lock for being able to abort the execution
+        }
+
+        // wait until skill is constructed. This assures, that a status update exists.
+        while (true)
+        {
+            {
+                std::scoped_lock l(wrapper->skillStatusesMutex);
+
+                if (wrapper->statusUpdate.hasBeenConstructed())
+                {
+                    break;
+                }
+            }
+
+            std::this_thread::sleep_for(std::chrono::milliseconds(20));
+        }
 
-        execution.detach();
         return executionId;
     }
 
-    void
-    SkillProviderComponentPlugin::addSkillParameters(const skills::SkillExecutionID& executionId,
-                                                     const armarx::aron::data::DictPtr& input)
+    bool
+    SkillProviderComponentPlugin::updateSkillParameters(const skills::SkillExecutionID& executionId,
+                                                        const armarx::aron::data::DictPtr& input)
     {
-        ARMARX_CHECK(executionId.skillId.fullySpecified());
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
 
         const std::scoped_lock l{skillExecutionsMutex};
         auto it = skillExecutions.find(executionId);
@@ -307,7 +309,7 @@ namespace armarx::plugins
         {
             ARMARX_INFO << "No acive execution for skill '" + executionId.skillId.toString() +
                                "' found! Ignoring prepareSkill request.";
-            return;
+            return false;
         }
 
         std::scoped_lock l2{it->second.skillStatusesMutex};
@@ -315,16 +317,17 @@ namespace armarx::plugins
         {
             ARMARX_INFO << "Could not prepare the skill '" + executionId.skillId.toString() +
                                "' because its not in preparing phase.";
-            return;
+            return false;
         }
 
-        it->second.addSkillParameters(input);
+        it->second.updateSkillParameters(input);
+        return true;
     }
 
-    void
+    bool
     SkillProviderComponentPlugin::abortSkill(const skills::SkillExecutionID& executionId)
     {
-        ARMARX_CHECK(executionId.skillId.fullySpecified());
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
 
         const std::unique_lock l(skillExecutionsMutex);
         auto it = skillExecutions.find(executionId);
@@ -332,10 +335,45 @@ namespace armarx::plugins
         {
             ARMARX_INFO << "No acive execution for skill '" + executionId.skillId.toString() +
                                "' found! Ignoring abortSkill request.";
-            return;
+            return false;
+        }
+
+        auto& runtime = it->second;
+        runtime.stopSkill();
+
+        while (true)
+        {
+            {
+                std::scoped_lock l(runtime.skillStatusesMutex);
+                auto status = runtime.statusUpdate;
+
+                if (status.hasBeenTerminated())
+                {
+                    break;
+                }
+            }
+            std::this_thread::sleep_for(std::chrono::milliseconds(20));
+        }
+
+        return true;
+    }
+
+    bool
+    SkillProviderComponentPlugin::abortSkillAsync(const skills::SkillExecutionID& executionId)
+    {
+        ARMARX_CHECK(executionId.skillId.isFullySpecified());
+
+        const std::unique_lock l(skillExecutionsMutex);
+        auto it = skillExecutions.find(executionId);
+        if (it == skillExecutions.end())
+        {
+            ARMARX_INFO << "No acive execution for skill '" + executionId.skillId.toString() +
+                               "' found! Ignoring abortSkill request.";
+            return false;
         }
 
         it->second.stopSkill();
+        return true;
     }
 
 } // namespace armarx::plugins
@@ -352,7 +390,7 @@ namespace armarx
         const skills::provider::dto::SkillID& skillId,
         const Ice::Current& /*unused*/)
     {
-        auto id = skills::SkillID::FromIce(skillId, getName());
+        auto id = skills::SkillID::FromIce(skillId, skills::ProviderID{.providerName = getName()});
         auto o = plugin->getSkillDescription(id);
         if (o.has_value())
         {
@@ -377,7 +415,8 @@ namespace armarx
         const skills::provider::dto::SkillExecutionID& executionId,
         const Ice::Current& /*unused*/)
     {
-        auto execId = skills::SkillExecutionID::FromIce(executionId, getName());
+        auto execId = skills::SkillExecutionID::FromIce(
+            executionId, skills::ProviderID{.providerName = getName()});
         auto o = plugin->getSkillExecutionStatus(execId);
         if (o.has_value())
         {
@@ -403,7 +442,8 @@ namespace armarx
         const skills::provider::dto::SkillExecutionRequest& info,
         const Ice::Current& /*unused*/)
     {
-        auto exec = skills::SkillExecutionRequest::FromIce(info, getName());
+        auto exec = skills::SkillExecutionRequest::FromIce(
+            info, skills::ProviderID{.providerName = getName()});
         auto up = this->plugin->executeSkill(exec);
         return up.toProviderIce();
     }
@@ -413,28 +453,48 @@ namespace armarx
         const skills::provider::dto::SkillExecutionRequest& info,
         const Ice::Current& current /*unused*/)
     {
-        auto exec = skills::SkillExecutionRequest::FromIce(info, getName());
+        auto exec = skills::SkillExecutionRequest::FromIce(
+            info, skills::ProviderID{.providerName = getName()});
         auto id = this->plugin->executeSkillAsync(exec);
         return id.toProviderIce();
     }
 
-    void
-    SkillProviderComponentPluginUser::addSkillParameters(
+    skills::provider::dto::ParameterUpdateResult
+    SkillProviderComponentPluginUser::updateSkillParameters(
         const skills::provider::dto::SkillExecutionID& id,
         const aron::data::dto::DictPtr& input,
         const Ice::Current& current /*unused*/)
     {
-        auto exec = skills::SkillExecutionID::FromIce(id, getName());
+        skills::provider::dto::ParameterUpdateResult res;
+
+        auto exec =
+            skills::SkillExecutionID::FromIce(id, skills::ProviderID{.providerName = getName()});
         auto prep = armarx::aron::data::Dict::FromAronDictDTO(input);
-        this->plugin->addSkillParameters(exec, prep);
+        res.success = this->plugin->updateSkillParameters(exec, prep);
+        return res;
     }
 
-    void
+    skills::provider::dto::AbortSkillResult
     SkillProviderComponentPluginUser::abortSkill(const skills::provider::dto::SkillExecutionID& id,
                                                  const Ice::Current& /*unused*/)
     {
-        auto exec = skills::SkillExecutionID::FromIce(id, getName());
-        this->plugin->abortSkill(exec);
+        skills::provider::dto::AbortSkillResult res;
+        auto exec =
+            skills::SkillExecutionID::FromIce(id, skills::ProviderID{.providerName = getName()});
+        res.success = this->plugin->abortSkill(exec);
+        return res;
+    }
+
+    skills::provider::dto::AbortSkillResult
+    SkillProviderComponentPluginUser::abortSkillAsync(
+        const skills::provider::dto::SkillExecutionID& id,
+        const Ice::Current& /*unused*/)
+    {
+        skills::provider::dto::AbortSkillResult res;
+        auto exec =
+            skills::SkillExecutionID::FromIce(id, skills::ProviderID{.providerName = getName()});
+        res.success = this->plugin->abortSkillAsync(exec);
+        return res;
     }
 
     const std::experimental::observer_ptr<plugins::SkillProviderComponentPlugin>&
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
index e03d73e26da0ae1fbec86daeca5bd8f1021f5a9f..812cc0a8814db843793038ebdd16a3a927c912cf 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
@@ -49,31 +49,31 @@ namespace armarx::plugins
 
         void preOnDisconnectComponent() override;
 
-        void addSkillFactory(std::unique_ptr<skills::SkillFactory>&&);
+        void addSkillFactory(std::unique_ptr<skills::SkillBlueprint>&&);
 
-        skills::SkillFactory* addSkillFactory(const skills::SkillDescription&,
-                                              const skills::LambdaSkill::FunT&);
+        skills::SkillBlueprint* addSkillFactory(const skills::SkillDescription&,
+                                                const skills::LambdaSkill::FunctionType&);
 
-        template <class _Skill, typename... Args>
+        template <class SkillT, typename... Args>
 
-        requires skills::isSkill<_Skill> skills::SkillFactory*
+        requires skills::isSkill<SkillT> skills::SkillBlueprint*
         addSkillFactory(Args&&... args)
         {
-            auto fac = skills::SkillFactory::ForSkill<_Skill>(std::forward<Args>(args)...);
+            auto fac = skills::SkillBlueprint::ForSkill<SkillT>(std::forward<Args>(args)...);
             auto* facPtr = fac.get();
             addSkillFactory(std::move(fac));
-            return static_cast<skills::SkillFactory*>(facPtr);
+            return static_cast<skills::SkillBlueprint*>(facPtr);
         }
 
-        template <typename _FactoryT, typename... Args>
+        template <typename FactoryT, typename... Args>
 
-        requires skills::isSkillFactory<_FactoryT> _FactoryT*
+        requires skills::isSkillBlueprint<FactoryT> FactoryT*
         addCustomSkillFactory(Args&&... args)
         {
-            auto fac = std::make_unique<_FactoryT>(std::forward<Args>(args)...);
+            auto fac = std::make_unique<FactoryT>(std::forward<Args>(args)...);
             auto* facPtr = fac.get();
             addCustomSkillFactory(std::move(fac));
-            return static_cast<_FactoryT*>(facPtr);
+            return static_cast<FactoryT*>(facPtr);
         }
 
         // Ice forwards
@@ -90,23 +90,25 @@ namespace armarx::plugins
         skills::SkillExecutionID
         executeSkillAsync(const skills::SkillExecutionRequest& executionInfo);
 
-        void addSkillParameters(const skills::SkillExecutionID& id,
-                                const armarx::aron::data::DictPtr& params);
+        bool updateSkillParameters(const skills::SkillExecutionID& id,
+                                   const armarx::aron::data::DictPtr& params);
 
-        void abortSkill(const skills::SkillExecutionID& execId);
+        bool abortSkill(const skills::SkillExecutionID& execId);
+
+        bool abortSkillAsync(const skills::SkillExecutionID& execId);
 
     private:
-        skills::SkillFactory* getSkillFactory(const armarx::skills::SkillID& name);
+        skills::SkillBlueprint* getSkillFactory(const armarx::skills::SkillID& name);
+
 
         skills::manager::dti::SkillManagerInterfacePrx manager;
         skills::provider::dti::SkillProviderInterfacePrx myPrx;
 
         mutable std::mutex skillFactoriesMutex;
-        std::map<skills::SkillID, std::unique_ptr<skills::SkillFactory>> skillFactories;
+        std::map<skills::SkillID, std::unique_ptr<skills::SkillBlueprint>> skillFactories;
 
         mutable std::mutex skillExecutionsMutex;
-        std::map<skills::SkillExecutionID, skills::detail::SkillImplementationWrapper>
-            skillExecutions;
+        std::map<skills::SkillExecutionID, skills::detail::SkillRuntime> skillExecutions;
 
         friend class armarx::SkillProviderComponentPluginUser;
     };
@@ -145,11 +147,17 @@ namespace armarx
         executeSkillAsync(const skills::provider::dto::SkillExecutionRequest& executionInfo,
                           const Ice::Current& current = Ice::Current()) override;
 
-        void addSkillParameters(const skills::provider::dto::SkillExecutionID& executionId,
-                                const armarx::aron::data::dto::DictPtr& input,
-                                const Ice::Current& current = Ice::Current()) override;
+        skills::provider::dto::ParameterUpdateResult
+        updateSkillParameters(const skills::provider::dto::SkillExecutionID& executionId,
+                              const armarx::aron::data::dto::DictPtr& parameters,
+                              const Ice::Current& current = Ice::Current()) override;
+
+        skills::provider::dto::AbortSkillResult
+        abortSkill(const skills::provider::dto::SkillExecutionID& skill,
+                   const Ice::Current& current = Ice::Current()) override;
 
-        void abortSkill(const skills::provider::dto::SkillExecutionID& skill,
+        skills::provider::dto::AbortSkillResult
+        abortSkillAsync(const skills::provider::dto::SkillExecutionID& skill,
                         const Ice::Current& current = Ice::Current()) override;
 
         // Plugin
@@ -157,49 +165,31 @@ namespace armarx
         getSkillProviderPlugin() const;
 
     protected:
-        // -----------------------------------------------------------------------------------------
-        // LEGACY, TODO: NEEDS TESTING
-        // -----------------------------------------------------------------------------------------
-        template <class _Skill>
-
-        requires skills::isSkill<_Skill> skills::SkillFactory*
-        addSkill(std::unique_ptr<_Skill>&& s)
-        {
-            return addSkillFactory<_Skill>();
-        }
-
-        template <class _Skill, typename... Args>
-
-        requires skills::isSkill<_Skill> skills::SkillFactory*
-        addSkill(Args&&... args)
-        {
-            return addSkillFactory<_Skill>(std::forward<Args>(args)...);
-        }
-
         // -----------------------------------------------------------------------------------------
         // New
         // -----------------------------------------------------------------------------------------
-        skills::SkillFactory*
-        addSkillFactory(const skills::SkillDescription& desc, const skills::LambdaSkill::FunT& f)
+        skills::SkillBlueprint*
+        addSkillFactory(const skills::SkillDescription& desc,
+                        const skills::LambdaSkill::FunctionType& f)
         {
             auto ret = plugin->addSkillFactory(desc, f);
             return ret;
         }
 
-        template <class _Skill, typename... Args>
+        template <class SkillT, typename... Args>
 
-        requires skills::isSkill<_Skill> skills::SkillFactory*
+        requires skills::isSkill<SkillT> skills::SkillBlueprint*
         addSkillFactory(Args&&... args)
         {
-            return plugin->addSkillFactory<_Skill>(std::forward<Args>(args)...);
+            return plugin->addSkillFactory<SkillT>(std::forward<Args>(args)...);
         }
 
-        template <typename _Fac, typename... Args>
+        template <typename FacT, typename... Args>
 
-        requires skills::isSkillFactory<_Fac> _Fac*
+        requires skills::isSkillBlueprint<FacT> FacT*
         addCustomSkillFactory(Args&&... args)
         {
-            return plugin->addSkillFactory<_Fac>(std::forward<Args>(args)...);
+            return plugin->addSkillFactory<FacT>(std::forward<Args>(args)...);
         }
 
     private:
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
deleted file mode 100644
index 3a969b2819eb8ec9fd2328dfe069ede85fa480f0..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "SkillProxy.h"
-
-namespace armarx
-{
-    namespace skills
-    {
-        SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                               const SkillID& skillId) :
-            manager(manager),
-            skillDescription(SkillDescription::FromIce(
-                manager->getSkillDescription(skillId.toManagerIce()).value()))
-        {
-        }
-
-        SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                               const SkillDescription& skillDesc) :
-            manager(manager), skillDescription(skillDesc)
-        {
-            ARMARX_CHECK(skillDesc.skillId.fullySpecified());
-        }
-
-        TerminatedSkillStatusUpdate
-        SkillProxy::executeSkill(const std::string& executorName, const aron::data::DictPtr& params)
-        {
-            skills::manager::dto::SkillExecutionRequest req;
-            req.executorName = executorName;
-            req.params = params->toAronDictDTO();
-            req.skillId = skillDescription.skillId.toManagerIce();
-
-            auto terminatingUpdateIce = manager->executeSkill(req);
-            return TerminatedSkillStatusUpdate::FromIce(terminatingUpdateIce);
-        }
-
-        SkillExecutionID
-        SkillProxy::executeSkillAsync(const std::string& executorName,
-                                      const aron::data::DictPtr& params)
-        {
-            skills::manager::dto::SkillExecutionRequest req;
-            req.executorName = executorName;
-            req.params = params->toAronDictDTO();
-            req.skillId = skillDescription.skillId.toManagerIce();
-
-            auto execReqIce = manager->executeSkillAsync(req);
-            return SkillExecutionID::FromIce(execReqIce);
-        }
-
-        void
-        SkillProxy::abortSkill(const SkillExecutionID& id)
-        {
-            // TODO: This will be used in the future, do not remove it!
-            manager->abortSkill(id.toManagerIce());
-        }
-
-        aron::data::DictPtr
-        SkillProxy::getDefaultParameters(const std::string& profileName)
-        {
-            if (profileName == "root")
-            {
-                return skillDescription.rootProfileParameterization;
-            }
-            // TODO @fabianPK
-            return nullptr;
-        }
-    } // namespace skills
-} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProxy.h b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
deleted file mode 100644
index 4cb09be7920e8496313fa59d5eef8c1615ef21d0..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/skills/provider/SkillProxy.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/skills/core/Skill.h>
-
-namespace armarx
-{
-    namespace skills
-    {
-        /* Manages the remote execution of a skill and converts the ice types */
-        class SkillProxy : public armarx::Logging
-        {
-        public:
-            SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                       const SkillID& skillId);
-            SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                       const SkillDescription& skillDesc);
-
-            // Provide a similar API as the skillprovider
-            TerminatedSkillStatusUpdate executeSkill(const std::string& executorName,
-                                                const aron::data::DictPtr& params = nullptr);
-
-            SkillExecutionID executeSkillAsync(const std::string& executorName,
-                                          const aron::data::DictPtr& params = nullptr);
-
-            void abortSkill(const SkillExecutionID& executorName);
-
-            // Utiliy methods
-            aron::data::DictPtr getDefaultParameters(const std::string& profileName = "root");
-
-        private:
-            manager::dti::SkillManagerInterfacePrx manager;
-            SkillDescription skillDescription;
-        };
-    } // namespace skills
-} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
index d551bd88df7a19144dac07930233dc5293ffc089..2fded9a0a50ede4cdc3e8d76861217fbc1127c58 100644
--- a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
@@ -23,17 +23,16 @@ namespace armarx
             void
             setParameters(const AronT& d)
             {
-                std::scoped_lock l(this->parametersMutex);
-                this->parameters = d;
-
                 Base::setParameters(d.toAron());
             }
 
+            /// Overwrite getter for parameters. Shadow Skill::getParameters()
             AronT
             getParameters() const
             {
-                std::scoped_lock l(this->parametersMutex);
-                return this->parameters;
+                AronT d;
+                d.fromAron(this->parameters);
+                return d;
             }
 
             /// returns the accepted type of the skill
@@ -45,8 +44,6 @@ namespace armarx
 
 
         protected:
-            mutable std::mutex parametersMutex;
-            AronT parameters;
         };
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkillProxy.cpp b/source/RobotAPI/libraries/skills/provider/SpecializedSkillProxy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f372c5f55247795f91d956f92d84eb6ac35ee77
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkillProxy.cpp
@@ -0,0 +1,8 @@
+#include "SpecializedSkillProxy.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkillProxy.h b/source/RobotAPI/libraries/skills/provider/SpecializedSkillProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..4dd53171c4cf17c7298cf9ba59c364ddcf81eb8e
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkillProxy.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <RobotAPI/libraries/skills/core/SkillProxy.h>
+
+namespace armarx
+{
+    namespace skills
+    {
+        template <class AronT>
+        class SpecializedSkillProxy : public SkillProxy
+        {
+        public:
+            using SkillProxy::SkillProxy;
+
+            // Provide a similar API as the skillprovider
+            TerminatedSkillStatusUpdate
+            executeSkill(const std::string& executorName, const AronT& params)
+            {
+                return SkillProxy::executeSkill(executorName, params.toAron());
+            }
+
+            SkillExecutionID
+            executeSkillAsync(const std::string& executorName, const AronT& params = nullptr)
+            {
+                return SkillProxy::executeSkillAsync(executorName, params.toAron());
+            }
+
+            // Utiliy methods
+            AronT
+            getRootProfileParameters()
+            {
+                auto dict = SkillProxy::getRootProfileParameters();
+                if (dict)
+                {
+                    return AronT::FromAron(dict);
+                }
+                return {};
+            }
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
index 41679d93a07ea883f9cf199431d83c217b33a3b6..60db0fa913274594078d59c3f7a930b86e1423be 100644
--- a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
+++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
@@ -4,17 +4,18 @@ namespace armarx
 {
     namespace skills::detail
     {
-        SkillImplementationWrapper::SkillImplementationWrapper(
-            const skills::SkillFactory& fac,
+        SkillRuntime::SkillRuntime(
+            const skills::SkillBlueprint& fac,
             const skills::SkillExecutionID& execId,
-            const skills::SkillParameterization& param) :
-            factory(fac), statusUpdate(execId, param)
+            const aron::data::DictPtr& initial_parameters,
+            const skills::callback::dti::SkillProviderCallbackInterfacePrx& callbackInterface) :
+            factory(fac), statusUpdate{{execId, initial_parameters, callbackInterface}}
         {
         }
 
         // ask a skill to stop
         void
-        SkillImplementationWrapper::stopSkill()
+        SkillRuntime::stopSkill()
         {
             while (this->skill == nullptr)
             {
@@ -24,11 +25,11 @@ namespace armarx
                 std::this_thread::sleep_for(std::chrono::milliseconds(100));
             }
 
-            this->skill->notifySkillToStopASAP();
+            this->skill->notifySkillToStop();
         }
 
         void
-        SkillImplementationWrapper::addSkillParameters(const aron::data::DictPtr& i)
+        SkillRuntime::updateSkillParameters(const aron::data::DictPtr& i)
         {
             while (this->skill == nullptr)
             {
@@ -38,11 +39,11 @@ namespace armarx
                 std::this_thread::sleep_for(std::chrono::milliseconds(100));
             }
 
-            this->skill->addParameters(i);
+            this->skill->updateParameters(i);
         }
 
         TerminatedSkillStatusUpdate
-        SkillImplementationWrapper::executeSkill()
+        SkillRuntime::executeSkill()
         {
             std::scoped_lock l(this->executionMutex);
             // -------------------------------------------------------------------------------------
@@ -56,14 +57,16 @@ namespace armarx
             // setup basic vars and lambdas
             // -------------------------------------------------------------------------------------
             // actually we should lock... however this is only read access and the members are const throughout the execution...
-            ARMARX_CHECK(statusUpdate.executionId.skillId.fullySpecified());
+            ARMARX_CHECK(statusUpdate.executionId.skillId.isFullySpecified());
 
-            const auto& initial_aron_params = statusUpdate.usedParameterization.parameterization;
-            const auto& callback_interface = statusUpdate.usedParameterization.callbackInterface;
+            const auto& initial_aron_params = statusUpdate.parameters;
+            const auto& callback_interface = statusUpdate.callbackInterface;
             const auto& skillId = statusUpdate.executionId.skillId;
             const auto& skillName = skillId.skillName;
             const auto& providerId = *skillId.providerId;
             const auto& executorName = statusUpdate.executionId.executorName;
+            const auto& manager =
+                skills::manager::dti::SkillManagerInterfacePrx::checkedCast(callback_interface);
 
             ARMARX_INFO_S << "Executing skill: " << skillName;
 
@@ -72,11 +75,11 @@ namespace armarx
             {
                 std::unique_lock l(skillStatusesMutex);
                 statusUpdate.status = status;
-                statusUpdate.data = data;
+                statusUpdate.result = data;
                 if (skill) // if skill has been constructed
                 {
                     // update parameterization
-                    statusUpdate.usedParameterization.parameterization = skill->getParameters();
+                    statusUpdate.parameters = skill->getParameters();
                 }
 
                 if (callback_interface) // if callback interface is used
@@ -114,27 +117,41 @@ namespace armarx
             // -------------------------------------------------------------------------------------
             // construct skill
             // -------------------------------------------------------------------------------------
+            ARMARX_INFO_S << "Construct skill: " << skillName;
+
             updateStatus(SkillStatus::Constructing);
             this->skill = this->factory.createSkill(providerId);
-            this->skill->executorName = (executorName);
-            this->skill->manager = skills::manager::dti::SkillManagerInterfacePrx::checkedCast(
-                callback_interface); // ugly. Get managerPrx from manager!
-            ;
-            this->skill->callback = [&](const SkillStatus s, const armarx::aron::data::DictPtr& d)
-            { updateStatus(s, d); };
+            this->skill->setExecutorName(executorName);
+            this->skill->setManager(manager);
+            this->skill->setCallback([&](const SkillStatus s, const armarx::aron::data::DictPtr& d)
+                                     { updateStatus(s, d); });
 
             // set initial parameters that were attached to the execution request (only add as we are not sure whether some updates already arrived)
-            skill->addParameters(initial_aron_params);
+            this->updateSkillParameters(initial_aron_params);
+
+            auto makeAbortedResult = [&](const std::string& message)
+            {
+                updateStatus(SkillStatus::Aborted, createErrorMessageData(message));
+
+                std::unique_lock l(skillStatusesMutex);
+                auto terminated = TerminatedSkillStatusUpdate{
+                    {.executionId = statusUpdate.executionId,
+                     .parameters = statusUpdate.parameters,
+                     .callbackInterface = statusUpdate.callbackInterface}};
+                terminated.status = TerminatedSkillStatus::Aborted;
+                return terminated;
+            };
 
 
-            auto makeTerminationResult = [&](const std::string& message)
+            auto makeFailedResult = [&](const std::string& message)
             {
                 updateStatus(SkillStatus::Failed, createErrorMessageData(message));
 
                 std::unique_lock l(skillStatusesMutex);
-                auto terminated = TerminatedSkillStatusUpdate(statusUpdate.executionId,
-                                                              statusUpdate.usedParameterization);
-                terminated.data = statusUpdate.data;
+                auto terminated = TerminatedSkillStatusUpdate{
+                    {.executionId = statusUpdate.executionId,
+                     .parameters = statusUpdate.parameters,
+                     .callbackInterface = statusUpdate.callbackInterface}};
                 terminated.status = TerminatedSkillStatus::Failed;
                 return terminated;
             };
@@ -154,42 +171,60 @@ namespace armarx
             //            }
 
 
-            auto exitAndMakeTerminationResult = [&](const std::string& message)
+            auto exitAndMakeFailedResult = [&](const std::string& message)
+            {
+                skill->exitSkill(); // try to exit skill. Ignore return value
+                return makeFailedResult(message);
+            };
+            auto exitAndMakeAbortedResult = [&](const std::string& message)
             {
                 skill->exitSkill(); // try to exit skill. Ignore return value
-                return makeTerminationResult(message);
+                return makeAbortedResult(message);
             };
 
+            // Construction succeeded!
             // -------------------------------------------------------------------------------------
             // Init skill
             // -------------------------------------------------------------------------------------
+            ARMARX_INFO_S << "Init skill: " << skillName;
+            updateStatus(SkillStatus::Initializing);
+
             try
             {
-                updateStatus(SkillStatus::Initializing);
                 Skill::InitResult initRet = skill->initSkill();
                 if (initRet.status != TerminatedSkillStatus::Succeeded)
                 {
                     std::string message = "SkillError 101: The initialization of skill '" +
                                           skillName + "' did not succeed.";
-                    return exitAndMakeTerminationResult(message);
+                    return exitAndMakeFailedResult(message);
                 }
             }
-
+            catch (const error::SkillAbortedException& ex)
+            {
+                return exitAndMakeAbortedResult(GetHandledExceptionString());
+            }
+            catch (const error::SkillFailedException& ex)
+            {
+                return exitAndMakeFailedResult(GetHandledExceptionString());
+            }
             catch (const std::exception& ex)
             {
                 std::string message =
                     "SkillError 101e: An error occured during the initialization of skill '" +
                     skillName + "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-                return exitAndMakeTerminationResult(message);
+                return exitAndMakeFailedResult(message);
             }
 
+            // Init succeeded!
             // -------------------------------------------------------------------------------------
             // Prepare skill
             // -------------------------------------------------------------------------------------
+            ARMARX_INFO_S << "Prepare skill: " << skillName;
+            updateStatus(SkillStatus::Preparing);
+
             try
             {
-                updateStatus(SkillStatus::Preparing);
                 auto prepareRet = skill->prepareSkill();
                 while (prepareRet.status == ActiveOrTerminatedSkillStatus::Running)
                 {
@@ -197,18 +232,25 @@ namespace armarx
                                 << skillName << " fulfilled. Waiting...";
 
                     // wait...
-                    prepareRet = skill->prepareSkill();
                     std::this_thread::sleep_for(std::chrono::milliseconds(50));
+                    prepareRet = skill->prepareSkill();
                 }
 
                 if (prepareRet.status != ActiveOrTerminatedSkillStatus::Succeeded)
                 {
                     std::string message = "SkillError 201: The prepare method of skill '" +
                                           skillName + "' did not succeed.";
-                    return exitAndMakeTerminationResult(message);
+                    return exitAndMakeFailedResult(message);
                 }
             }
-
+            catch (const error::SkillAbortedException& ex)
+            {
+                return exitAndMakeAbortedResult(GetHandledExceptionString());
+            }
+            catch (const error::SkillFailedException& ex)
+            {
+                return exitAndMakeFailedResult(GetHandledExceptionString());
+            }
             catch (const std::exception& ex)
             {
                 std::string message = "SkillError 201e: An error occured during waiting for skill "
@@ -216,15 +258,17 @@ namespace armarx
                                       skillName +
                                       "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-                return exitAndMakeTerminationResult(message);
+                return exitAndMakeFailedResult(message);
             }
 
+            // Prepare succeeded!
+            // -------------------------------------------------------------------------------------
+            // Main of skill
+            // -------------------------------------------------------------------------------------
             // execute. If the skill fails for some reason, from this point it will always execute its exit function.
+            ARMARX_INFO_S << "Main skill: " << skillName;
             updateStatus(SkillStatus::Running);
 
-            // Init succeeded!
-
-
             Skill::MainResult mainRet;
             try
             {
@@ -233,21 +277,31 @@ namespace armarx
                 {
                     std::string message = "SkillError 501: The main method of skill '" + skillName +
                                           "' did not succeed.";
-                    return exitAndMakeTerminationResult(message);
+                    return exitAndMakeFailedResult(message);
                 }
             }
-
+            catch (const error::SkillAbortedException& ex)
+            {
+                return exitAndMakeAbortedResult(GetHandledExceptionString());
+            }
+            catch (const error::SkillFailedException& ex)
+            {
+                return exitAndMakeFailedResult(GetHandledExceptionString());
+            }
             catch (const std::exception& ex)
             {
                 std::string message =
                     "SkillError 501e: An error occured during the main method of skill '" +
                     skillName + "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-                return exitAndMakeTerminationResult(message);
+                return exitAndMakeFailedResult(message);
             }
 
             // Main succeeded!
-
+            // -------------------------------------------------------------------------------------
+            // Exit of skill
+            // -------------------------------------------------------------------------------------
+            ARMARX_INFO_S << "Exit skill: " << skillName;
             try
             {
                 Skill::ExitResult exitRet = skill->exitSkill();
@@ -255,31 +309,38 @@ namespace armarx
                 {
                     std::string message = "SkillError 601: The exit method of skill '" + skillName +
                                           "' did not succeed.";
-                    return makeTerminationResult(message);
+                    return makeFailedResult(message);
                 }
             }
-
+            catch (const error::SkillAbortedException& ex)
+            {
+                return makeAbortedResult(GetHandledExceptionString());
+            }
+            catch (const error::SkillFailedException& ex)
+            {
+                return makeFailedResult(GetHandledExceptionString());
+            }
             catch (const std::exception& ex)
             {
                 std::string message =
                     "SkillError 601e: An error occured during the exit method of skill '" +
                     skillName + "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-                return makeTerminationResult(message);
+                return makeFailedResult(message);
             }
 
             // Exit succeeded!
-
-
             // All succeeded!
             {
                 updateStatus(SkillStatus::Succeeded);
 
                 // return result of main method
                 std::unique_lock l(skillStatusesMutex);
-                TerminatedSkillStatusUpdate ret(statusUpdate.executionId,
-                                                statusUpdate.usedParameterization);
-                ret.data = mainRet.data;
+                TerminatedSkillStatusUpdate ret{
+                    {.executionId = statusUpdate.executionId,
+                     .parameters = statusUpdate.parameters,
+                     .callbackInterface = statusUpdate.callbackInterface}};
+                ret.result = mainRet.data;
                 ret.status = TerminatedSkillStatus::Succeeded;
                 return ret;
             }
diff --git a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
index 45108724d3ce8ec2bf1e9e1559ebb9be5142fdb6..e5a5b1f82c3db4e5939fd4c880a738373967402b 100644
--- a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
+++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
@@ -15,10 +15,10 @@ namespace armarx
     {
         namespace detail
         {
-            class SkillImplementationWrapper
+            class SkillRuntime
             {
             private:
-                const skills::SkillFactory& factory;
+                const skills::SkillBlueprint factory;
 
                 std::unique_ptr<Skill> skill;
                 mutable std::mutex executionMutex;
@@ -29,10 +29,14 @@ namespace armarx
                 mutable std::mutex skillStatusesMutex;
                 SkillStatusUpdate statusUpdate;
 
+                // Set exteranally to store the execution somewhere
+                std::thread execution;
+
                 // ctor
-                SkillImplementationWrapper(const skills::SkillFactory& fac,
-                                           const skills::SkillExecutionID&,
-                                           const skills::SkillParameterization&);
+                SkillRuntime(const skills::SkillBlueprint& fac,
+                             const skills::SkillExecutionID&,
+                             const aron::data::DictPtr&,
+                             const skills::callback::dti::SkillProviderCallbackInterfacePrx&);
 
                 // execute a skill. The parameterization is copied. T
                 // the return type additionally contains the input configuration (similar to the status updates used in callbacks)
@@ -42,7 +46,7 @@ namespace armarx
                 void stopSkill();
 
                 // add parameters to a skill. Must be concurrent to execute skill
-                void addSkillParameters(const aron::data::DictPtr& i);
+                void updateSkillParameters(const aron::data::DictPtr& i);
             };
         } // namespace detail
     } // namespace skills
diff --git a/source/RobotAPI/statecharts/ObjectMemoryGroup/RequestObjects.cpp b/source/RobotAPI/statecharts/ObjectMemoryGroup/RequestObjects.cpp
index 562ddabd56b6d07428f8ce2b386fa682ac95dd1f..56dc86697810e10870f6b409b3f6f810ee9b0729 100644
--- a/source/RobotAPI/statecharts/ObjectMemoryGroup/RequestObjects.cpp
+++ b/source/RobotAPI/statecharts/ObjectMemoryGroup/RequestObjects.cpp
@@ -3,30 +3,34 @@
 //#include <ArmarXCore/core/time/TimeUtil.h>
 //#include <ArmarXCore/observers/variant/DatafieldRef.h>
 
-#include <RobotAPI/libraries/armem_objects/client/instance/ObjectReader.h>
 #include <RobotAPI/libraries/ArmarXObjects/ObjectID.h>
 #include <RobotAPI/libraries/ArmarXObjects/ice_conversions.h>
+#include <RobotAPI/libraries/armem_objects/client/instance/ObjectReader.h>
 
 #include "ObjectMemoryGroupStatechartContext.generated.h"
 
 namespace armarx::ObjectMemoryGroup
 {
     // DO NOT EDIT NEXT LINE
-    RequestObjects::SubClassRegistry RequestObjects::Registry(RequestObjects::GetName(), &RequestObjects::CreateInstance);
+    RequestObjects::SubClassRegistry RequestObjects::Registry(RequestObjects::GetName(),
+                                                              &RequestObjects::CreateInstance);
 
-    RequestObjects::RequestObjects(const XMLStateConstructorParams& stateData):
-        XMLStateTemplate<RequestObjects>(stateData), RequestObjectsGeneratedBase<RequestObjects>(stateData)
+    RequestObjects::RequestObjects(const XMLStateConstructorParams& stateData) :
+        XMLStateTemplate<RequestObjects>(stateData),
+        RequestObjectsGeneratedBase<RequestObjects>(stateData)
     {
     }
 
-    void RequestObjects::onEnter()
+    void
+    RequestObjects::onEnter()
     {
 
         // put your user code for the enter-point here
         // execution time should be short (<100ms)
     }
 
-    void RequestObjects::run()
+    void
+    RequestObjects::run()
     {
         if (not in.getEnable())
         {
@@ -39,7 +43,8 @@ namespace armarx::ObjectMemoryGroup
         const std::string provider = in.isProviderSet() ? in.getProvider() : "";
 
         const std::vector<std::string> objectIdsString = in.getObjectIds();
-        const armarx::Duration relativeTimeout = armarx::Duration::MilliSeconds(in.getRelativeTimeoutMilliseconds());
+        const armarx::Duration relativeTimeout =
+            armarx::Duration::MilliSeconds(in.getRelativeTimeoutMilliseconds());
 
         std::stringstream info;
         std::stringstream warn;
@@ -49,21 +54,22 @@ namespace armarx::ObjectMemoryGroup
         {
             try
             {
-                 armarx::ObjectID id = armarx::ObjectID::FromString(idString);
-                 objectIds.push_back(id);
-                 info << "Requesting object " << id << "\n";
+                armarx::ObjectID id = armarx::ObjectID::FromString(idString);
+                objectIds.push_back(id);
+                info << "Requesting object " << id << "\n";
             }
             catch (const armarx::LocalException& e)
             {
-                warn << "\nGiven object ID '" << idString << "' could not parsed as ObjectID: " << e.what();
+                warn << "\nGiven object ID '" << idString
+                     << "' could not parsed as ObjectID: " << e.what();
             }
         }
 
         auto context = getContext<ObjectMemoryGroupStatechartContext>();
         armarx::armem::client::MemoryNameSystem mns(getMemoryNameSystem(), context);
 
-        Reader reader{mns};
-        reader.connect();
+        Reader reader;
+        reader.connect(mns);
         objpose::ObjectPoseStorageInterfacePrx storage = reader.getObjectPoseStorage();
 
         armarx::objpose::observer::RequestObjectsInput input;
@@ -91,7 +97,8 @@ namespace armarx::ObjectMemoryGroup
         {
             if (result.result.success)
             {
-                info << "Requested object " << id << " via provider '" << result.providerName << "'.\n";
+                info << "Requested object " << id << " via provider '" << result.providerName
+                     << "'.\n";
             }
             else
             {
@@ -105,8 +112,9 @@ namespace armarx::ObjectMemoryGroup
         }
         if (not warn.str().empty())
         {
-            ARMARX_WARNING << "The following issues occurred whhen requesting objects for localization:"
-                           << warn.str();
+            ARMARX_WARNING
+                << "The following issues occurred whhen requesting objects for localization:"
+                << warn.str();
         }
 
         emitSuccess();
@@ -118,16 +126,17 @@ namespace armarx::ObjectMemoryGroup
     //    // execution time should be short (<100ms)
     //}
 
-    void RequestObjects::onExit()
+    void
+    RequestObjects::onExit()
     {
         // put your user code for the exit point here
         // execution time should be short (<100ms)
     }
 
-
     // DO NOT EDIT NEXT FUNCTION
-    XMLStateFactoryBasePtr RequestObjects::CreateInstance(XMLStateConstructorParams stateData)
+    XMLStateFactoryBasePtr
+    RequestObjects::CreateInstance(XMLStateConstructorParams stateData)
     {
         return XMLStateFactoryBasePtr(new RequestObjects(stateData));
     }
-}
+} // namespace armarx::ObjectMemoryGroup