From 847fe14ba8862cc30c95ca610cc5a90b3e853e83 Mon Sep 17 00:00:00 2001
From: Fabian Peller <fabian.peller-konrad@kit.edu>
Date: Wed, 4 Oct 2023 16:45:39 +0200
Subject: [PATCH] finished implementation of updated skill api. Works with
 example skill provider. Needs testing of specialized skills and refactoring
 of remaining skills.

---
 .../server/SkillsMemory/SkillsMemory.cpp      |  28 +-
 .../armem/server/SkillsMemory/SkillsMemory.h  |   4 +-
 .../SkillProviderExample.cpp                  |  79 +++-
 .../SkillProviderExample.h                    |  14 +
 .../SkillManagerPlugin/CMakeLists.txt         |   1 +
 .../SkillManagerMonitorWidget.ui              |  58 ++-
 .../SkillManagerMonitorWidgetController.cpp   | 409 ++++++++++--------
 .../SkillManagerMonitorWidgetController.h     |  65 ++-
 .../skills/SkillManagerInterface.ice          |  68 ++-
 .../interface/skills/SkillMemoryInterface.ice |   2 +-
 .../skills/SkillProviderInterface.ice         | 130 +++---
 .../libraries/armem_skills/aron/Skill.xml     |  62 ++-
 .../armem_skills/aron_conversions.cpp         | 191 +++++++-
 .../libraries/armem_skills/aron_conversions.h |  41 +-
 .../segment/ExecutableSkillLibrarySegment.cpp |  28 +-
 .../segment/ExecutableSkillLibrarySegment.h   |  13 +-
 .../server/segment/SkillEventSegment.cpp      |  69 +--
 .../server/segment/SkillEventSegment.h        |   6 +-
 .../segment/SkillExecutionRequestSegment.cpp  |  46 +-
 .../segment/SkillExecutionRequestSegment.h    |  14 +-
 .../aron/core/data/variant/container/Dict.cpp |  53 +--
 .../aron/core/data/variant/container/List.cpp |  33 +-
 .../libraries/skills/core/ProviderID.cpp      |  12 +-
 .../libraries/skills/core/ProviderID.h        |   8 +-
 .../libraries/skills/core/ProviderInfo.cpp    |  21 +-
 .../libraries/skills/core/ProviderInfo.h      |   4 +-
 .../RobotAPI/libraries/skills/core/Skill.cpp  |  78 ++--
 source/RobotAPI/libraries/skills/core/Skill.h |  48 +-
 .../skills/core/SkillDescription.cpp          |  33 +-
 .../libraries/skills/core/SkillDescription.h  |  12 +-
 .../skills/core/SkillExecutionID.cpp          |  19 +-
 .../libraries/skills/core/SkillExecutionID.h  |  16 +-
 .../skills/core/SkillExecutionRequest.cpp     |   9 +-
 .../skills/core/SkillExecutionRequest.h       |  12 +-
 .../libraries/skills/core/SkillID.cpp         |  34 +-
 .../RobotAPI/libraries/skills/core/SkillID.h  |  31 +-
 .../skills/core/SkillStatusUpdate.cpp         | 225 ++++++----
 .../libraries/skills/core/SkillStatusUpdate.h |  68 ++-
 .../manager/SkillManagerComponentPlugin.cpp   | 270 ++++++++----
 .../manager/SkillManagerComponentPlugin.h     |  37 +-
 .../skills/provider/PeriodicSkill.cpp         |   2 +-
 .../libraries/skills/provider/PeriodicSkill.h |   4 +-
 .../provider/PeriodicSpecializedSkill.h       |  11 +-
 .../libraries/skills/provider/SkillContext.h  |  17 +-
 .../libraries/skills/provider/SkillFactory.h  |  66 +--
 .../provider/SkillProviderComponentPlugin.cpp | 175 ++++----
 .../provider/SkillProviderComponentPlugin.h   |  65 ++-
 .../libraries/skills/provider/SkillProxy.cpp  |  63 +--
 .../libraries/skills/provider/SkillProxy.h    |  33 +-
 .../skills/provider/SpecializedSkill.h        |  28 +-
 .../detail/SkillImplementationWrapper.cpp     |  54 ++-
 .../detail/SkillImplementationWrapper.h       |   2 +-
 52 files changed, 1780 insertions(+), 1091 deletions(-)

diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
index 00f5da832..02cbe58ce 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
@@ -114,9 +114,9 @@ namespace armarx
                 {
                     ARMARX_CHECK_NOT_NULL(instance);
 
-                    skills::manager::dto::SkillExecutionRequest exInfo =
+                    skills::SkillExecutionRequest exInfo =
                         skillExecutionRequestCoreSegment.convertCommit(instance);
-                    SkillManagerComponentPluginUser::executeSkill(exInfo, current);
+                    SkillManagerComponentPluginUser::executeSkill(exInfo.toManagerIce(), current);
                 }
             }
         }
@@ -128,10 +128,12 @@ namespace armarx
     SkillsMemory::addProvider(const skills::manager::dto::ProviderInfo& info,
                               const Ice::Current& current)
     {
+        ARMARX_INFO << "Adding provider to skill memory: " << info.providerId.providerName;
         SkillManagerComponentPluginUser::addProvider(info, current);
 
         // log skills to memory
-        executableSkillCoreSegment.addSkillProvider(info);
+        auto p = skills::ProviderInfo::FromIce(info);
+        executableSkillCoreSegment.addSkillProvider(p);
     }
 
     void
@@ -148,22 +150,32 @@ namespace armarx
     SkillsMemory::executeSkill(const skills::manager::dto::SkillExecutionRequest& info,
                                const Ice::Current& current)
     {
-        skillExecutionRequestCoreSegment.addSkillExecutionRequest(info);
+        auto e = skills::SkillExecutionRequest::FromIce(info);
+        skillExecutionRequestCoreSegment.addSkillExecutionRequest(e);
+
         return SkillManagerComponentPluginUser::executeSkill(info, current);
     }
 
     void
     SkillsMemory::updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
-                                       const skills::provider::dto::ProviderID& providerId,
+                                       const skills::callback::dto::ProviderID& providerId,
                                        const Ice::Current& current)
     {
-        skillEventCoreSegment.addSkillUpdateEvent(update, providerId.providerName);
+        auto p = skills::ProviderID::FromIce(providerId);
+        auto u = skills::SkillStatusUpdate::FromIce(update, p);
+        skillEventCoreSegment.addSkillUpdateEvent(u);
     }
 
-    skills::provider::dto::SkillStatusUpdateMap
+    skills::manager::dto::SkillStatusUpdateMap
     SkillsMemory::getLatestSkillExecutionStatuses(int n, const Ice::Current& current)
     {
-        return {}; // TODO
+        auto m = skillEventCoreSegment.getLatestSkillEvents(n);
+        skills::manager::dto::SkillStatusUpdateMap ret;
+        for (const auto& [k, v] : m)
+        {
+            ret[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 da7e3df47..81109b0bd 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
@@ -86,10 +86,10 @@ namespace armarx
                      const Ice::Current& current) override;
 
         void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
-                                  const skills::provider::dto::ProviderID& id,
+                                  const skills::callback::dto::ProviderID& id,
                                   const Ice::Current& current) override;
 
-        skills::provider::dto::SkillStatusUpdateMap
+        skills::manager::dto::SkillStatusUpdateMap
         getLatestSkillExecutionStatuses(int n, const Ice::Current& current) override;
 
         // WritingInterface interface
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
index 401335868..2fbc92142 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
@@ -39,10 +39,60 @@ namespace armarx::skills::provider
                                 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())
     {
     }
@@ -68,11 +118,12 @@ namespace armarx::skills::provider
         exec2.some_text = "Hello from the ChainingSkill 2";
         exec3.some_text = "Hello from the ChainingSkill 3";
 
-        SkillProxy skillExecPrx(manager, {"SkillProviderExample", "HelloWorld"});
+        SkillProxy skillExecPrx(
+            manager, skills::SkillID(skills::ProviderID("SkillProviderExample"), "HelloWorld"));
 
-        skillExecPrx.executeFullSkill(getSkillId().toString(), exec1.toAron());
-        skillExecPrx.executeFullSkill(getSkillId().toString(), exec2.toAron());
-        skillExecPrx.executeFullSkill(getSkillId().toString(), exec3.toAron());
+        skillExecPrx.executeSkill(getSkillId().toString(), exec1.toAron());
+        skillExecPrx.executeSkill(getSkillId().toString(), exec2.toAron());
+        skillExecPrx.executeSkill(getSkillId().toString(), exec3.toAron());
 
         return {TerminatedSkillStatus::Succeeded, nullptr};
     }
@@ -88,7 +139,7 @@ namespace armarx::skills::provider
         return SkillDescription{{"Timeout"},
                                 "This fails with timeout reached",
                                 {},
-                                armarx::core::time::Duration::MilliSeconds(1000),
+                                armarx::core::time::Duration::MilliSeconds(5000),
                                 nullptr};
     }
 
@@ -96,7 +147,7 @@ namespace armarx::skills::provider
     TimeoutSkill::step()
     {
         // do heavy work
-        std::this_thread::sleep_for(std::chrono::milliseconds(200));
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
 
         return {ActiveOrTerminatedSkillStatus::Running, nullptr};
     }
@@ -157,7 +208,8 @@ namespace armarx::skills::provider
     SkillProviderExample::onInitComponent()
     {
         // Add example skill
-        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<HelloWorldSkill>());
+        ARMARX_INFO << "Adding skill HelloWorldSkill";
+        addSkillFactory<HelloWorldSkill>();
 
         // Add another lambda example skill
         {
@@ -175,13 +227,20 @@ namespace armarx::skills::provider
         }
 
         // Add another example skill
-        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<CallbackSkill>());
+        ARMARX_INFO << "Adding skill CallbackSkill";
+        addSkillFactory<CallbackSkill>();
 
         // Add timeout skill
-        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<TimeoutSkill>());
+        ARMARX_INFO << "Adding skill TimeoutSkill";
+        addSkillFactory<TimeoutSkill>();
 
         // chaining
-        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<ChainingSkill>());
+        ARMARX_INFO << "Adding skill ChainingSkill";
+        addSkillFactory<ChainingSkill>();
+
+        // incomplete and prepare
+        ARMARX_INFO << "Adding skill IncompleteSkill";
+        addSkillFactory<IncompleteSkill>();
     }
 
     void
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
index ea8f114eb..190dc56a2 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
@@ -44,6 +44,20 @@ namespace armarx::skills::provider
         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:
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt
index b40d5a2fc..a6d2ff63c 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt
@@ -63,6 +63,7 @@ set(COMPONENT_LIBS
     RobotAPIInterfaces
     aron
     RobotAPISkills
+    SkillsMemory
     aronjsonconverter
     SimpleConfigDialog
 )
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
index 34d82d1fc..b96d3850e 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
@@ -79,32 +79,42 @@
         <widget class="QTreeWidget" name="treeWidgetSkillExecutions">
          <column>
           <property name="text">
-           <string>ID</string>
+           <string>ExecutionID</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Skill</string>
+           <string>Executor</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Scheduled</string>
+           <string>SkillID</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Running</string>
+           <string>IsConstructing</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Finished</string>
+           <string>IsInitializing</string>
           </property>
          </column>
          <column>
           <property name="text">
-           <string>Executor</string>
+           <string>IsPreparing</string>
+          </property>
+         </column>
+         <column>
+          <property name="text">
+           <string>IsRunning</string>
+          </property>
+         </column>
+         <column>
+          <property name="text">
+           <string>Finished</string>
           </property>
          </column>
         </widget>
@@ -132,7 +142,7 @@
         <string>Manager</string>
        </property>
        <layout class="QGridLayout" name="gridLayout">
-        <item row="4" column="0" colspan="3">
+        <item row="5" column="0" colspan="3">
          <widget class="QTreeWidget" name="treeWidgetSkills">
           <column>
            <property name="text">
@@ -141,11 +151,30 @@
           </column>
           <column>
            <property name="text">
-            <string>HasType</string>
+            <string>HasInputType</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>HasOutputType</string>
            </property>
           </column>
          </widget>
         </item>
+        <item row="4" column="1">
+         <widget class="QPushButton" name="pushButtonSearch">
+          <property name="text">
+           <string>Search</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="0">
+         <widget class="QLineEdit" name="lineEditSearch">
+          <property name="text">
+           <string>Search...</string>
+          </property>
+         </widget>
+        </item>
        </layout>
       </widget>
       <widget class="QGroupBox" name="groupBoxSkillDetails">
@@ -176,17 +205,10 @@
           </property>
          </widget>
         </item>
-        <item row="8" column="0">
-         <widget class="QPushButton" name="pushButtonStopSkill">
-          <property name="text">
-           <string>Stop current skill</string>
-          </property>
-         </widget>
-        </item>
         <item row="0" column="3">
          <widget class="QPushButton" name="pushButtonReset">
           <property name="text">
-           <string>Reset args</string>
+           <string>Reset args to profile</string>
           </property>
          </widget>
         </item>
@@ -215,7 +237,7 @@
           </column>
           <column>
            <property name="text">
-            <string>defaultValue</string>
+            <string>defaultValue (hidden in GUI)</string>
            </property>
           </column>
          </widget>
@@ -231,7 +253,7 @@
          <widget class="QComboBox" name="comboBoxProfiles">
           <item>
            <property name="text">
-            <string>&lt;No Profile&gt;</string>
+            <string>&lt;No Profile selected. Using root&gt;</string>
            </property>
           </item>
          </widget>
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
index 127db31f0..f48165ab9 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
@@ -38,6 +38,7 @@
 #include <QDoubleSpinBox>
 
 #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
+#include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
 
 #include "aronTreeWidget/Data.h"
 
@@ -50,8 +51,8 @@ namespace armarx
         if (!dialog)
         {
             dialog = new SimpleConfigDialog(parent);
-            dialog->addProxyFinder<skills::manager::dti::SkillManagerInterfacePrx>(
-                "SkillManager", "", "Skill*");
+            dialog->addProxyFinder<skills::dti::SkillMemoryInterfacePrx>(
+                "SkillMemory", "", "SkillMem*");
         }
         return qobject_cast<SimpleConfigDialog*>(dialog);
     }
@@ -59,25 +60,47 @@ namespace armarx
     void
     SkillManagerMonitorWidgetController::configured()
     {
-        observerName = dialog->getProxyName("SkillManager");
+        observerName = dialog->getProxyName("SkillMemory");
     }
 
     void
     SkillManagerMonitorWidgetController::loadSettings(QSettings* settings)
     {
-        observerName = settings->value("SkillManager", "SkillManager").toString().toStdString();
+        observerName = settings->value("SkillMemory", "SkillMemory").toString().toStdString();
     }
 
     void
     SkillManagerMonitorWidgetController::saveSettings(QSettings* settings)
     {
-        settings->setValue("SkillManager", QString::fromStdString(observerName));
+        settings->setValue("SkillMemory", QString::fromStdString(observerName));
     }
 } // namespace armarx
 
 // Others
 namespace armarx
 {
+    SkillExecutionInfoTreeWidgetItem*
+    SkillExecutionInfoTreeWidgetItem::SearchRecursiveForMatch(
+        SkillExecutionInfoTreeWidgetItem* haystack,
+        const skills::SkillExecutionID& needle)
+    {
+        if (!haystack)
+        {
+            return nullptr;
+        }
+
+        if (needle == haystack->executionId)
+        {
+            return haystack;
+        }
+        for (int i = 0; i < haystack->childCount(); ++i)
+        {
+            auto el = static_cast<SkillExecutionInfoTreeWidgetItem*>(haystack->child(i));
+            return SkillExecutionInfoTreeWidgetItem::SearchRecursiveForMatch(el, needle);
+        }
+        return nullptr;
+    }
+
     SkillManagerMonitorWidgetController::SkillManagerMonitorWidgetController()
     {
         widget.setupUi(getWidget());
@@ -115,10 +138,10 @@ namespace armarx
                 &QPushButton::clicked,
                 this,
                 &SkillManagerMonitorWidgetController::executeSkill);
-        connect(widget.pushButtonStopSkill,
-                &QPushButton::clicked,
-                this,
-                &SkillManagerMonitorWidgetController::stopSkill);
+        //        connect(widget.pushButtonStopSkill,
+        //                &QPushButton::clicked,
+        //                this,
+        //                &SkillManagerMonitorWidgetController::stopSkill);
 
         connect(widget.treeWidgetSkills,
                 &QTreeWidget::currentItemChanged,
@@ -149,7 +172,7 @@ namespace armarx
             QAbstractItemView::EditTrigger::NoEditTriggers);
         widget.treeWidgetSkillDetails->setColumnHidden(3, true);
 
-        getProxy(manager, observerName, 1000);
+        getProxy(memory, observerName, 1000);
         connected = true;
     }
 
@@ -157,15 +180,15 @@ namespace armarx
     SkillManagerMonitorWidgetController::onDisconnectComponent()
     {
         connected = false;
-        manager = nullptr;
+        memory = nullptr;
 
         // reset all
         skills.clear();
         widget.treeWidgetSkills->clear();
         widget.treeWidgetSkillDetails->clear();
         skillsArgumentsTreeWidgetItem = nullptr;
-        selectedSkill.providerName = "";
-        selectedSkill.skillName = "";
+        selectedSkill.skillId.providerId->providerName = skills::SkillID::UNKNOWN;
+        selectedSkill.skillId.skillName = skills::SkillID::UNKNOWN;
     }
 
     void
@@ -188,7 +211,7 @@ namespace armarx
     void
     SkillManagerMonitorWidgetController::refreshSkills()
     {
-        if (!manager)
+        if (!memory)
         {
             // check if null
             return;
@@ -200,66 +223,104 @@ namespace armarx
         {
             std::scoped_lock l(updateMutex);
 
-            auto managerSkills = manager->getSkillDescriptions();
+            auto managerSkills = memory->getSkillDescriptions();
 
-            std::vector<armarx::skills::manager::dto::SkillID> removedSkills;
-            for (auto it = skills.begin(); it != skills.end();)
+            // completely recreate internal skills map
+            skills.clear();
+            for (const auto& [sid, desc] : managerSkills)
             {
-                auto pid = it->first;
-                if (managerSkills.find(pid) == managerSkills.end())
-                {
-                    ARMARX_DEBUG << "REMOVE " << pid;
-                    removedSkills.push_back(pid);
-                    it = skills.erase(it);
-                }
-                else
-                {
-                    it++;
-                }
-            }
+                auto description = skills::SkillDescription::FromIce(desc);
+                auto skillId = skills::SkillID::FromIce(sid);
+                auto providerId = skills::ProviderID(skillId);
 
-            // add new ones
-            std::vector<armarx::skills::manager::dto::SkillID> newSkills;
-            for (const auto& [skillID, providerSkills] : managerSkills)
-            {
-                if (skills.find(skillID) == skills.end())
-                {
-                    skills.insert(std::make_pair(skillID, providerSkills));
-                    newSkills.push_back(skillID);
-                }
+                ARMARX_CHECK(skillId.fullySpecified());
+
+                auto& providedSkillsMap = skills[providerId]; // create new if not existent
+                providedSkillsMap.insert({skillId, description});
             }
 
-            /* UPDATE TREE VIEW */
-            // remove providers from tree
+            // update tree view. Remove non-existing elements
             int i = 0;
             while (i < widget.treeWidgetSkills->topLevelItemCount())
             {
-                QTreeWidgetItem* item = widget.treeWidgetSkills->topLevelItem(i);
-                if (auto it = std::find(
-                        removedSkills.begin(), removedSkills.end(), item->text(0).toStdString());
-                    it != removedSkills.end())
+                auto* providerItem = widget.treeWidgetSkills->topLevelItem(i);
+                auto providerName = providerItem->text(0).toStdString();
+                skills::ProviderID providerId(providerName);
+
+                if (skills.find(providerId) == skills.end())
                 {
-                    delete widget.treeWidgetSkills->takeTopLevelItem(i);
+                    providerItem = nullptr; // reset
+                    auto remove = widget.treeWidgetSkills->takeTopLevelItem(i);
+                    delete remove;
+                    continue;
                 }
-                else
+
+                ++i;
+                auto& providedSkills = skills.at(providerId);
+
+                int j = 0;
+                while (j < providerItem->childCount())
                 {
-                    ++i;
+                    auto* skillItem = providerItem->child(j);
+                    auto skillName = skillItem->text(0).toStdString();
+
+                    skills::SkillID skillId(providerName, skillName);
+
+                    if (providedSkills.find(skillId) == providedSkills.end())
+                    {
+                        skillItem = nullptr;
+                        auto remove = providerItem->takeChild(j);
+                        delete remove;
+                        continue;
+                    }
+
+                    ++j;
                 }
             }
 
-            // add new providers
-            for (const auto& [providerName, providerSkills] : skills)
+            // update tree view. Add new elements
+            for (const auto& [providerId, providedSkills] : skills)
             {
-                if (auto it = std::find(newSkills.begin(), newSkills.end(), providerName);
-                    it != newSkills.end())
+                QTreeWidgetItem* providerItem = nullptr;
+                for (int i = 0; i < widget.treeWidgetSkills->topLevelItemCount(); ++i)
+                {
+                    auto el = widget.treeWidgetSkills->topLevelItem(i);
+                    auto providerName = el->text(0).toStdString();
+                    skills::ProviderID elProviderId(providerName);
+
+                    if (providerId == elProviderId)
+                    {
+                        providerItem = el;
+                        break;
+                    }
+                }
+
+                if (!providerItem)
                 {
-                    auto item = new QTreeWidgetItem(widget.treeWidgetSkills);
-                    item->setText(0, QString::fromStdString(providerName));
-                    for (const auto& [name, sk] : providerSkills)
+                    providerItem = new QTreeWidgetItem(widget.treeWidgetSkills);
+                    providerItem->setText(0, QString::fromStdString(providerId.providerName));
+                }
+
+                for (const auto& [skillId, skill] : providedSkills)
+                {
+                    QTreeWidgetItem* skillItem = nullptr;
+                    for (int i = 0; i < providerItem->childCount(); ++i)
+                    {
+                        auto el = providerItem->child(i);
+                        auto skillName = el->text(0).toStdString();
+                        skills::SkillID elSkillId(providerId.providerName, skillName);
+
+                        if (skillId == elSkillId)
+                        {
+                            skillItem = el;
+                            break;
+                        }
+                    }
+
+                    if (!skillItem)
                     {
-                        auto itsk = new QTreeWidgetItem(item);
-                        item->addChild(itsk);
-                        itsk->setText(0, QString::fromStdString(name));
+                        skillItem = new SkillInfoTreeWidgetItem(skill, providerItem);
+                        skillItem->setText(0, QString::fromStdString(skillId.skillName));
                     }
                 }
             }
@@ -285,7 +346,7 @@ namespace armarx
             {skills::SkillStatus::Initializing, "Initializing"},
             {skills::SkillStatus::Preparing, "Preparing"}};
 
-        if (!manager)
+        if (!memory)
         {
             // check if null
             return;
@@ -295,74 +356,73 @@ namespace armarx
         {
             std::scoped_lock l(updateMutex);
 
-            auto currentManagerStatuses = manager->getSkillExecutionStatuses();
+            auto currentManagerStatuses = memory->getLatestSkillExecutionStatuses(
+                100); // we assume that there are no more than 100 new skills..
 
-            for (const auto& up : currentManagerStatuses)
+            for (const auto& [k, v] : currentManagerStatuses)
             {
-                auto statusUpdate = skills::SkillStatusUpdate::FromIce(up);
+                auto executionId = skills::SkillExecutionID::FromIce(k);
+                auto statusUpdate = skills::SkillStatusUpdate::FromIce(v);
 
-                if (auto it = pastSkillStatusUpdates.find(statusUpdate.executionId);
-                    it == pastSkillStatusUpdates.end())
+                SkillExecutionInfoTreeWidgetItem* found = nullptr;
+                for (int i = 0; i < widget.treeWidgetSkillExecutions->topLevelItemCount(); ++i)
                 {
-                    pastSkillStatusUpdates.insert({statusUpdate.executionId, statusUpdate});
+                    auto c = static_cast<SkillExecutionInfoTreeWidgetItem*>(
+                        widget.treeWidgetSkillExecutions->topLevelItem(i));
 
-                    auto item = new QTreeWidgetItem(widget.treeWidgetSkillExecutions);
-                    item->setText(0, QString::fromStdString("TODO:"));
-                    item->setText(
-                        1, QString::fromStdString(statusUpdate.executionId.skillId.toString()));
-                    if (statusUpdate.hasBeenInitialized())
-                    {
-                        item->setText(
-                            2, QString::fromStdString("YES (TODO:)")); // when was skill scheduled
-                    }
+                    found =
+                        SkillExecutionInfoTreeWidgetItem::SearchRecursiveForMatch(c, executionId);
 
-                    if (statusUpdate.hasBeenRunning())
+                    if (found)
                     {
-                        item->setText(
-                            3, QString::fromStdString("YES (TODO:)")); // when was skill running
+                        // update values
+                        found->setText(3,
+                                       QString::fromStdString(
+                                           statusUpdate.hasBeenConstructed() ? " (\xfb) " : ""));
+                        found->setText(4,
+                                       QString::fromStdString(
+                                           statusUpdate.hasBeenInitialized() ? " (\xfb) " : ""));
+                        found->setText(5,
+                                       QString::fromStdString(
+                                           statusUpdate.hasBeenPrepared() ? " (\xfb) " : ""));
+                        found->setText(6,
+                                       QString::fromStdString(
+                                           statusUpdate.hasBeenRunning() ? " (\xfb) " : ""));
+                        found->setText(7,
+                                       QString::fromStdString(
+                                           statusUpdate.hasBeenTerminated() ? " (\xfb) " : ""));
+                        break;
                     }
+                }
 
-                    if (statusUpdate.hasBeenTerminated())
-                    {
-                        item->setText(4,
-                                      QString::fromStdString(
-                                          "(" + ExecutionStatus2String.at(statusUpdate.status) +
-                                          ")")); // when was skill terminated (and how)
-                    }
-                    item->setText(5, QString::fromStdString(statusUpdate.executionId.executorName));
+                if (!found)
+                {
+                    // TODO: Sort to executor!
+                    auto item = new SkillExecutionInfoTreeWidgetItem(
+                        executionId, widget.treeWidgetSkillExecutions);
+
+                    item->setText(0,
+                                  QString::fromStdString(
+                                      executionId.executionStartedTime.toDateTimeString()));
+                    item->setText(1, QString::fromStdString(executionId.executorName));
+                    item->setText(2, QString::fromStdString(executionId.skillId.toString()));
+                    item->setText(3,
+                                  QString::fromStdString(
+                                      statusUpdate.hasBeenConstructed() ? " (\xfb) " : ""));
+                    item->setText(4,
+                                  QString::fromStdString(
+                                      statusUpdate.hasBeenInitialized() ? " (\xfb) " : ""));
+                    item->setText(
+                        5,
+                        QString::fromStdString(statusUpdate.hasBeenPrepared() ? " (\xfb) " : ""));
+                    item->setText(
+                        6, QString::fromStdString(statusUpdate.hasBeenRunning() ? " (\xfb) " : ""));
+                    item->setText(
+                        7,
+                        QString::fromStdString(statusUpdate.hasBeenTerminated() ? " (\xfb) " : ""));
                 }
             }
-
-            //            widget.listWidgetActiveSkills->clear();
-            //            for (const auto& [id, prefix] : activeSkillsAndPrefixes)
-            //            {
-            //                auto prefixedStr = id.toString(prefix);
-            //                bool longest = true;
-            //                for (
-            //                    const auto& [id2, prefix2] :
-            //                    activeSkillsAndPrefixes) // check if there is a deeper skill currently executing
-            //                {
-            //                    auto prefixedStr2 = id.toString(prefix2);
-            //                    if (prefixedStr == prefixedStr2)
-            //                    {
-            //                        continue;
-            //                    }
-
-            //                    if (simox::alg::starts_with(prefixedStr2, prefixedStr))
-            //                    {
-            //                        longest = false;
-            //                        break;
-            //                    }
-            //                }
-
-            //                if (longest)
-            //                {
-            //                    widget.listWidgetActiveSkills->addItem(
-            //                        QString::fromStdString(id.toString() + ": " + id.toString(prefix)));
-            //                }
-            //            }
         }
-
         catch (...)
         {
             // perhaps the manager died during the method?
@@ -372,14 +432,16 @@ namespace armarx
     void
     SkillManagerMonitorWidgetController::executeSkill()
     {
-        if (selectedSkill.providerName.empty() or selectedSkill.skillName.empty())
+        if (not selectedSkill.skillId.fullySpecified())
         {
             return;
         }
 
         std::scoped_lock l(updateMutex);
-        const auto& skillDescriptions = skills.at(selectedSkill.providerName);
-        if (!skillDescriptions.count(selectedSkill.skillName))
+
+        auto providerId = skills::ProviderID(selectedSkill.skillId);
+        const auto& skillDescriptions = skills.at(providerId);
+        if (skillDescriptions.find(selectedSkill.skillId) == skillDescriptions.end())
         {
             return;
         }
@@ -387,41 +449,37 @@ namespace armarx
         auto data = getConfigAsAron();
 
         char hostname[HOST_NAME_MAX];
-
         gethostname(hostname, HOST_NAME_MAX);
 
-        skills::manager::dto::SkillExecutionRequest exInfo;
-        exInfo.executorName = "Skills.Manager GUI (hostname: " + std::string(hostname) + ")";
-        exInfo.skillId = {selectedSkill.providerName, selectedSkill.skillName};
-        exInfo.params = aron::data::Dict::ToAronDictDTO(data);
+        skills::SkillExecutionRequest req(selectedSkill.skillId,
+                                          "Skills.Manager GUI (hostname: " + std::string(hostname) +
+                                              ")",
+                                          data);
 
-        ARMARX_IMPORTANT << "Executing skill from GUI: " << selectedSkill.providerName << "/"
-                         << selectedSkill.skillName << ". The data was: " << data;
+        ARMARX_CHECK(selectedSkill.skillId.fullySpecified()); // 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.
-        manager->begin_executeSkill(exInfo);
+        memory->begin_executeSkill(req.toManagerIce());
     }
 
     void
     SkillManagerMonitorWidgetController::stopSkill()
     {
-        std::scoped_lock l(updateMutex);
-        if (selectedSkill.providerName.empty() or selectedSkill.skillName.empty())
-        {
-            return;
-        }
+        //        std::scoped_lock l(updateMutex);
+        //        if (selectedSkill.skillId.fullySpecified())
+        //        {
+        //            return;
+        //        }
 
-        const auto& skillDescriptions = skills.at(selectedSkill.providerName);
-        if (!skillDescriptions.count(selectedSkill.skillName))
-        {
-            return;
-        }
+        //        const auto& skillDescriptions = skills.at(*selectedSkill.skillId.providerId);
+        //        if (!skillDescriptions.count(selectedSkill.skillId.skillName))
+        //        {
+        //            return;
+        //        }
 
-        ARMARX_INFO << "Stopping skill from GUI: " << selectedSkill.providerName << "/"
-                    << selectedSkill.skillName;
+        //        ARMARX_INFO << "Stopping skill from GUI: " << selectedSkill.skillId;
 
-        auto id =
-            skills::manager::dto::SkillID{selectedSkill.providerName, selectedSkill.skillName};
-        manager->abortSkill(id);
+        //        manager->abortSkill(selectedSkill.skillId);
     }
 
     void
@@ -439,35 +497,35 @@ namespace armarx
 
         if (!current->parent())
         {
-            // no parent available. Should not happen
+            // no parent available. Perhaps provider clicked?
             return;
         }
 
-        SelectedSkill newSelectedSkill;
-
-        // setup selected skill
-        newSelectedSkill.providerName = current->parent()->text(0).toStdString();
-        newSelectedSkill.skillName = current->text(0).toStdString();
-
-        // setup groupBox
-        widget.groupBoxSkillDetails->setTitle(QString::fromStdString(
-            newSelectedSkill.providerName + "/" + newSelectedSkill.skillName));
-        widget.groupBoxSkillDetails->setEnabled(true);
+        auto c = static_cast<SkillInfoTreeWidgetItem*>(current);
+        auto skillDescription = c->skillDescription;
 
-        if (newSelectedSkill.providerName == selectedSkill.providerName and
-            newSelectedSkill.skillName == selectedSkill.skillName)
+        if (selectedSkill.skillId == skillDescription.skillId)
         {
+            // no change
             return;
         }
 
-        selectedSkill = newSelectedSkill;
+        selectedSkill.skillId = skillDescription.skillId;
+
+        // setup groupBox
+        widget.groupBoxSkillDetails->setTitle(
+            QString::fromStdString(selectedSkill.skillId.toString()));
+        widget.groupBoxSkillDetails->setEnabled(true);
 
         // setup table view
         widget.treeWidgetSkillDetails->clear();
         aronTreeWidgetController = nullptr;
         skillsArgumentsTreeWidgetItem = nullptr;
 
-        auto skillDesc = skills.at(selectedSkill.providerName).at(selectedSkill.skillName);
+        // We assert that the skill exists
+        ARMARX_CHECK(skills.count(selectedSkill.skillId) > 0);
+        ARMARX_CHECK(skills.at(*selectedSkill.skillId.providerId).count(selectedSkill.skillId) > 0);
+        auto skillDesc = skills.at(*selectedSkill.skillId.providerId).at(selectedSkill.skillId);
 
         {
             auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
@@ -476,14 +534,6 @@ namespace armarx
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
-        {
-            auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
-                                          {QString::fromStdString("Available profiles"),
-                                           QString::fromStdString("" /*simox::alg::join(
-                                               simox::alg::get_keys(skillDesc.profiles), ", ")*/)});
-            widget.treeWidgetSkillDetails->addTopLevelItem(it);
-        }
-
         {
             auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
                                           {QString::fromStdString("Description"),
@@ -492,24 +542,39 @@ namespace armarx
         }
 
         {
-            armarx::core::time::Duration d;
-            armarx::core::time::fromIce(skillDesc.timeout, d);
-
             auto it = new QTreeWidgetItem(
                 widget.treeWidgetSkillDetails,
                 {QString::fromStdString("Timeout"),
-                 QString::fromStdString(std::to_string(d.toMilliSeconds())) + " ms"});
+                 QString::fromStdString(std::to_string(skillDesc.timeout.toMilliSeconds())) +
+                     " ms"});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
+        // select root profile
+        widget.comboBoxProfiles->setCurrentIndex(0);
+
+        // remove any profile
+        while (widget.comboBoxProfiles->count() > 1)
+        {
+            widget.comboBoxProfiles->removeItem(1);
+        }
+
+        // add new profiles for this skill
+        // TODO: Where stored?
+
         skillsArgumentsTreeWidgetItem = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
                                                             {QString::fromStdString("Arguments")});
-        auto aron_args = aron::type::Object::FromAronObjectDTO(skillDesc.acceptedType);
-        auto default_args =
-            nullptr; //aron::data::Dict::FromAronDictDTO(skillDesc.defaultParams); TODO! fabian.peller
+        auto aron_args = skillDesc.acceptedType;
+        auto default_args_of_profile = skillDesc.rootProfileParameterization;
+
+        aronTreeWidgetController =
+            std::make_shared<AronTreeWidgetController>(widget.treeWidgetSkillDetails,
+                                                       skillsArgumentsTreeWidgetItem,
+                                                       aron_args,
+                                                       default_args_of_profile);
 
-        aronTreeWidgetController = std::make_shared<AronTreeWidgetController>(
-            widget.treeWidgetSkillDetails, skillsArgumentsTreeWidgetItem, aron_args, default_args);
+        // automatically expand args
+        skillsArgumentsTreeWidgetItem->setExpanded(true);
     }
 
     aron::data::DictPtr
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
index d3fb1250f..869e79213 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
@@ -38,12 +38,51 @@
 #include <RobotAPI/libraries/aron/core/data/variant/All.h>
 #include <RobotAPI/libraries/aron/core/type/variant/All.h>
 #include <RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.h>
+#include <RobotAPI/libraries/skills/core/ProviderID.h>
+#include <RobotAPI/libraries/skills/core/SkillDescription.h>
 #include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 #include "aronTreeWidget/AronTreeWidgetController.h"
 
 namespace armarx
 {
+    class SkillInfoTreeWidgetItem : public QTreeWidgetItem
+    {
+    public:
+        SkillInfoTreeWidgetItem(const skills::SkillDescription& desc, QTreeWidgetItem* parent) :
+            QTreeWidgetItem(parent), skillDescription(desc)
+        {
+        }
+
+        SkillInfoTreeWidgetItem(const skills::SkillDescription& desc, QTreeWidget* parent) :
+            QTreeWidgetItem(parent), skillDescription(desc)
+        {
+        }
+
+        skills::SkillDescription skillDescription;
+    };
+
+    class SkillExecutionInfoTreeWidgetItem : public QTreeWidgetItem
+    {
+    public:
+        SkillExecutionInfoTreeWidgetItem(const skills::SkillExecutionID& id,
+                                         QTreeWidgetItem* parent) :
+            QTreeWidgetItem(parent), executionId(id)
+        {
+        }
+
+        SkillExecutionInfoTreeWidgetItem(const skills::SkillExecutionID& id, QTreeWidget* parent) :
+            QTreeWidgetItem(parent), executionId(id)
+        {
+        }
+
+        static SkillExecutionInfoTreeWidgetItem*
+        SearchRecursiveForMatch(SkillExecutionInfoTreeWidgetItem* el,
+                                const skills::SkillExecutionID& needle);
+
+        skills::SkillExecutionID executionId;
+    };
+
     class ARMARXCOMPONENT_IMPORT_EXPORT SkillManagerMonitorWidgetController :
         public armarx::ArmarXComponentWidgetControllerTemplate<SkillManagerMonitorWidgetController>
     {
@@ -101,21 +140,24 @@ namespace armarx
         QPointer<SimpleConfigDialog> dialog;
 
         std::string observerName = "SkillManager";
-        skills::manager::dti::SkillManagerInterfacePrx manager = nullptr;
-
-        struct SelectedSkill
-        {
-            std::string providerName;
-            std::string skillName;
-        };
+        skills::dti::SkillMemoryInterfacePrx memory = nullptr;
 
         // Data taken from observer (snapshot of it)
         mutable std::mutex updateMutex;
-        skills::manager::dto::SkillDescriptionMap skills = {};
-        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> pastSkillStatusUpdates = {};
+        std::map<skills::ProviderID, std::map<skills::SkillID, skills::SkillDescription>> skills =
+            {};
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> skillStatusUpdates = {};
 
         // User Input
-        SelectedSkill selectedSkill;
+        struct SelectedSkill
+        {
+            skills::SkillID skillId;
+
+            // make default constructable
+            SelectedSkill() : skillId({skills::SkillID::UNKNOWN}, skills::SkillID::UNKNOWN)
+            {
+            }
+        } selectedSkill;
 
         // Helper to get the treeWidgetItem easily
         QTreeWidgetItem* skillsArgumentsTreeWidgetItem = nullptr;
@@ -124,9 +166,6 @@ namespace armarx
         // others
         QTimer* refreshSkillsResultTimer;
 
-        // skillExecutions
-        std::vector<std::thread> executions;
-
         // connected flag
         std::atomic_bool connected = false;
     };
diff --git a/source/RobotAPI/interface/skills/SkillManagerInterface.ice b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
index adda483ad..17294f7a6 100644
--- a/source/RobotAPI/interface/skills/SkillManagerInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
@@ -32,67 +32,62 @@ module armarx
         {
             module dto
             {
+                struct ProviderID
+                {
+                    string providerName;
+                };
+
                 // A skill ID. Must be unique within one SkillManager
                 struct SkillID
                 {
-                    string providerName;
+                    ProviderID providerId;
                     string skillName;
                 };
 
-                struct ProviderID
+                struct SkillDescription
                 {
-                    string providerName;
+                    SkillID skillId;
+                    string description;
+                    armarx::core::time::dto::Duration timeout;
+                    aron::type::dto::AronObject acceptedType;
+                    aron::type::dto::AronObject returndType;
+                    aron::data::dto::Dict rootProfileDefaults;
                 };
 
+                dictionary<SkillID, dto::SkillDescription> SkillDescriptionMap;
+
                 struct ProviderInfo
                 {
                     ProviderID providerId;
-                    provider::dti::SkillProviderInterface* provider;
-                    provider::dto::SkillDescriptionMap providedSkills;
+                    provider::dti::SkillProviderInterface* providerInterface;
+                    dto::SkillDescriptionMap providedSkills;
                 };
 
-                // The minimum information that is needed to uniquely identifying a past skill execution
                 struct SkillExecutionID
                 {
-                    SkillID skillId; // the id of the skill
-                    string
-                        executorName; // the name of the component/lib/skill that called the execution of the skill
-                    armarx::core::time::dto::DateTime
-                        executionStartedTime; // The time a skill was triggered
+                    SkillID skillId;
+                    string executorName;
+                    armarx::core::time::dto::DateTime executionStartedTime;
                     string uuid;
                 };
 
-                // Status updates of a skill (similar to the status update of the providers except the skillID)
-                struct SkillStatusUpdateHeader
-                {
-                    SkillExecutionID executionId;
-                    aron::data::dto::Dict usedParams; // the used parameterization
-                    callback::dti::SkillProviderCallbackInterface*
-                        usedCallbackInterface; // the used callback interface. Probably a prx to the manager
-                    provider::dto::Execution::Status status; // the current status of the skill
-                };
-
-                // (similar to the status update of the providers except the skillID)
                 struct SkillStatusUpdate
                 {
-                    SkillStatusUpdateHeader header;
-                    aron::data::dto::Dict
-                        data; // data, attached to the status update. If send via a callback, this data may be used by the callback interface
+                    SkillExecutionID executionId;
+                    aron::data::dto::Dict usedParams;
+                    callback::dti::SkillProviderCallbackInterface* usedCallbackInterface;
+                    core::dto::Execution::Status status;
+                    aron::data::dto::Dict data;
                 };
 
                 dictionary<SkillExecutionID, SkillStatusUpdate> SkillStatusUpdateMap;
 
                 struct SkillExecutionRequest
                 {
-                    SkillID
-                        skillId; // The id of a skill to request. Note that the skill or provider name can be regexes.
-                    string executorName; // Who called the request
-                    aron::data::dto::Dict
-                        params; // the parameters for the skill. Can be nullptr if the skill does not require parameters
+                    SkillID skillId;
+                    string executorName;
+                    aron::data::dto::Dict params;
                 };
-
-                // Provider data types
-                dictionary<SkillID, provider::dto::SkillDescription> SkillDescriptionMap;
             }
 
             module dti
@@ -106,11 +101,14 @@ module armarx
 
                     void removeProvider(dto::ProviderID provider);
 
+                    optional(1) dto::SkillDescription getSkillDescription(
+                        dto::SkillID skillId); // get one skilldescriptions from a provider
+
                     dto::SkillDescriptionMap
                     getSkillDescriptions(); // get all skilldescriptions from all providers
 
-                    dto::SkillStatusUpdate
-                    getSkillExecutionStatus(dto::SkillExecutionID executionId);
+                    optional(2) dto::SkillStatusUpdate
+                        getSkillExecutionStatus(dto::SkillExecutionID executionId);
 
                     dto::SkillStatusUpdateMap
                     getSkillExecutionStatuses(); // returns the current executions from all providers
diff --git a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
index 15a3dc379..934d2faba 100644
--- a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
@@ -38,7 +38,7 @@ module armarx
             interface SkillMemoryInterface extends armem::server::MemoryInterface,
                 dti::StatechartListenerInterface, manager::dti::SkillManagerInterface
             {
-                provider::dto::SkillStatusUpdateMap getLatestSkillExecutionStatuses(
+                manager::dto::SkillStatusUpdateMap getLatestSkillExecutionStatuses(
                     int n); // returns latest n statusupdates of all providers
             };
         }
diff --git a/source/RobotAPI/interface/skills/SkillProviderInterface.ice b/source/RobotAPI/interface/skills/SkillProviderInterface.ice
index 31449a86d..b9db3268a 100644
--- a/source/RobotAPI/interface/skills/SkillProviderInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillProviderInterface.ice
@@ -39,6 +39,51 @@ module armarx
                 interface SkillProviderCallbackInterface;
             }
         }
+
+        module provider
+        {
+            module dti
+            {
+                interface SkillProviderInterface;
+            }
+        }
+    }
+}
+
+module armarx
+{
+    module skills
+    {
+        module core
+        {
+            module dto
+            {
+
+                sequence<string> StringList;
+
+                // The status enum of a skill
+                module Execution
+                {
+                    enum Status
+                    {
+                        Constructing,
+                        Initializing,
+                        Preparing,
+                        Running,
+
+                        // terminating values
+                        Failed,
+                        Succeeded,
+                        Aborted
+                    };
+                }
+
+                // Status updates of a skill
+                class SkillStatusUpdateBase
+                {
+                };
+            }
+        }
     }
 }
 
@@ -51,7 +96,6 @@ module armarx
         {
             module dto
             {
-                sequence<string> StringList;
 
                 // A profile is something that is client side!
                 //                // A parameterization profile
@@ -72,24 +116,16 @@ module armarx
                     string skillName;
                 };
 
-                // A provider ID. Only used in callbacks
-                struct ProviderID
-                {
-                    string providerName;
-                };
-
                 // Description of a skill, independant of a provider
                 // A skill is nothing but a executable thing, which can be executed on one or more 'robots' (empty means all)
                 struct SkillDescription
                 {
-                    SkillID skillId; // the id of the skill
-                    string
-                        description; // a human readable description of what the skill does. Used in GUI
-                    armarx::core::time::dto::Duration timeout; // can be set to -1 for infinite
-                    aron::type::dto::AronObject
-                        acceptedType; // the name of the object is irrelevant and only used in GUI. nullptr if not set
-                    aron::data::dto::Dict
-                        rootProfileDefaults; // default parameterization for the skill. Must be robot agnostic
+                    SkillID skillId;
+                    string description;
+                    armarx::core::time::dto::Duration timeout;
+                    aron::type::dto::AronObject acceptedType;
+                    aron::type::dto::AronObject returndType;
+                    aron::data::dto::Dict rootProfileDefaults;
                 };
 
                 dictionary<SkillID, SkillDescription> SkillDescriptionMap;
@@ -97,57 +133,29 @@ module armarx
                 // Input to a provider to execute a skill
                 struct SkillExecutionRequest
                 {
-                    SkillID skillId; // the id of the skill
-                    string
-                        executorName; // the name of the component/lib/skill that called the execution of the skill
-                    aron::data::dto::Dict params; // the used parameterization
-                    callback::dti::SkillProviderCallbackInterface*
-                        callbackInterface; // use nullptr if you do not want to have callbacks
+                    SkillID skillId;
+                    string executorName;
+                    aron::data::dto::Dict params;
+                    callback::dti::SkillProviderCallbackInterface* callbackInterface;
                 };
 
-                // The status enum of a skill
-                module Execution
-                {
-                    enum Status
-                    {
-                        Constructing,
-                        Initializing,
-                        Preparing,
-                        Running,
-
-                        // terminating values
-                        Failed,
-                        Succeeded,
-                        Aborted
-                    };
-                }
-
                 // The minimum information that is needed to uniquely identifying a past skill execution
                 struct SkillExecutionID
                 {
-                    SkillID skillId; // the id of the skill
-                    string
-                        executorName; // the name of the component/lib/skill that called the execution of the skill
-                    armarx::core::time::dto::DateTime
-                        executionStartedTime; // The time a skill was triggered
+                    SkillID skillId;
+                    string executorName;
+                    armarx::core::time::dto::DateTime executionStartedTime;
                     string uuid;
                 };
 
                 // Status updates of a skill
-                struct SkillStatusUpdateHeader
-                {
-                    SkillExecutionID executionId;
-                    aron::data::dto::Dict usedParams; // the used parameterization
-                    callback::dti::SkillProviderCallbackInterface*
-                        usedCallbackInterface; // the used callback interface. Probably a prx to the manager
-                    Execution::Status status; // the current status of the skill
-                };
-
                 struct SkillStatusUpdate
                 {
-                    SkillStatusUpdateHeader header;
-                    aron::data::dto::Dict
-                        data; // data, attached to the status update. If send via a callback, this data may be used by the callback interface
+                    SkillExecutionID executionId;
+                    aron::data::dto::Dict usedParams;
+                    callback::dti::SkillProviderCallbackInterface* usedCallbackInterface;
+                    core::dto::Execution::Status status;
+                    aron::data::dto::Dict data;
                 };
 
                 dictionary<SkillExecutionID, SkillStatusUpdate> SkillStatusUpdateMap;
@@ -157,12 +165,12 @@ module armarx
             {
                 interface SkillProviderInterface
                 {
-                    dto::SkillDescription getSkillDescription(dto::SkillID skill);
+                    optional(1) dto::SkillDescription getSkillDescription(dto::SkillID skill);
 
                     dto::SkillDescriptionMap getSkillDescriptions();
 
-                    dto::SkillStatusUpdate
-                    getSkillExecutionStatus(dto::SkillExecutionID executionId);
+                    optional(2) dto::SkillStatusUpdate
+                        getSkillExecutionStatus(dto::SkillExecutionID executionId);
 
                     dto::SkillStatusUpdateMap
                     getSkillExecutionStatuses(); // returns all current skill executions
@@ -195,6 +203,10 @@ module armarx
         {
             module dto
             {
+                struct ProviderID
+                {
+                    string providerName;
+                };
             }
 
             module dti
@@ -203,7 +215,7 @@ module armarx
                 {
                     // used for callbacks from providers to update their skill execution status
                     void updateStatusForSkill(provider::dto::SkillStatusUpdate statusUpdate,
-                                              provider::dto::ProviderID providerId);
+                                              dto::ProviderID providerId);
                 }
             }
         }
diff --git a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
index 9b218af03..85bf52319 100644
--- a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
+++ b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
@@ -11,6 +11,23 @@ The memory should look like the following:
 <?xml version="1.0" encoding="UTF-8" ?>
 <AronTypeDefinition>
     <GenerateTypes>
+        <Object name='armarx::skills::arondto::ProviderID'>
+            <ObjectChild key='providerName'>
+                <String />
+            </ObjectChild>
+        </Object>
+
+        <Object name='armarx::skills::arondto::SkillID'>
+            <ObjectChild key='providerId'>
+                <armarx::skills::arondto::ProviderID />
+            </ObjectChild>
+            <ObjectChild key='skillName'>
+                <String />
+            </ObjectChild>
+        </Object>
+
+
+        <!-- TODO -->
         <Object name='armarx::skills::arondto::SkillProfile'>
 
             <ObjectChild key='profileName'>
@@ -29,8 +46,8 @@ The memory should look like the following:
 
 
         <Object name='armarx::skills::arondto::SkillDescription'>
-            <ObjectChild key='skillName'>
-                <String />
+            <ObjectChild key='skillId'>
+                <armarx::skills::arondto::SkillID />
             </ObjectChild>
 
             <ObjectChild key='description'>
@@ -53,14 +70,28 @@ The memory should look like the following:
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
 
+            <ObjectChild key='returnType'>
+                <AnyObject shared_ptr="1" />
+            </ObjectChild>
+
         </Object>
 
-        <Object name='armarx::skills::arondto::SkillExecutionInfo'>
+        <!-- TODO -->
+        <Object name='armarx::skills::arondto::CompositeSkillExecutionParams'>
             <ObjectChild key='providerName'>
-                <String />
+                <List>
+                    <String /> <!--<armarx::skills::arondto::SkillExecutionInfo />-->
+                </List>
             </ObjectChild>
+        </Object>
 
-            <ObjectChild key='skillName'>
+        <Object name='armarx::skills::arondto::SkillExecutionRequest'>
+
+            <ObjectChild key='skillId'>
+                <armarx::skills::arondto::SkillID />
+            </ObjectChild>
+
+            <ObjectChild key='executorName'>
                 <String />
             </ObjectChild>
 
@@ -69,25 +100,28 @@ The memory should look like the following:
             </ObjectChild>
         </Object>
 
-        <Object name='armarx::skills::arondto::CompositeSkillExecutionParams'>
-            <ObjectChild key='providerName'>
-                <List>
-                    <armarx::skills::arondto::SkillExecutionInfo />
-                </List>
+        <Object name='armarx::skills::arondto::SkillExecutionEvent'>
+
+            <ObjectChild key='skillId'>
+                <armarx::skills::arondto::SkillID />
             </ObjectChild>
-        </Object>
 
-        <Object name='armarx::skills::arondto::SkillExecutionRequest' extends="armarx::skills::arondto::SkillExecutionInfo">
             <ObjectChild key='executorName'>
                 <String />
             </ObjectChild>
-        </Object>
 
-        <Object name='armarx::skills::arondto::SkillExecutionEvent' extends="armarx::skills::arondto::SkillExecutionInfo">
+            <ObjectChild key='executionStartedTimestamp'>
+                <DateTime />
+            </ObjectChild>
+
             <ObjectChild key='status'>
                 <String />
             </ObjectChild>
 
+            <ObjectChild key='params'>
+                <AnyObject shared_ptr="1" />
+            </ObjectChild>
+
             <ObjectChild key='data'>
                 <AnyObject shared_ptr="1" />
             </ObjectChild>
diff --git a/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp b/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp
index 1d8383b68..4bb6f1f51 100644
--- a/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp
+++ b/source/RobotAPI/libraries/armem_skills/aron_conversions.cpp
@@ -1,26 +1,50 @@
 #include "aron_conversions.h"
 
+#include <RobotAPI/libraries/aron/converter/datatype/DatatypeConverterVisitor.h>
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
+
 namespace armarx::armem
 {
-    std::map<armarx::eStateType, armarx::skills::arondto::Statechart::StateType> toAronStateTypeMap =
-    {
-        {eNormalState, (armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::NORMAL},
-        {eFinalState, (armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::FINAL},
-        {eRemoteState, (armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::REMOTE},
-        {eDynamicRemoteState, (armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::DYNAMIC_REMOTE},
-        {eUndefined, (armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::UNDEFINED},
+    std::map<armarx::eStateType, armarx::skills::arondto::Statechart::StateType>
+        toAronStateTypeMap = {
+            {eNormalState,
+             (armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::NORMAL},
+            {eFinalState,
+             (armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::FINAL},
+            {eRemoteState,
+             (armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::REMOTE},
+            {eDynamicRemoteState,
+             (armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::DYNAMIC_REMOTE},
+            {eUndefined,
+             (armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::UNDEFINED},
     };
 
-    std::map<armarx::skills::arondto::Statechart::StateType, armarx::eStateType> fromAronStateTypeMap =
-    {
-        {(armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::NORMAL, eNormalState},
-        {(armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::FINAL, eFinalState},
-        {(armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::REMOTE, eRemoteState},
-        {(armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::DYNAMIC_REMOTE, eDynamicRemoteState},
-        {(armarx::skills::arondto::Statechart::StateType) armarx::skills::arondto::Statechart::StateType::UNDEFINED, eUndefined},
+    std::map<armarx::skills::arondto::Statechart::StateType, armarx::eStateType>
+        fromAronStateTypeMap = {
+            {(armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::NORMAL,
+             eNormalState},
+            {(armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::FINAL,
+             eFinalState},
+            {(armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::REMOTE,
+             eRemoteState},
+            {(armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::DYNAMIC_REMOTE,
+             eDynamicRemoteState},
+            {(armarx::skills::arondto::Statechart::StateType)
+                 armarx::skills::arondto::Statechart::StateType::UNDEFINED,
+             eUndefined},
     };
 
-    void fromAron(const skills::arondto::Statechart::StateType& dto, eStateType& bo)
+    void
+    fromAron(const skills::arondto::Statechart::StateType& dto, eStateType& bo)
     {
         if (fromAronStateTypeMap.find(dto) != fromAronStateTypeMap.end())
         {
@@ -32,7 +56,8 @@ namespace armarx::armem
         }
     }
 
-    void toAron(skills::arondto::Statechart::StateType& dto, const eStateType& bo)
+    void
+    toAron(skills::arondto::Statechart::StateType& dto, const eStateType& bo)
     {
         if (toAronStateTypeMap.find(bo) != toAronStateTypeMap.end())
         {
@@ -44,7 +69,8 @@ namespace armarx::armem
         }
     }
 
-    void fromAron(const skills::arondto::Statechart::ParameterMap& dto, StateParameterMap& bo)
+    void
+    fromAron(const skills::arondto::Statechart::ParameterMap& dto, StateParameterMap& bo)
     {
         // todo: implement
         //        for (auto const& [key, val] : dto.parameters)
@@ -54,7 +80,8 @@ namespace armarx::armem
         //        }
     }
 
-    void toAron(skills::arondto::Statechart::ParameterMap& dto, const StateParameterMap& bo)
+    void
+    toAron(skills::arondto::Statechart::ParameterMap& dto, const StateParameterMap& bo)
     {
         for (auto const& [key, val] : bo)
         {
@@ -62,7 +89,9 @@ namespace armarx::armem
         }
     }
 
-    void fromAron(const skills::arondto::Statechart::Transition& dto, ProfilerStatechartTransitionWithParameters& bo)
+    void
+    fromAron(const skills::arondto::Statechart::Transition& dto,
+             ProfilerStatechartTransitionWithParameters& bo)
     {
         bo.processId = dto.processId;
         bo.sourceStateIdentifier = dto.sourceStateIdentifier;
@@ -74,7 +103,9 @@ namespace armarx::armem
         fromAron(dto.outputParameters, bo.outputParameters);
     }
 
-    void toAron(skills::arondto::Statechart::Transition& dto, const ProfilerStatechartTransitionWithParameters& bo)
+    void
+    toAron(skills::arondto::Statechart::Transition& dto,
+           const ProfilerStatechartTransitionWithParameters& bo)
     {
         dto.processId = bo.processId;
         dto.sourceStateIdentifier = bo.sourceStateIdentifier;
@@ -85,4 +116,122 @@ namespace armarx::armem
         toAron(dto.localParameters, bo.localParameters);
         toAron(dto.outputParameters, bo.outputParameters);
     }
-}
+
+    void
+    fromAron(const armarx::skills::arondto::ProviderID& dto, skills::ProviderID& bo)
+    {
+        bo.providerName = dto.providerName;
+    }
+
+    void
+    toAron(armarx::skills::arondto::ProviderID& dto, const skills::ProviderID& bo)
+    {
+        dto.providerName = bo.providerName;
+    }
+
+    void
+    fromAron(const armarx::skills::arondto::SkillID& dto, skills::SkillID& bo)
+    {
+        bo.skillName = dto.skillName;
+        bo.providerId = skills::ProviderID(skills::SkillID::UNKNOWN);
+        fromAron(dto.providerId, *bo.providerId);
+    }
+
+    void
+    toAron(armarx::skills::arondto::SkillID& dto, const skills::SkillID& bo)
+    {
+        dto.skillName = bo.skillName;
+        dto.providerId.resetHard();
+        if (bo.providerId.has_value())
+        {
+            toAron(dto.providerId, *bo.providerId);
+        }
+    }
+
+    void
+    fromAron(const armarx::skills::arondto::SkillDescription& dto, skills::SkillDescription& bo)
+    {
+        fromAron(dto.skillId, bo.skillId);
+        bo.description = dto.description;
+        bo.timeout = dto.timeout;
+        bo.rootProfileParameterization = dto.rootProfileParameterization;
+        if (dto.acceptedType)
+        {
+            throw armarx::LocalException("Not implemented yet");
+        }
+    }
+
+    void
+    toAron(armarx::skills::arondto::SkillDescription& dto, const skills::SkillDescription& bo)
+    {
+        toAron(dto.skillId, bo.skillId);
+        dto.description = bo.description;
+        dto.timeout = bo.timeout;
+        dto.rootProfileParameterization = bo.rootProfileParameterization;
+        if (bo.acceptedType)
+        {
+            aron::type::converter::AronDatatypeConverterVisitor c;
+            aron::type::visit(c, bo.acceptedType);
+
+            dto.acceptedType = aron::data::Dict::DynamicCastAndCheck(c.latest);
+        }
+    }
+
+    void
+    fromAron(const armarx::skills::arondto::SkillExecutionRequest& dto,
+             skills::SkillExecutionRequest& bo)
+    {
+        fromAron(dto.skillId, bo.skillId);
+        bo.executorName = dto.executorName;
+        bo.params = dto.params;
+    }
+
+    void
+    toAron(armarx::skills::arondto::SkillExecutionRequest& dto,
+           const skills::SkillExecutionRequest& bo)
+    {
+        toAron(dto.skillId, bo.skillId);
+        dto.executorName = bo.executorName;
+        dto.params = bo.params;
+    }
+
+    void
+    fromAron(const armarx::skills::arondto::SkillExecutionEvent& dto, skills::SkillStatusUpdate& bo)
+    {
+        static std::map<std::string, skills::SkillStatus> map{
+            {"Constructing", skills::SkillStatus::Constructing},
+            {"Initializing", skills::SkillStatus::Initializing},
+            {"Preparing", skills::SkillStatus::Preparing},
+            {"Running", skills::SkillStatus::Running},
+            {"Failed", skills::SkillStatus::Failed},
+            {"Aborted", skills::SkillStatus::Aborted},
+            {"Succeeded", skills::SkillStatus::Succeeded}};
+
+        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.status = map.at(dto.status);
+    }
+
+    void
+    toAron(armarx::skills::arondto::SkillExecutionEvent& dto, const skills::SkillStatusUpdate& bo)
+    {
+        static std::map<skills::SkillStatus, std::string> map{
+            {skills::SkillStatus::Constructing, "Constructing"},
+            {skills::SkillStatus::Initializing, "Initializing"},
+            {skills::SkillStatus::Preparing, "Preparing"},
+            {skills::SkillStatus::Running, "Running"},
+            {skills::SkillStatus::Failed, "Failed"},
+            {skills::SkillStatus::Aborted, "Aborted"},
+            {skills::SkillStatus::Succeeded, "Succeeded"}};
+
+        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.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 37092255c..57b7dd312 100644
--- a/source/RobotAPI/libraries/armem_skills/aron_conversions.h
+++ b/source/RobotAPI/libraries/armem_skills/aron_conversions.h
@@ -3,16 +3,45 @@
 #include <ArmarXCore/interface/core/Profiler.h>
 #include <ArmarXCore/observers/ObserverObjectFactories.h>
 
+#include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
 #include <RobotAPI/libraries/armem_skills/aron/Statechart.aron.generated.h>
+#include <RobotAPI/libraries/skills/core/SkillDescription.h>
+#include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 namespace armarx::armem
 {
-    void fromAron(const armarx::skills::arondto::Statechart::StateType& dto, armarx::eStateType& bo);
+    void fromAron(const armarx::skills::arondto::Statechart::StateType& dto,
+                  armarx::eStateType& bo);
     void toAron(armarx::skills::arondto::Statechart::StateType& dto, const armarx::eStateType& bo);
 
-    void fromAron(const armarx::skills::arondto::Statechart::ParameterMap& dto, armarx::StateParameterMap& bo);
-    void toAron(armarx::skills::arondto::Statechart::ParameterMap& dto, const armarx::StateParameterMap& bo);
+    void fromAron(const armarx::skills::arondto::Statechart::ParameterMap& dto,
+                  armarx::StateParameterMap& bo);
+    void toAron(armarx::skills::arondto::Statechart::ParameterMap& dto,
+                const armarx::StateParameterMap& bo);
 
-    void fromAron(const armarx::skills::arondto::Statechart::Transition& dto, armarx::ProfilerStatechartTransitionWithParameters& bo);
-    void toAron(armarx::skills::arondto::Statechart::Transition& dto, const armarx::ProfilerStatechartTransitionWithParameters& bo);
-}
+    void fromAron(const armarx::skills::arondto::Statechart::Transition& dto,
+                  armarx::ProfilerStatechartTransitionWithParameters& bo);
+    void toAron(armarx::skills::arondto::Statechart::Transition& dto,
+                const armarx::ProfilerStatechartTransitionWithParameters& bo);
+
+    void fromAron(const armarx::skills::arondto::ProviderID& dto, skills::ProviderID& bo);
+    void toAron(armarx::skills::arondto::ProviderID& dto, const skills::ProviderID& bo);
+
+    void fromAron(const armarx::skills::arondto::SkillID& dto, skills::SkillID& bo);
+    void toAron(armarx::skills::arondto::SkillID& dto, const skills::SkillID& bo);
+
+    void fromAron(const armarx::skills::arondto::SkillDescription& dto,
+                  skills::SkillDescription& bo);
+    void toAron(armarx::skills::arondto::SkillDescription& dto, const skills::SkillDescription& bo);
+
+    void fromAron(const armarx::skills::arondto::SkillExecutionRequest& dto,
+                  skills::SkillExecutionRequest& bo);
+    void toAron(armarx::skills::arondto::SkillExecutionRequest& dto,
+                const skills::SkillExecutionRequest& bo);
+
+    void fromAron(const armarx::skills::arondto::SkillExecutionEvent& dto,
+                  skills::SkillStatusUpdate& bo);
+    void toAron(armarx::skills::arondto::SkillExecutionEvent& dto,
+                const skills::SkillStatusUpdate& bo);
+} // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp
index 51d783b81..d2f99544e 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp
@@ -6,6 +6,7 @@
 
 #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
+#include <RobotAPI/libraries/armem_skills/aron_conversions.h>
 #include <RobotAPI/libraries/aron/converter/datatype/DatatypeConverterVisitor.h>
 #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 
@@ -31,35 +32,16 @@ namespace armarx::skills::segment
     }
 
     void
-    ExecutableSkillLibraryCoreSegment::addSkillProvider(
-        const skills::manager::dto::ProviderInfo& info)
+    ExecutableSkillLibraryCoreSegment::addSkillProvider(const skills::ProviderInfo& info)
     {
         // add skills
         auto skills = info.providedSkills;
-
         auto provId = id().withProviderSegmentName(info.providerId.providerName);
 
-        for (const auto& [key, desc] : skills)
+        for (const auto& [s, d] : skills)
         {
             armarx::skills::arondto::SkillDescription skillDescription;
-            skillDescription.skillName = desc.skillId.skillName;
-            skillDescription.description = desc.description;
-            skillDescription.iceInfo = info.provider->ice_toString();
-
-            skillDescription.rootProfileParameterization =
-                armarx::aron::data::Dict::FromAronDictDTO(desc.rootProfileDefaults);
-
-            armarx::core::time::fromIce(desc.timeout, skillDescription.timeout);
-
-            if (desc.acceptedType)
-            {
-                auto t = aron::type::Object::FromAronObjectDTO(desc.acceptedType);
-
-                aron::type::converter::AronDatatypeConverterVisitor c;
-                aron::type::visit(c, t);
-
-                skillDescription.acceptedType = aron::data::Dict::DynamicCastAndCheck(c.latest);
-            }
+            armem::toAron(skillDescription, d);
 
             armem::Commit commit;
             auto& entityUpdate = commit.add();
@@ -68,7 +50,7 @@ namespace armarx::skills::segment
             entityUpdate.sentTime = armem::Time::Now();
             entityUpdate.arrivedTime = armem::Time::Now();
             entityUpdate.instancesData = {skillDescription.toAron()};
-            entityUpdate.entityID = provId.withEntityName(skillDescription.skillName);
+            entityUpdate.entityID = provId.withEntityName(d.skillId.skillName);
 
             // Commit data to memory and notify
             iceMemory.commit(commit);
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h
index a2d4227bb..e71a8a74a 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h
@@ -4,19 +4,18 @@
 #include <RobotAPI/libraries/armem/server/segment/SpecializedSegment.h>
 
 // ArmarX
+#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 #include <ArmarXCore/interface/core/Profiler.h>
 #include <ArmarXCore/observers/ObserverObjectFactories.h>
-#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
 #include <RobotAPI/interface/skills/SkillProviderInterface.h>
-
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
+#include <RobotAPI/libraries/skills/core/ProviderInfo.h>
 
 namespace armarx::skills::segment
 {
-    class ExecutableSkillLibraryCoreSegment :
-        public armem::server::segment::SpecializedCoreSegment
+    class ExecutableSkillLibraryCoreSegment : public armem::server::segment::SpecializedCoreSegment
     {
         using Base = armem::server::segment::SpecializedCoreSegment;
 
@@ -25,10 +24,10 @@ namespace armarx::skills::segment
 
         ExecutableSkillLibraryCoreSegment(armem::server::MemoryToIceAdapter& iceMemory);
 
-        void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix);
+        void defineProperties(PropertyDefinitionsPtr defs, const std::string& prefix);
         void init();
 
-        void addSkillProvider(const skills::manager::dto::ProviderInfo& info);
+        void addSkillProvider(const skills::ProviderInfo& info);
         void removeSkillProvider(const std::string& providerName);
 
         size_t size() const;
@@ -36,4 +35,4 @@ namespace armarx::skills::segment
     private:
         std::map<std::string, std::map<std::string, skills::manager::dto::ProviderInfo>> skills;
     };
-}
+} // namespace armarx::skills::segment
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
index 8960afd4b..6328e6d73 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
@@ -4,8 +4,8 @@
 
 #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
+#include <RobotAPI/libraries/armem_skills/aron_conversions.h>
 #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 namespace armarx::skills::segment
 {
@@ -30,34 +30,15 @@ namespace armarx::skills::segment
     }
 
     void
-    SkillEventCoreSegment::addSkillUpdateEvent(
-        const skills::provider::dto::SkillStatusUpdate& update,
-        const std::string& providerName)
+    SkillEventCoreSegment::addSkillUpdateEvent(const skills::SkillStatusUpdate& update)
     {
-        // add update for skill to memory
-        static std::map<armarx::skills::provider::dto::Execution::Status, std::string>
-            ExecutionStatus2String = {
-                {armarx::skills::provider::dto::Execution::Status::Constructing, "Constructing"},
-                {armarx::skills::provider::dto::Execution::Status::Initializing, "Initializing"},
-                {armarx::skills::provider::dto::Execution::Status::Preparing, "Preparing"},
-                {armarx::skills::provider::dto::Execution::Status::Running, "Running"},
-                {armarx::skills::provider::dto::Execution::Status::Aborted, "Aborted"},
-                {armarx::skills::provider::dto::Execution::Status::Failed, "Failed"},
-                {armarx::skills::provider::dto::Execution::Status::Succeeded, "Succeeded"}};
-
-        auto up = skills::SkillStatusUpdate::FromIce(update, providerName);
-
         // create commit about new update
         armarx::skills::arondto::SkillExecutionEvent event;
-        event.providerName = up.executionId.skillId.providerName;
-        event.skillName = up.executionId.skillId.skillName;
-        event.status = ExecutionStatus2String.at(update.header.status);
-        event.params = up.usedParameterization.parameterization;
-        event.data = up.data;
+        armem::toAron(event, update);
 
         armem::MemoryID commitId = id();
-        commitId.providerSegmentName = event.providerName;
-        commitId.entityName = event.skillName;
+        commitId.providerSegmentName = event.skillId.providerId.providerName;
+        commitId.entityName = event.skillId.skillName;
 
         auto aron = event.toAron();
 
@@ -68,6 +49,44 @@ namespace armarx::skills::segment
         entityUpdate.instancesData = {aron};
         entityUpdate.entityID = commitId;
 
-        iceMemory.commit(comm);
+        iceMemory.commitLocking(comm);
+    }
+
+    std::map<skills::SkillExecutionID, skills::SkillStatusUpdate>
+    SkillEventCoreSegment::getLatestSkillEvents(int n)
+    {
+        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)
+            {
+                auto event = i.dataAs<armarx::skills::arondto::SkillExecutionEvent>();
+                skills::SkillStatusUpdate up({{{""}, ""}, "", armarx::core::time::DateTime::Now()},
+                                             {nullptr, nullptr});
+                armem::fromAron(event, up);
+                sorted.emplace_back(std::move(up));
+            });
+
+        std::sort(sorted.begin(),
+                  sorted.end(),
+                  [](const skills::SkillStatusUpdate& a, const skills::SkillStatusUpdate& b)
+                  { return b < a; });
+
+        for (const auto& el : sorted)
+        {
+            if (ret.size() >= (size_t)n)
+            {
+                break;
+            }
+
+            ret.emplace(
+                std::piecewise_construct, std::make_tuple(el.executionId), std::make_tuple(el));
+        }
+
+        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 7d67fc2d6..492c26090 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h
@@ -9,6 +9,7 @@
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
 #include <RobotAPI/interface/skills/SkillProviderInterface.h>
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 namespace armarx::skills::segment
 {
@@ -24,8 +25,9 @@ namespace armarx::skills::segment
         void defineProperties(PropertyDefinitionsPtr defs, const std::string& prefix);
         void init();
 
-        void addSkillUpdateEvent(const skills::provider::dto::SkillStatusUpdate& update,
-                                 const std::string& providerName);
+        void addSkillUpdateEvent(const skills::SkillStatusUpdate& update);
+
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> getLatestSkillEvents(int n);
 
     private:
     };
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp
index 818f3d13b..4b57e0b44 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp
@@ -1,33 +1,36 @@
 #include "SkillExecutionRequestSegment.h"
 
-#include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 #include <SimoxUtility/algorithm/string.h>
 
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-
+#include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
-
+#include <RobotAPI/libraries/armem_skills/aron_conversions.h>
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 
 namespace armarx::skills::segment
 {
 
-    SkillExecutionRequestCoreSegment::SkillExecutionRequestCoreSegment(armem::server::MemoryToIceAdapter& iceMemory):
+    SkillExecutionRequestCoreSegment::SkillExecutionRequestCoreSegment(
+        armem::server::MemoryToIceAdapter& iceMemory) :
         Base(iceMemory, CoreSegmentName, skills::arondto::SkillExecutionRequest::ToAronType())
     {
     }
 
-    void SkillExecutionRequestCoreSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix)
+    void
+    SkillExecutionRequestCoreSegment::defineProperties(PropertyDefinitionsPtr defs,
+                                                       const std::string& prefix)
     {
         // No properties! (meaning no name and no max size)
     }
 
-    void SkillExecutionRequestCoreSegment::init()
+    void
+    SkillExecutionRequestCoreSegment::init()
     {
         Base::init();
     }
 
-
-    skills::manager::dto::SkillExecutionRequest SkillExecutionRequestCoreSegment::convertCommit(const aron::data::dto::DictPtr& commitData)
+    skills::SkillExecutionRequest
+    SkillExecutionRequestCoreSegment::convertCommit(const aron::data::dto::DictPtr& commitData)
     {
         // convert ice commitData to aron
         auto commitDataAron = std::make_shared<aron::data::Dict>(commitData);
@@ -36,23 +39,20 @@ namespace armarx::skills::segment
         skills::arondto::SkillExecutionRequest request;
         request.fromAron(commitDataAron);
 
-        skills::manager::dto::SkillExecutionRequest info;
-        info.skillId = {request.providerName, request.skillName};
-        info.params = request.params->toAronDictDTO();
+        skills::SkillExecutionRequest info({{""}, ""}, "", nullptr);
+        armem::fromAron(request, info);
         return info;
     }
 
-
-    void SkillExecutionRequestCoreSegment::addSkillExecutionRequest(const skills::manager::dto::SkillExecutionRequest& info)
+    void
+    SkillExecutionRequestCoreSegment::addSkillExecutionRequest(
+        const skills::SkillExecutionRequest& info)
     {
         // override directly execution to add a request to the memory
         armem::Commit comm;
 
         skills::arondto::SkillExecutionRequest request;
-        request.executorName = info.executorName;
-        request.providerName = info.skillId.providerName;
-        request.skillName = info.skillId.skillName;
-        request.params = aron::data::Dict::FromAronDictDTO(info.params);
+        armem::toAron(request, info);
 
         auto aron = request.toAron();
 
@@ -60,11 +60,11 @@ namespace armarx::skills::segment
             auto& entityUpdate = comm.add();
 
             armem::MemoryID skillExecutionMemID = id();
-            skillExecutionMemID.providerSegmentName = request.providerName;
-            skillExecutionMemID.entityName = request.skillName;
+            skillExecutionMemID.providerSegmentName = request.skillId.providerId.providerName;
+            skillExecutionMemID.entityName = request.skillId.skillName;
 
             entityUpdate.entityID = skillExecutionMemID;
-            entityUpdate.instancesData = { aron };
+            entityUpdate.instancesData = {aron};
             entityUpdate.confidence = 1.0;
             entityUpdate.referencedTime = armem::Time::Now();
         }
@@ -77,7 +77,7 @@ namespace armarx::skills::segment
             skillExecutionMemID.entityName = "All Skill Execution Requests";
 
             entityUpdate.entityID = skillExecutionMemID;
-            entityUpdate.instancesData = { aron };
+            entityUpdate.instancesData = {aron};
             entityUpdate.confidence = 1.0;
             entityUpdate.referencedTime = armem::Time::Now();
         }
@@ -85,4 +85,4 @@ namespace armarx::skills::segment
 
         iceMemory.commit(comm);
     }
-}
+} // namespace armarx::skills::segment
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h
index 262bc829b..c5af9dd8a 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h
@@ -4,17 +4,17 @@
 #include <RobotAPI/libraries/armem/server/segment/SpecializedSegment.h>
 
 // ArmarX
+#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 #include <ArmarXCore/interface/core/Profiler.h>
 #include <ArmarXCore/observers/ObserverObjectFactories.h>
-#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
 #include <RobotAPI/interface/skills/SkillProviderInterface.h>
+#include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
 
 namespace armarx::skills::segment
 {
-    class SkillExecutionRequestCoreSegment :
-        public armem::server::segment::SpecializedCoreSegment
+    class SkillExecutionRequestCoreSegment : public armem::server::segment::SpecializedCoreSegment
     {
         using Base = armem::server::segment::SpecializedCoreSegment;
 
@@ -23,11 +23,11 @@ namespace armarx::skills::segment
 
         SkillExecutionRequestCoreSegment(armem::server::MemoryToIceAdapter& iceMemory);
 
-        void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix);
+        void defineProperties(PropertyDefinitionsPtr defs, const std::string& prefix);
         void init();
 
-        skills::manager::dto::SkillExecutionRequest convertCommit(const aron::data::dto::DictPtr& commitData);
+        skills::SkillExecutionRequest convertCommit(const aron::data::dto::DictPtr& commitData);
 
-        void addSkillExecutionRequest(const skills::manager::dto::SkillExecutionRequest& info);
+        void addSkillExecutionRequest(const skills::SkillExecutionRequest& info);
     };
-}
+} // namespace armarx::skills::segment
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
index bed880399..1d85a7f80 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
@@ -347,65 +347,68 @@ namespace armarx::aron::data
             {
                 ARMARX_TRACE;
                 auto objectTypeNav = type::Object::DynamicCastAndCheck(type);
-                for (const auto& [key, nav] : childrenNavigators)
+
+                // here we need to iterate over the elements of the type. That must be fulfilled.
+                // If this dict has more members that its fine.
+                for (const auto& [key, childTypeNav] : objectTypeNav->getMemberTypes())
                 {
-                    if (!objectTypeNav->hasMemberType(key))
+                    if (!this->hasElement(key))
                     {
-                        ARMARX_TRACE;
-                        return false;
+                        return false; // key must exist
                     }
 
-                    auto childTypeNav = objectTypeNav->getMemberType(key);
-                    if (!nav)
+                    if (!childTypeNav)
                     {
-                        ARMARX_TRACE;
-                        if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
+                        continue; // no information whih is fine --> continue
+                    }
+
+                    auto childNav = this->getElement(key);
+                    if (childNav)
+                    {
+                        if (not childNav->fullfillsType(childTypeNav))
                         {
-                            ARMARX_TRACE;
                             return false;
                         }
-                        ARMARX_TRACE;
-                        return true;
+                        // else childnav fulfills type which is fine --> continue
+                        continue;
                     }
-                    if (!nav->fullfillsType(childTypeNav))
+                    else
                     {
-                        ARMARX_TRACE;
-                        return false;
+                        if (childTypeNav->getMaybe() == type::Maybe::NONE)
+                        {
+                            return false;
+                        }
+                        // else: childTypeNav == maybe && nav == null which is fine --> continue
+                        continue;
                     }
                 }
-                ARMARX_TRACE;
                 return true;
             }
             case type::Descriptor::DICT:
             {
                 ARMARX_TRACE;
                 auto dictTypeNav = type::Dict::DynamicCastAndCheck(type);
-                for (const auto& [key, nav] : childrenNavigators)
+                for (const auto& [key, childNav] : childrenNavigators)
                 {
                     (void)key;
                     auto childTypeNav = dictTypeNav->getAcceptedType();
-                    if (!nav)
+                    if (!childNav)
                     {
-                        ARMARX_TRACE;
                         if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
                         {
-                            ARMARX_TRACE;
                             return false;
                         }
-                        ARMARX_TRACE;
-                        return true;
+                        // else childTypeNav is null or maybe and childNav is null which is fine.
+                        continue;
                     }
-                    if (!nav->fullfillsType(childTypeNav))
+                    if (!childNav->fullfillsType(childTypeNav))
                     {
-                        ARMARX_TRACE;
                         return false;
                     }
                 }
-                ARMARX_TRACE;
                 return true;
             }
             default:
-                ARMARX_TRACE;
                 return false;
         }
     }
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
index 83e23f76f..82955eabf 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
@@ -271,59 +271,51 @@ namespace armarx::aron::data
                     {
                         if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
                         {
-                            ARMARX_TRACE;
                             return false;
                         }
-                        ARMARX_TRACE;
-                        return true;
+                        continue;
                     }
                     if (!nav->fullfillsType(childTypeNav))
                     {
-                        ARMARX_TRACE;
                         return false;
                     }
                 }
-                ARMARX_TRACE;
                 return true;
             }
             case type::Descriptor::TUPLE:
             {
+                ARMARX_TRACE;
                 auto tupleTypeNav = type::Tuple::DynamicCastAndCheck(type);
                 unsigned int i = 0;
-                for (const auto& nav : childrenNavigators)
+                for (const auto& childTypeNav : tupleTypeNav->getAcceptedTypes())
                 {
-                    if (!tupleTypeNav->hasAcceptedType(i))
+                    if (!this->hasElement(i))
                     {
-                        ARMARX_TRACE;
                         return false;
                     }
 
-                    auto childTypeNav = tupleTypeNav->getAcceptedType(i);
-                    if (!nav)
+                    auto childNav = this->getElement(i);
+                    if (!childNav)
                     {
                         if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
                         {
-                            ARMARX_TRACE;
                             return false;
                         }
-                        ARMARX_TRACE;
-                        return false;
+                        continue;
                     }
-                    if (!nav->fullfillsType(tupleTypeNav->getAcceptedType(i)))
+                    if (!childNav->fullfillsType(tupleTypeNav->getAcceptedType(i)))
                     {
-                        ARMARX_TRACE;
                         return false;
                     }
                 }
-                ARMARX_TRACE;
                 return true;
             }
             case type::Descriptor::PAIR:
             {
+                ARMARX_TRACE;
                 auto pairTypeNav = type::Pair::DynamicCastAndCheck(type);
                 if (childrenSize() != 2)
                 {
-                    ARMARX_TRACE;
                     return false;
                 }
                 auto firstChildTypeNav = pairTypeNav->getFirstAcceptedType();
@@ -331,24 +323,17 @@ namespace armarx::aron::data
                 {
                     if (firstChildTypeNav && firstChildTypeNav->getMaybe() == type::Maybe::NONE)
                     {
-                        ARMARX_TRACE;
                         return false;
                     }
-                    ARMARX_TRACE;
-                    return false;
                 }
                 auto secondChildTypeNav = pairTypeNav->getSecondAcceptedType();
                 if (!childrenNavigators[1])
                 {
                     if (secondChildTypeNav && secondChildTypeNav->getMaybe() == type::Maybe::NONE)
                     {
-                        ARMARX_TRACE;
                         return false;
                     }
-                    ARMARX_TRACE;
-                    return false;
                 }
-                ARMARX_TRACE;
                 return childrenNavigators[0]->fullfillsType(firstChildTypeNav) &&
                        childrenNavigators[1]->fullfillsType(secondChildTypeNav);
             }
diff --git a/source/RobotAPI/libraries/skills/core/ProviderID.cpp b/source/RobotAPI/libraries/skills/core/ProviderID.cpp
index c347dcf2f..83330c897 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderID.cpp
+++ b/source/RobotAPI/libraries/skills/core/ProviderID.cpp
@@ -1,5 +1,7 @@
 #include "ProviderID.h"
 
+#include "SkillID.h"
+
 namespace armarx
 {
     namespace skills
@@ -8,8 +10,10 @@ namespace armarx
         {
         }
 
-        ProviderID::ProviderID(const skills::SkillID& skillid) : providerName(skillid.providerName)
+        ProviderID::ProviderID(const skills::SkillID& skillid)
         {
+            ARMARX_CHECK(skillid.providerId.has_value());
+            providerName = skillid.providerId->providerName;
         }
 
         bool
@@ -37,7 +41,7 @@ namespace armarx
         }
 
         ProviderID
-        ProviderID::FromIce(const provider::dto::ProviderID& s)
+        ProviderID::FromIce(const callback::dto::ProviderID& s)
         {
             return ProviderID(s.providerName);
         }
@@ -48,8 +52,8 @@ namespace armarx
             return {providerName};
         }
 
-        provider::dto::ProviderID
-        ProviderID::toProviderIce() const
+        callback::dto::ProviderID
+        ProviderID::toCallbackIce() const
         {
             return {providerName};
         }
diff --git a/source/RobotAPI/libraries/skills/core/ProviderID.h b/source/RobotAPI/libraries/skills/core/ProviderID.h
index 7aee01fd7..0e0159d9d 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderID.h
+++ b/source/RobotAPI/libraries/skills/core/ProviderID.h
@@ -6,12 +6,12 @@
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
 #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
 
-#include "SkillID.h"
-
 namespace armarx
 {
     namespace skills
     {
+        class SkillID;
+
         class ProviderID
         {
         public:
@@ -28,10 +28,10 @@ namespace armarx
             bool operator<(const ProviderID& other) const;
 
             manager::dto::ProviderID toManagerIce() const;
-            provider::dto::ProviderID toProviderIce() const;
+            callback::dto::ProviderID toCallbackIce() const;
 
             static ProviderID FromIce(const manager::dto::ProviderID&);
-            static ProviderID FromIce(const provider::dto::ProviderID&);
+            static ProviderID FromIce(const callback::dto::ProviderID&);
 
             std::string toString(const std::string& prefix = "") const;
         };
diff --git a/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp b/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
index ec12cb9ae..7ae36dbfa 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
+++ b/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
@@ -7,20 +7,33 @@ namespace armarx
         ProviderInfo::ProviderInfo(const ProviderID& pid,
                                    const provider::dti::SkillProviderInterfacePrx& i,
                                    const std::map<SkillID, SkillDescription>& skills) :
-            providerId(pid), provider(i), providedSkills(skills)
+            providerId(pid), providerInterface(i), providedSkills(skills)
         {
         }
 
+        skills::manager::dto::ProviderInfo
+        ProviderInfo::toIce() const
+        {
+            skills::manager::dto::ProviderInfo ret;
+            ret.providerId = providerId.toManagerIce();
+            ret.providerInterface = providerInterface;
+
+            for (const auto& [k, v] : providedSkills)
+            {
+                ret.providedSkills[k.toManagerIce()] = v.toManagerIce();
+            }
+            return ret;
+        }
+
         ProviderInfo
         ProviderInfo::FromIce(const manager::dto::ProviderInfo& i)
         {
             std::map<SkillID, SkillDescription> m;
             for (const auto& [k, v] : i.providedSkills)
             {
-                m.insert({skills::SkillID::FromIce(k, i.providerId.providerName),
-                          skills::SkillDescription::FromIce(v)});
+                m.insert({skills::SkillID::FromIce(k), skills::SkillDescription::FromIce(v)});
             }
-            return ProviderInfo(skills::ProviderID::FromIce(i.providerId), i.provider, 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 2213d1615..92c5484c3 100644
--- a/source/RobotAPI/libraries/skills/core/ProviderInfo.h
+++ b/source/RobotAPI/libraries/skills/core/ProviderInfo.h
@@ -20,7 +20,7 @@ namespace armarx
         {
         public:
             ProviderID providerId;
-            provider::dti::SkillProviderInterfacePrx provider;
+            provider::dti::SkillProviderInterfacePrx providerInterface;
             std::map<SkillID, SkillDescription> providedSkills;
 
             ProviderInfo() = delete;
@@ -28,6 +28,8 @@ namespace armarx
                          const provider::dti::SkillProviderInterfacePrx& i,
                          const std::map<SkillID, SkillDescription>& skills);
 
+            skills::manager::dto::ProviderInfo toIce() const;
+
             static ProviderInfo FromIce(const manager::dto::ProviderInfo&);
         };
     } // namespace skills
diff --git a/source/RobotAPI/libraries/skills/core/Skill.cpp b/source/RobotAPI/libraries/skills/core/Skill.cpp
index e104ef656..19169d627 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.cpp
+++ b/source/RobotAPI/libraries/skills/core/Skill.cpp
@@ -18,7 +18,7 @@ namespace armarx
             conditionCallbacks.push_back({f, cb});
         }
 
-        void
+        Skill::InitResult
         Skill::_init()
         {
             //ARMARX_IMPORTANT << "Initializing skill '" << description.skillName << "'";
@@ -61,21 +61,41 @@ namespace armarx
                         }
                     }
                 });
+            return {.status = TerminatedSkillStatus::Succeeded};
         }
 
-        void
+        Skill::PrepareResult
         Skill::_prepare()
         {
-            // Nothing here yet...
+            if (checkWhetherSkillShouldStopASAP())
+            {
+                return {.status = ActiveOrTerminatedSkillStatus::Aborted};
+            }
+
+            // Default nothing to prepare
+            std::scoped_lock l(parametersMutex);
+            if (not description.acceptedType)
+            {
+                return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
+            }
+            if (this->parameters && this->parameters->fullfillsType(description.acceptedType))
+            {
+                // wait until parameters fulfill type
+                return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
+            }
+
+            // false if we have to wait for parameters
+            return {.status = ActiveOrTerminatedSkillStatus::Running};
         }
 
-        void
+        Skill::MainResult
         Skill::_main()
         {
             // Nothing here yet...
+            return {.status = TerminatedSkillStatus::Succeeded};
         }
 
-        void
+        Skill::ExitResult
         Skill::_exit()
         {
             // ARMARX_IMPORTANT << "Exiting Skill '" << description.skillName << "'";
@@ -86,41 +106,39 @@ namespace armarx
                 conditionCheckingThread.join();
             }
             exited = armarx::core::time::DateTime::Now();
+            return {.status = TerminatedSkillStatus::Succeeded};
         }
 
         Skill::InitResult
         Skill::initSkill()
         {
-            this->_init();
-            return this->init();
-        }
-
-        bool
-        Skill::skillPreparationFinished() const
-        {
-            return this->preparationFinished();
+            auto _res = this->_init();
+            auto res = this->init();
+            return {.status = skills::MergeSkillStatus(_res.status, res.status)};
         }
 
         Skill::PrepareResult
         Skill::prepareSkill()
         {
-            this->_prepare();
-            return this->prepare();
+            auto _res = this->_prepare();
+            auto res = this->prepare();
+            return {.status = skills::MergeSkillStatus(_res.status, res.status)};
         }
 
         Skill::MainResult
         Skill::mainOfSkill()
         {
-            this->_main();
-            return this->main();
+            auto _res = this->_main();
+            auto res = this->main();
+            return {.status = skills::MergeSkillStatus(_res.status, res.status), .data = res.data};
         }
 
         Skill::ExitResult
         Skill::exitSkill()
         {
-            auto ret = this->exit();
-            this->_exit();
-            return ret;
+            auto res = this->exit();
+            auto _res = this->_exit();
+            return {.status = skills::MergeSkillStatus(_res.status, res.status)};
         }
 
         void
@@ -171,26 +189,6 @@ namespace armarx
             return {.status = TerminatedSkillStatus::Succeeded};
         }
 
-        bool
-        Skill::preparationFinished() const
-        {
-            std::scoped_lock l(parametersMutex);
-            if (description.acceptedType != nullptr)
-            {
-                if (this->parameters != nullptr)
-                {
-                    // wait until parameters fulfill type
-                    return this->parameters->fullfillsType(description.acceptedType);
-                }
-
-                // false if we have to wait for parameters
-                return false;
-            }
-
-            // always true if no type set.
-            return true;
-        }
-
         // always called before main (should not take longer than 100ms)
         Skill::PrepareResult
         Skill::prepare()
diff --git a/source/RobotAPI/libraries/skills/core/Skill.h b/source/RobotAPI/libraries/skills/core/Skill.h
index 30f1f666e..bc7402a97 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.h
+++ b/source/RobotAPI/libraries/skills/core/Skill.h
@@ -60,12 +60,22 @@ namespace armarx
             SkillID
             getSkillId() const
             {
-                return {providerName, description.skillId.providerName};
+                return description.skillId;
             }
 
-            PrepareResult prepareSkill();
+            SkillDescription
+            getSkillDescription() const
+            {
+                return description;
+            }
+
+            void
+            setProviderId(const skills::ProviderID& pid)
+            {
+                description.skillId.providerId = pid;
+            }
 
-            bool skillPreparationFinished() const;
+            PrepareResult prepareSkill();
 
             InitResult initSkill();
 
@@ -95,6 +105,14 @@ namespace armarx
                 }
             }
 
+            // 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;
+            }
+
             // get the parameters
             aron::data::DictPtr
             getParameters() const
@@ -110,27 +128,24 @@ namespace armarx
             void notifyTimeoutReached();
 
             // helper methods to do all the static initialization stuff
-            void _init();
-            void _prepare();
-            void _main();
-            void _exit();
+            InitResult _init();
+            PrepareResult _prepare();
+            MainResult _main();
+            ExitResult _exit();
 
-        private:
             /// Override this method with the actual implementation.
             virtual InitResult init();
 
             /// Override this method with the actual implementation.
             virtual PrepareResult prepare();
 
-            /// Override this method with the actual implementation
-            virtual bool preparationFinished() const;
-
             /// Override this method with the actual implementation. The callback is for status updates to the calling instance
             virtual MainResult main();
 
             /// Override this method with the actual implementation.
             virtual ExitResult exit();
 
+        private:
             /// Override these methods if you want to do something special when notification comes
             virtual void onTimeoutReached();
             virtual void onStopRequested();
@@ -141,25 +156,24 @@ namespace armarx
                                               std::function<void()>&& cb);
 
         public:
-            // The descripion of the skill, which will be available via the provider/manager
-            const SkillDescription description;
-
             // running params
             armarx::core::time::DateTime started = armarx::core::time::DateTime::Invalid();
             armarx::core::time::DateTime exited = armarx::core::time::DateTime::Invalid();
 
             // parameterization.Will be set from implementation wrapper.
-            // const params after initialization
+            // const params after initialization!!
             std::function<void(const SkillStatus s, const armarx::aron::data::DictPtr&)> callback;
             manager::dti::SkillManagerInterfacePrx manager = nullptr;
-            std::string providerName = "INVALID PROVIDER NAME";
             std::string executorName = "INVALID EXECUTOR NAME";
 
+        protected:
             // non-const params
             mutable std::mutex parametersMutex;
             armarx::aron::data::DictPtr parameters;
 
-        protected:
+            // 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;
diff --git a/source/RobotAPI/libraries/skills/core/SkillDescription.cpp b/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
index fb5f6f062..d8e7885a0 100644
--- a/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
@@ -32,20 +32,47 @@ namespace armarx
         }
 
         provider::dto::SkillDescription
-        SkillDescription::toIce() const
+        SkillDescription::toProviderIce() const
         {
             provider::dto::SkillDescription ret;
             ret.acceptedType = aron::type::Object::ToAronObjectDTO(acceptedType);
             ret.description = description;
             ret.skillId = skillId.toProviderIce();
-            ret.rootProfileDefaults = rootProfileParameterization->toAronDictDTO();
+            ret.rootProfileDefaults = aron::data::Dict::ToAronDictDTO(rootProfileParameterization);
 
             armarx::core::time::toIce(ret.timeout, timeout);
             return ret;
         }
 
+        manager::dto::SkillDescription
+        SkillDescription::toManagerIce() const
+        {
+            manager::dto::SkillDescription ret;
+            ret.acceptedType = aron::type::Object::ToAronObjectDTO(acceptedType);
+            ret.description = description;
+            ret.skillId = skillId.toManagerIce();
+            ret.rootProfileDefaults = aron::data::Dict::ToAronDictDTO(rootProfileParameterization);
+
+            armarx::core::time::toIce(ret.timeout, timeout);
+            return ret;
+        }
+
+        SkillDescription
+        SkillDescription::FromIce(const provider::dto::SkillDescription& i,
+                                  const std::optional<ProviderID>& pid)
+        {
+            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));
+        }
+
         SkillDescription
-        SkillDescription::FromIce(const provider::dto::SkillDescription& i)
+        SkillDescription::FromIce(const manager::dto::SkillDescription& i)
         {
             armarx::core::time::Duration _d;
             armarx::core::time::fromIce(i.timeout, _d);
diff --git a/source/RobotAPI/libraries/skills/core/SkillDescription.h b/source/RobotAPI/libraries/skills/core/SkillDescription.h
index e1e5b4fcf..1fc370e2c 100644
--- a/source/RobotAPI/libraries/skills/core/SkillDescription.h
+++ b/source/RobotAPI/libraries/skills/core/SkillDescription.h
@@ -30,6 +30,7 @@ namespace armarx
         struct SkillDescription
         {
             SkillDescription() = delete;
+            SkillDescription(const SkillDescription&) = default;
             SkillDescription(const SkillID& id,
                              const std::string& desc,
                              const aron::data::DictPtr& data = nullptr,
@@ -37,6 +38,7 @@ namespace armarx
                                  armarx::core::time::Duration::MilliSeconds(-1),
                              const aron::type::ObjectPtr& acceptedType = nullptr);
 
+            SkillDescription& operator=(const SkillDescription&) = default;
 
             SkillID skillId;
             std::string description;
@@ -44,9 +46,15 @@ namespace armarx
             armarx::core::time::Duration timeout;
             aron::type::ObjectPtr acceptedType;
 
-            provider::dto::SkillDescription toIce() const;
+            provider::dto::SkillDescription toProviderIce() const;
+            manager::dto::SkillDescription toManagerIce() const;
 
-            static SkillDescription FromIce(const provider::dto::SkillDescription& i);
+            static SkillDescription FromIce(const provider::dto::SkillDescription& i,
+                                            const std::optional<ProviderID>& = std::nullopt);
+            static SkillDescription FromIce(const manager::dto::SkillDescription& i);
         };
+
+        template <class T>
+        concept isSkillDescription = std::is_base_of<SkillDescription, T>::value;
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp b/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
index 3efb06d9e..f048167a1 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
@@ -4,7 +4,7 @@ namespace armarx
 {
     namespace skills
     {
-        SkillExecutionId::SkillExecutionId(const SkillID& id,
+        SkillExecutionID::SkillExecutionID(const SkillID& id,
                                            const std::string& executorName,
                                            const armarx::core::time::DateTime& time) :
             skillId(id), executorName(executorName), executionStartedTime(time)
@@ -12,18 +12,17 @@ namespace armarx
         }
 
         skills::manager::dto::SkillExecutionID
-        SkillExecutionId::toManagerIce() const
+        SkillExecutionID::toManagerIce() const
         {
             skills::manager::dto::SkillExecutionID ret;
-            ret.skillId.skillName = skillId.skillName;
-            ret.skillId.providerName = skillId.providerName;
+            ret.skillId = skillId.toManagerIce();
             ret.executorName = executorName;
             armarx::core::time::toIce(ret.executionStartedTime, executionStartedTime);
             return ret;
         }
 
         skills::provider::dto::SkillExecutionID
-        SkillExecutionId::toProviderIce() const
+        SkillExecutionID::toProviderIce() const
         {
             skills::provider::dto::SkillExecutionID ret;
             ret.skillId = skillId.toProviderIce();
@@ -32,17 +31,17 @@ namespace armarx
             return ret;
         }
 
-        SkillExecutionId
-        SkillExecutionId::FromIce(const skills::manager::dto::SkillExecutionID& i)
+        SkillExecutionID
+        SkillExecutionID::FromIce(const skills::manager::dto::SkillExecutionID& i)
         {
             armarx::core::time::DateTime t;
             armarx::core::time::fromIce(i.executionStartedTime, t);
             return {skills::SkillID::FromIce(i.skillId), i.executorName, t};
         }
 
-        SkillExecutionId
-        SkillExecutionId::FromIce(const skills::provider::dto::SkillExecutionID& i,
-                                  const std::string& providerName)
+        SkillExecutionID
+        SkillExecutionID::FromIce(const skills::provider::dto::SkillExecutionID& i,
+                                  const std::optional<skills::ProviderID>& providerName)
         {
             armarx::core::time::DateTime t;
             armarx::core::time::fromIce(i.executionStartedTime, t);
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionID.h b/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
index 356aec611..7ba3ea987 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
@@ -16,19 +16,19 @@ namespace armarx
 {
     namespace skills
     {
-        struct SkillExecutionId
+        struct SkillExecutionID
         {
             SkillID skillId;
             std::string executorName;
             armarx::core::time::DateTime executionStartedTime;
 
-            SkillExecutionId() = delete;
-            SkillExecutionId(const SkillID&,
+            SkillExecutionID() = delete;
+            SkillExecutionID(const SkillID&,
                              const std::string& executorName,
                              const armarx::core::time::DateTime&);
 
             bool
-            operator==(const SkillExecutionId& other) const
+            operator==(const SkillExecutionID& other) const
             {
                 if (skillId != other.skillId)
                 {
@@ -46,7 +46,7 @@ namespace armarx
             }
 
             bool
-            operator<(const SkillExecutionId& other) const
+            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;
@@ -56,10 +56,10 @@ namespace armarx
 
             skills::provider::dto::SkillExecutionID toProviderIce() const;
 
-            static SkillExecutionId FromIce(const skills::manager::dto::SkillExecutionID&);
+            static SkillExecutionID FromIce(const skills::manager::dto::SkillExecutionID&);
 
-            static SkillExecutionId FromIce(const skills::provider::dto::SkillExecutionID&,
-                                            const std::string& providerName);
+            static SkillExecutionID FromIce(const skills::provider::dto::SkillExecutionID&,
+                                            const std::optional<skills::ProviderID>& providerName);
         };
 
     } // namespace skills
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
index d045cc239..91fca69ca 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
@@ -19,7 +19,7 @@ namespace armarx
             manager::dto::SkillExecutionRequest ret;
             ret.skillId = skillId.toManagerIce();
             ret.executorName = executorName;
-            ret.params = params->toAronDictDTO();
+            ret.params = armarx::aron::data::Dict::ToAronDictDTO(params);
             return ret;
         }
 
@@ -29,7 +29,7 @@ namespace armarx
             provider::dto::SkillExecutionRequest ret;
             ret.skillId = skillId.toProviderIce();
             ret.executorName = executorName;
-            ret.params = params->toAronDictDTO();
+            ret.params = armarx::aron::data::Dict::ToAronDictDTO(params);
             ret.callbackInterface = callbackInterface;
             return ret;
         }
@@ -44,9 +44,10 @@ namespace armarx
         }
 
         SkillExecutionRequest
-        SkillExecutionRequest::FromIce(const provider::dto::SkillExecutionRequest& req)
+        SkillExecutionRequest::FromIce(const provider::dto::SkillExecutionRequest& req,
+                                       const std::optional<skills::ProviderID>& providerId)
         {
-            return {skills::SkillID::FromIce(req.skillId),
+            return {skills::SkillID::FromIce(req.skillId, providerId),
                     req.executorName,
                     armarx::aron::data::Dict::FromAronDictDTO(req.params),
                     req.callbackInterface};
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
index ec39e2f44..9eaa00791 100644
--- a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
@@ -27,17 +27,19 @@ namespace armarx
             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);
+            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;
 
             static SkillExecutionRequest FromIce(const manager::dto::SkillExecutionRequest&);
             static SkillExecutionRequest
-            FromIce(const provider::dto::SkillExecutionRequest&);
+            FromIce(const provider::dto::SkillExecutionRequest&,
+                    const std::optional<skills::ProviderID>& providerId = std::nullopt);
         };
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillID.cpp b/source/RobotAPI/libraries/skills/core/SkillID.cpp
index 80373376a..9bb0b36a8 100644
--- a/source/RobotAPI/libraries/skills/core/SkillID.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillID.cpp
@@ -4,14 +4,15 @@ namespace armarx
 {
     namespace skills
     {
-        SkillID::SkillID(const std::string& skillName) : SkillID(NOT_YET_KNOWN, skillName)
+        SkillID::SkillID(const std::string& skillName) :
+            providerId(std::nullopt), skillName(skillName)
         {
         }
 
-        SkillID::SkillID(const std::string& providerName, const std::string& skillName) :
-            providerName(providerName), skillName(skillName)
+        SkillID::SkillID(const ProviderID& providerId, const std::string& skillName) :
+            providerId(providerId), skillName(skillName)
         {
-            if (simox::alg::contains(providerName, NAME_SEPARATOR) ||
+            if (simox::alg::contains(providerId.providerName, NAME_SEPARATOR) ||
                 simox::alg::contains(skillName, NAME_SEPARATOR))
             {
                 throw error::SkillException(
@@ -20,7 +21,7 @@ namespace armarx
                         NAME_SEPARATOR + "'.");
             }
 
-            if (simox::alg::contains(providerName, PREFIX_SEPARATOR) ||
+            if (simox::alg::contains(providerId.providerName, PREFIX_SEPARATOR) ||
                 simox::alg::contains(skillName, PREFIX_SEPARATOR))
             {
                 throw error::SkillException(
@@ -33,7 +34,7 @@ namespace armarx
         bool
         SkillID::operator==(const SkillID& other) const
         {
-            return providerName == other.providerName && skillName == other.skillName;
+            return providerId == other.providerId && skillName == other.skillName;
         }
 
         bool
@@ -51,19 +52,25 @@ namespace armarx
         SkillID
         SkillID::FromIce(const manager::dto::SkillID& s)
         {
-            return SkillID(s.providerName, s.skillName);
+            return SkillID(s.providerId.providerName, s.skillName);
         }
 
         SkillID
-        SkillID::FromIce(const provider::dto::SkillID& s, const std::string& providerName)
+        SkillID::FromIce(const provider::dto::SkillID& s,
+                         const std::optional<ProviderID>& providerId)
         {
-            return SkillID(providerName, s.skillName);
+            if (providerId.has_value())
+            {
+                return SkillID(*providerId, s.skillName);
+            }
+            return SkillID(s.skillName);
         }
 
         manager::dto::SkillID
         SkillID::toManagerIce() const
         {
-            return {providerName, skillName};
+            ARMARX_CHECK(fullySpecified());
+            return {providerId->toManagerIce(), skillName};
         }
 
         provider::dto::SkillID
@@ -75,7 +82,12 @@ namespace armarx
         std::string
         SkillID::toString(const std::string& prefix) const
         {
-            return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) + providerName +
+            if (providerId.has_value())
+            {
+                return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) +
+                       providerId->providerName + NAME_SEPARATOR + skillName;
+            }
+            return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) + UNKNOWN +
                    NAME_SEPARATOR + skillName;
         }
     } // namespace skills
diff --git a/source/RobotAPI/libraries/skills/core/SkillID.h b/source/RobotAPI/libraries/skills/core/SkillID.h
index a65765f0c..39561595d 100644
--- a/source/RobotAPI/libraries/skills/core/SkillID.h
+++ b/source/RobotAPI/libraries/skills/core/SkillID.h
@@ -7,6 +7,7 @@
 
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
 
+#include "ProviderID.h"
 #include "error/Exception.h"
 
 namespace armarx
@@ -18,25 +19,47 @@ namespace armarx
         public:
             static const constexpr char* PREFIX_SEPARATOR = "->";
             static const constexpr char* NAME_SEPARATOR = "/";
-            static const constexpr char* NOT_YET_KNOWN = "NOT YET KNOWN";
+            static const constexpr char* UNKNOWN = "UNKNOWN";
 
-            std::string providerName;
+            std::optional<ProviderID> providerId;
             std::string skillName;
 
             SkillID() = delete;
             SkillID(const std::string& skillName);
-            SkillID(const std::string& providerName, 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
+            fullySpecified() const
+            {
+                return skillSpecified() && providerSpecified();
+            }
+
+            bool
+            skillSpecified() const
+            {
+                return skillName != UNKNOWN;
+            }
+
+            bool
+            providerSpecified() const
+            {
+                if (not providerId.has_value())
+                {
+                    return false;
+                }
+                return providerId->providerName != UNKNOWN;
+            }
+
             manager::dto::SkillID toManagerIce() const;
             provider::dto::SkillID toProviderIce() const;
 
             static SkillID FromIce(const manager::dto::SkillID&);
             static SkillID FromIce(const provider::dto::SkillID&,
-                                           const std::string& providerName = NOT_YET_KNOWN);
+                                   const std::optional<ProviderID>& providerId = std::nullopt);
 
             std::string toString(const std::string& prefix = "") const;
         };
diff --git a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
index df5950ac3..36ac32ed7 100644
--- a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
@@ -36,95 +36,142 @@ namespace armarx
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
+        TerminatedSkillStatus
+        MergeSkillStatus(const TerminatedSkillStatus t1, const TerminatedSkillStatus t2)
+        {
+            // if both are equal
+            if (t1 == t2)
+            {
+                return t1;
+            }
+
+            // if one is failed (most unspecific result)
+            if (t1 == TerminatedSkillStatus::Failed or t2 == TerminatedSkillStatus::Failed)
+            {
+                return TerminatedSkillStatus::Failed;
+            }
+
+            // else one must be aborted and the other one must be succeeded
+            return TerminatedSkillStatus::Aborted;
+        }
+
+        ActiveOrTerminatedSkillStatus
+        MergeSkillStatus(const ActiveOrTerminatedSkillStatus t1,
+                         const ActiveOrTerminatedSkillStatus t2)
+        {
+            // if both are equal
+            if (t1 == t2)
+            {
+                return t1;
+            }
+
+            // if one is failed (most unspecific result)
+            if (t1 == ActiveOrTerminatedSkillStatus::Failed or
+                t2 == ActiveOrTerminatedSkillStatus::Failed)
+            {
+                return ActiveOrTerminatedSkillStatus::Failed;
+            }
+
+            // if none is failed and one is aborted (second most unspecific result)
+            if (t1 == ActiveOrTerminatedSkillStatus::Aborted or
+                t2 == ActiveOrTerminatedSkillStatus::Aborted)
+            {
+                return ActiveOrTerminatedSkillStatus::Aborted;
+            }
+
+            // else one must be running and the other one must be succeeded
+            return ActiveOrTerminatedSkillStatus::Running;
+        }
+
         void
-        toIce(provider::dto::Execution::Status& ret, const SkillStatus& status)
+        toIce(core::dto::Execution::Status& ret, const SkillStatus& status)
         {
             switch (status)
             {
                 case SkillStatus::Constructing:
-                    ret = provider::dto::Execution::Status::Constructing;
+                    ret = core::dto::Execution::Status::Constructing;
                     return;
                 case SkillStatus::Initializing:
-                    ret = provider::dto::Execution::Status::Initializing;
+                    ret = core::dto::Execution::Status::Initializing;
                     return;
                 case SkillStatus::Preparing:
-                    ret = provider::dto::Execution::Status::Preparing;
+                    ret = core::dto::Execution::Status::Preparing;
                     return;
                 case SkillStatus::Running:
-                    ret = provider::dto::Execution::Status::Running;
+                    ret = core::dto::Execution::Status::Running;
                     return;
                 case SkillStatus::Failed:
-                    ret = provider::dto::Execution::Status::Failed;
+                    ret = core::dto::Execution::Status::Failed;
                     return;
                 case SkillStatus::Succeeded:
-                    ret = provider::dto::Execution::Status::Succeeded;
+                    ret = core::dto::Execution::Status::Succeeded;
                     return;
                 case SkillStatus::Aborted:
-                    ret = provider::dto::Execution::Status::Aborted;
+                    ret = core::dto::Execution::Status::Aborted;
                     return;
             }
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
         void
-        toIce(provider::dto::Execution::Status& ret, const ActiveOrTerminatedSkillStatus& status)
+        toIce(core::dto::Execution::Status& ret, const ActiveOrTerminatedSkillStatus& status)
         {
             switch (status)
             {
                 case ActiveOrTerminatedSkillStatus::Running:
-                    ret = provider::dto::Execution::Status::Running;
+                    ret = core::dto::Execution::Status::Running;
                     return;
                 case ActiveOrTerminatedSkillStatus::Failed:
-                    ret = provider::dto::Execution::Status::Failed;
+                    ret = core::dto::Execution::Status::Failed;
                     return;
                 case ActiveOrTerminatedSkillStatus::Succeeded:
-                    ret = provider::dto::Execution::Status::Succeeded;
+                    ret = core::dto::Execution::Status::Succeeded;
                     return;
                 case ActiveOrTerminatedSkillStatus::Aborted:
-                    ret = provider::dto::Execution::Status::Aborted;
+                    ret = core::dto::Execution::Status::Aborted;
                     return;
             }
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
         void
-        toIce(provider::dto::Execution::Status& ret, const TerminatedSkillStatus& status)
+        toIce(core::dto::Execution::Status& ret, const TerminatedSkillStatus& status)
         {
             switch (status)
             {
                 case TerminatedSkillStatus::Failed:
-                    ret = provider::dto::Execution::Status::Failed;
+                    ret = core::dto::Execution::Status::Failed;
                     return;
                 case TerminatedSkillStatus::Succeeded:
-                    ret = provider::dto::Execution::Status::Succeeded;
+                    ret = core::dto::Execution::Status::Succeeded;
                     return;
                 case TerminatedSkillStatus::Aborted:
-                    ret = provider::dto::Execution::Status::Aborted;
+                    ret = core::dto::Execution::Status::Aborted;
                     return;
             }
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
         void
-        fromIce(const provider::dto::Execution::Status& status, TerminatedSkillStatus& ret)
+        fromIce(const core::dto::Execution::Status& status, TerminatedSkillStatus& ret)
         {
             switch (status)
             {
-                case provider::dto::Execution::Status::Constructing:
+                case core::dto::Execution::Status::Constructing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Initializing:
+                case core::dto::Execution::Status::Initializing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Preparing:
+                case core::dto::Execution::Status::Preparing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Running:
+                case core::dto::Execution::Status::Running:
                     break;
-                case provider::dto::Execution::Status::Failed:
+                case core::dto::Execution::Status::Failed:
                     ret = TerminatedSkillStatus::Failed;
                     return;
-                case provider::dto::Execution::Status::Succeeded:
+                case core::dto::Execution::Status::Succeeded:
                     ret = TerminatedSkillStatus::Succeeded;
                     return;
-                case provider::dto::Execution::Status::Aborted:
+                case core::dto::Execution::Status::Aborted:
                     ret = TerminatedSkillStatus::Aborted;
                     return;
             }
@@ -134,26 +181,26 @@ namespace armarx
         }
 
         void
-        fromIce(const provider::dto::Execution::Status& status, ActiveOrTerminatedSkillStatus& ret)
+        fromIce(const core::dto::Execution::Status& status, ActiveOrTerminatedSkillStatus& ret)
         {
             switch (status)
             {
-                case provider::dto::Execution::Status::Constructing:
+                case core::dto::Execution::Status::Constructing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Initializing:
+                case core::dto::Execution::Status::Initializing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Preparing:
+                case core::dto::Execution::Status::Preparing:
                     break;
-                case provider::dto::Execution::Status::Running:
+                case core::dto::Execution::Status::Running:
                     ret = ActiveOrTerminatedSkillStatus::Running;
                     return;
-                case provider::dto::Execution::Status::Failed:
+                case core::dto::Execution::Status::Failed:
                     ret = ActiveOrTerminatedSkillStatus::Failed;
                     return;
-                case provider::dto::Execution::Status::Succeeded:
+                case core::dto::Execution::Status::Succeeded:
                     ret = ActiveOrTerminatedSkillStatus::Succeeded;
                     return;
-                case provider::dto::Execution::Status::Aborted:
+                case core::dto::Execution::Status::Aborted:
                     ret = ActiveOrTerminatedSkillStatus::Aborted;
                     return;
             }
@@ -163,36 +210,36 @@ namespace armarx
         }
 
         void
-        fromIce(const provider::dto::Execution::Status& status, SkillStatus& ret)
+        fromIce(const core::dto::Execution::Status& status, SkillStatus& ret)
         {
             switch (status)
             {
-                case provider::dto::Execution::Status::Constructing:
+                case core::dto::Execution::Status::Constructing:
                     ret = SkillStatus::Constructing;
                     return;
-                case provider::dto::Execution::Status::Initializing:
+                case core::dto::Execution::Status::Initializing:
                     ret = SkillStatus::Initializing;
                     return;
-                case provider::dto::Execution::Status::Preparing:
+                case core::dto::Execution::Status::Preparing:
                     ret = SkillStatus::Preparing;
                     return;
-                case provider::dto::Execution::Status::Running:
+                case core::dto::Execution::Status::Running:
                     ret = SkillStatus::Running;
                     return;
-                case provider::dto::Execution::Status::Failed:
+                case core::dto::Execution::Status::Failed:
                     ret = SkillStatus::Failed;
                     return;
-                case provider::dto::Execution::Status::Succeeded:
+                case core::dto::Execution::Status::Succeeded:
                     ret = SkillStatus::Succeeded;
                     return;
-                case provider::dto::Execution::Status::Aborted:
+                case core::dto::Execution::Status::Aborted:
                     ret = SkillStatus::Aborted;
                     return;
             }
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
-        SkillStatusUpdateBase::SkillStatusUpdateBase(const SkillExecutionId& exec,
+        SkillStatusUpdateBase::SkillStatusUpdateBase(const SkillExecutionID& exec,
                                                      const SkillParameterization& param) :
             executionId(exec), usedParameterization(param)
         {
@@ -202,13 +249,12 @@ namespace armarx
         SkillStatusUpdateBase::toManagerIce() const
         {
             manager::dto::SkillStatusUpdate ret;
-            ret.header.executionId.skillId = executionId.skillId.toManagerIce();
-            ret.header.executionId.executorName = executionId.executorName;
-            armarx::core::time::toIce(ret.header.executionId.executionStartedTime,
+            ret.executionId.skillId = executionId.skillId.toManagerIce();
+            ret.executionId.executorName = executionId.executorName;
+            armarx::core::time::toIce(ret.executionId.executionStartedTime,
                                       executionId.executionStartedTime);
-            ret.header.usedParams =
-                aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
-            ret.header.usedCallbackInterface = usedParameterization.callbackInterface;
+            ret.usedParams = aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
+            ret.usedCallbackInterface = usedParameterization.callbackInterface;
             ret.data = aron::data::Dict::ToAronDictDTO(data);
             return ret;
         }
@@ -217,13 +263,12 @@ namespace armarx
         SkillStatusUpdateBase::toProviderIce() const
         {
             provider::dto::SkillStatusUpdate ret;
-            ret.header.executionId.skillId = executionId.skillId.toProviderIce();
-            ret.header.executionId.executorName = executionId.executorName;
-            armarx::core::time::toIce(ret.header.executionId.executionStartedTime,
+            ret.executionId.skillId = executionId.skillId.toProviderIce();
+            ret.executionId.executorName = executionId.executorName;
+            armarx::core::time::toIce(ret.executionId.executionStartedTime,
                                       executionId.executionStartedTime);
-            ret.header.usedParams =
-                aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
-            ret.header.usedCallbackInterface = usedParameterization.callbackInterface;
+            ret.usedParams = aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
+            ret.usedCallbackInterface = usedParameterization.callbackInterface;
             ret.data = aron::data::Dict::ToAronDictDTO(data);
             return ret;
         }
@@ -232,7 +277,7 @@ namespace armarx
         TerminatedSkillStatusUpdate::toManagerIce() const
         {
             manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toManagerIce();
-            skills::toIce(ret.header.status, status);
+            skills::toIce(ret.status, status);
             return ret;
         }
 
@@ -240,7 +285,7 @@ namespace armarx
         TerminatedSkillStatusUpdate::toProviderIce() const
         {
             provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toProviderIce();
-            skills::toIce(ret.header.status, status);
+            skills::toIce(ret.status, status);
             return ret;
         }
 
@@ -248,7 +293,7 @@ namespace armarx
         SkillStatusUpdate::toManagerIce() const
         {
             manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toManagerIce();
-            skills::toIce(ret.header.status, status);
+            skills::toIce(ret.status, status);
             return ret;
         }
 
@@ -256,7 +301,7 @@ namespace armarx
         SkillStatusUpdate::toProviderIce() const
         {
             provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toProviderIce();
-            skills::toIce(ret.header.status, status);
+            skills::toIce(ret.status, status);
             return ret;
         }
 
@@ -264,7 +309,7 @@ namespace armarx
         ActiveOrTerminatedSkillStatusUpdate::toManagerIce() const
         {
             manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toManagerIce();
-            skills::toIce(ret.header.status, status);
+            skills::toIce(ret.status, status);
             return ret;
         }
 
@@ -272,53 +317,50 @@ namespace armarx
         ActiveOrTerminatedSkillStatusUpdate::toProviderIce() const
         {
             provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toProviderIce();
-            skills::toIce(ret.header.status, status);
+            skills::toIce(ret.status, status);
             return ret;
         }
 
         TerminatedSkillStatusUpdate
         TerminatedSkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            TerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionId::FromIce(update.header.executionId),
-                skills::SkillParameterization::FromIce(update.header.usedParams,
-                                                       update.header.usedCallbackInterface));
-            skills::fromIce(update.header.status, ret.status);
+            TerminatedSkillStatusUpdate ret(skills::SkillExecutionID::FromIce(update.executionId),
+                                            skills::SkillParameterization::FromIce(
+                                                update.usedParams, update.usedCallbackInterface));
+            skills::fromIce(update.status, ret.status);
             return ret;
         }
 
         TerminatedSkillStatusUpdate
         TerminatedSkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
-                                             const std::string& providerName)
+                                             const std::optional<skills::ProviderID>& providerId)
         {
             TerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionId::FromIce(update.header.executionId, providerName),
-                skills::SkillParameterization::FromIce(update.header.usedParams,
-                                                       update.header.usedCallbackInterface));
-            skills::fromIce(update.header.status, ret.status);
+                skills::SkillExecutionID::FromIce(update.executionId, providerId),
+                skills::SkillParameterization::FromIce(update.usedParams,
+                                                       update.usedCallbackInterface));
+            skills::fromIce(update.status, ret.status);
             return ret;
         }
 
         SkillStatusUpdate
         SkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            SkillStatusUpdate ret(
-                skills::SkillExecutionId::FromIce(update.header.executionId),
-                skills::SkillParameterization::FromIce(update.header.usedParams,
-                                                       update.header.usedCallbackInterface));
-            skills::fromIce(update.header.status, ret.status);
+            SkillStatusUpdate ret(skills::SkillExecutionID::FromIce(update.executionId),
+                                  skills::SkillParameterization::FromIce(
+                                      update.usedParams, update.usedCallbackInterface));
+            skills::fromIce(update.status, ret.status);
             return ret;
         }
 
         SkillStatusUpdate
         SkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
-                                   const std::string& providerName)
+                                   const std::optional<skills::ProviderID>& providerId)
         {
-            SkillStatusUpdate ret(
-                skills::SkillExecutionId::FromIce(update.header.executionId, providerName),
-                skills::SkillParameterization::FromIce(update.header.usedParams,
-                                                       update.header.usedCallbackInterface));
-            skills::fromIce(update.header.status, ret.status);
+            SkillStatusUpdate ret(skills::SkillExecutionID::FromIce(update.executionId, providerId),
+                                  skills::SkillParameterization::FromIce(
+                                      update.usedParams, update.usedCallbackInterface));
+            skills::fromIce(update.status, ret.status);
             return ret;
         }
 
@@ -326,22 +368,23 @@ namespace armarx
         ActiveOrTerminatedSkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
             ActiveOrTerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionId::FromIce(update.header.executionId),
-                skills::SkillParameterization::FromIce(update.header.usedParams,
-                                                       update.header.usedCallbackInterface));
-            skills::fromIce(update.header.status, ret.status);
+                skills::SkillExecutionID::FromIce(update.executionId),
+                skills::SkillParameterization::FromIce(update.usedParams,
+                                                       update.usedCallbackInterface));
+            skills::fromIce(update.status, ret.status);
             return ret;
         }
 
         ActiveOrTerminatedSkillStatusUpdate
-        ActiveOrTerminatedSkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
-                                                     const std::string& providerName)
+        ActiveOrTerminatedSkillStatusUpdate::FromIce(
+            const provider::dto::SkillStatusUpdate& update,
+            const std::optional<skills::ProviderID>& providerId)
         {
             ActiveOrTerminatedSkillStatusUpdate ret(
-                skills::SkillExecutionId::FromIce(update.header.executionId, providerName),
-                skills::SkillParameterization::FromIce(update.header.usedParams,
-                                                       update.header.usedCallbackInterface));
-            skills::fromIce(update.header.status, ret.status);
+                skills::SkillExecutionID::FromIce(update.executionId, providerId),
+                skills::SkillParameterization::FromIce(update.usedParams,
+                                                       update.usedCallbackInterface));
+            skills::fromIce(update.status, ret.status);
             return ret;
         }
     } // namespace skills
diff --git a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
index 536a169f6..368dbe8b4 100644
--- a/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
+++ b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
@@ -46,24 +46,29 @@ namespace armarx
         SkillStatus toSkillStatus(const ActiveOrTerminatedSkillStatus&);
         SkillStatus toSkillStatus(const TerminatedSkillStatus&);
 
-        void toIce(provider::dto::Execution::Status& ret, const SkillStatus& status);
-        void toIce(provider::dto::Execution::Status& ret,
-                   const ActiveOrTerminatedSkillStatus& status);
-        void toIce(provider::dto::Execution::Status& ret, const TerminatedSkillStatus& status);
+        void toIce(core::dto::Execution::Status& ret, const SkillStatus& status);
+        void toIce(core::dto::Execution::Status& ret, const ActiveOrTerminatedSkillStatus& status);
+        void toIce(core::dto::Execution::Status& ret, const TerminatedSkillStatus& status);
 
-        void fromIce(const provider::dto::Execution::Status& status, TerminatedSkillStatus& ret);
-        void fromIce(const provider::dto::Execution::Status& status,
+        void fromIce(const core::dto::Execution::Status& status, TerminatedSkillStatus& ret);
+        void fromIce(const core::dto::Execution::Status& status,
                      ActiveOrTerminatedSkillStatus& ret);
-        void fromIce(const provider::dto::Execution::Status& status, SkillStatus& 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);
 
         struct SkillStatusUpdateBase
         {
             // header
-            SkillExecutionId executionId;
+            SkillExecutionID executionId;
             SkillParameterization usedParameterization;
 
             SkillStatusUpdateBase() = delete;
-            SkillStatusUpdateBase(const SkillExecutionId& exec, const SkillParameterization& param);
+            SkillStatusUpdateBase(const SkillExecutionID& exec, const SkillParameterization& param);
+            SkillStatusUpdateBase(const SkillStatusUpdateBase&) = default;
 
             // data
             aron::data::DictPtr data = nullptr;
@@ -92,7 +97,7 @@ namespace armarx
 
             static TerminatedSkillStatusUpdate
             FromIce(const provider::dto::SkillStatusUpdate& update,
-                    const std::string& providerName);
+                    const std::optional<skills::ProviderID>& providerId = std::nullopt);
 
             static TerminatedSkillStatusUpdate
             FromIce(const manager::dto::SkillStatusUpdate& update);
@@ -119,7 +124,7 @@ namespace armarx
 
             static ActiveOrTerminatedSkillStatusUpdate
             FromIce(const provider::dto::SkillStatusUpdate& update,
-                    const std::string& providerName);
+                    const std::optional<skills::ProviderID>& providerId = std::nullopt);
 
             static ActiveOrTerminatedSkillStatusUpdate
             FromIce(const manager::dto::SkillStatusUpdate& update);
@@ -132,6 +137,42 @@ namespace armarx
 
             using SkillStatusUpdateBase::SkillStatusUpdateBase;
 
+            bool
+            operator<(const SkillStatusUpdate& o) const
+            {
+                if (!hasBeenConstructed() and o.hasBeenConstructed())
+                {
+                    return true;
+                }
+                if (!hasBeenInitialized() and o.hasBeenInitialized())
+                {
+                    return true;
+                }
+                if (!hasBeenPrepared() and o.hasBeenPrepared())
+                {
+                    return true;
+                }
+                if (!hasBeenRunning() and o.hasBeenRunning())
+                {
+                    return true;
+                }
+                if (!hasBeenTerminated() and o.hasBeenTerminated())
+                {
+                    return true;
+                }
+                return false;
+            }
+
+            bool
+            operator<=(const SkillStatusUpdate& o) const
+            {
+                if (status == o.status)
+                {
+                    return true;
+                }
+                return *this < o;
+            }
+
             bool
             hasBeenConstructed() const
             {
@@ -167,8 +208,9 @@ namespace armarx
 
             provider::dto::SkillStatusUpdate toProviderIce() const;
 
-            static SkillStatusUpdate FromIce(const provider::dto::SkillStatusUpdate& update,
-                                             const std::string& providerName);
+            static SkillStatusUpdate
+            FromIce(const provider::dto::SkillStatusUpdate& update,
+                    const std::optional<skills::ProviderID>& providerId = std::nullopt);
 
             static SkillStatusUpdate FromIce(const manager::dto::SkillStatusUpdate& update);
         };
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 057715f98..51694c8d9 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -18,6 +18,8 @@ namespace armarx::plugins
     void
     SkillManagerComponentPlugin::preOnConnectComponent()
     {
+        auto& p = parent<SkillManagerComponentPluginUser>();
+        p.getProxy(myPrx, -1);
     }
 
     void
@@ -44,56 +46,55 @@ namespace armarx::plugins
     }
 
     void
-    SkillManagerComponentPlugin::addProvider(const skills::ProviderInfo& info)
+    SkillManagerComponentPlugin::addProvider(const skills::ProviderInfo& providerInfo)
     {
         std::scoped_lock l(skillProviderMapMutex);
-        if (skillProviderMap.find(info.providerId.providerName) == skillProviderMap.end())
+        if (skillProviderMap.find(providerInfo.providerId.providerName) == skillProviderMap.end())
         {
-            ARMARX_INFO << "Adding a provider with name '" << info.providerId.providerName << "'.";
-            skillProviderMap.insert({info.providerId.providerName, info.provider});
+            ARMARX_INFO << "Adding a provider with name '" << providerInfo.providerId.providerName
+                        << "'.";
+            skillProviderMap.insert(
+                {providerInfo.providerId.providerName, providerInfo.providerInterface});
         }
         else
         {
-            ARMARX_INFO << "Trying to add a provider with name '" << info.providerId.providerName
+            ARMARX_INFO << "Trying to add a provider with name '"
+                        << providerInfo.providerId.providerName
                         << "' but the provider already exists. "
                         << "Overwriting the old provider info.";
-            skillProviderMap[info.providerId.providerName] = info.provider;
+            skillProviderMap[providerInfo.providerId.providerName] = providerInfo.providerInterface;
         }
     }
 
     void
-    SkillManagerComponentPlugin::removeProvider(const skills::ProviderID& id)
+    SkillManagerComponentPlugin::removeProvider(const skills::ProviderID& providerId)
     {
         std::scoped_lock l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(id.providerName); it != skillProviderMap.end())
+        if (auto it = skillProviderMap.find(providerId.providerName); it != skillProviderMap.end())
         {
-            ARMARX_INFO << "Removing a provider with name '" << id.providerName << "'.";
+            ARMARX_INFO << "Removing a provider with name '" << providerId.providerName << "'.";
             skillProviderMap.erase(it);
         }
         else
         {
-            ARMARX_INFO << "Trying to remove a provider with name '" << id.providerName
+            ARMARX_INFO << "Trying to remove a provider with name '" << providerId.providerName
                         << "' but it couldn't be found.";
         }
     }
 
     skills::SkillStatusUpdate
-    SkillManagerComponentPlugin::executeSkill(
-        const skills::SkillExecutionRequest& req,
-        const skills::callback::dti::SkillProviderCallbackInterfacePrx& myPrx)
+    SkillManagerComponentPlugin::executeSkill(const skills::SkillExecutionRequest& executionRequest)
     {
+        ARMARX_CHECK(executionRequest.skillId.fullySpecified());
+
         std::unique_lock l(skillProviderMapMutex);
 
-        skills::ProviderID provderId("INVALID PROVIDER NAME");
+        skills::ProviderID provderId(executionRequest.skillId);
 
         // TODO: Really support regexes!
-        if (req.skillId.providerName == "*")
-        {
-            provderId = getFirstProviderNameThatHasSkill(req.skillId.skillName);
-        }
-        else if (not(req.skillId.providerName.empty()))
+        if (executionRequest.skillId.providerId->providerName == "*")
         {
-            provderId = skills::ProviderID(req.skillId);
+            provderId = getFirstProviderNameThatHasSkill(executionRequest.skillId.skillName);
         }
 
 
@@ -115,15 +116,21 @@ namespace armarx::plugins
 
             try
             {
-                skills::SkillExecutionRequest exInfo(
-                    req.skillId, req.executorName, req.params, myPrx);
+                skills::SkillExecutionRequest provider_executionRequest(
+                    executionRequest.skillId,
+                    executionRequest.executorName,
+                    executionRequest.params,
+                    myPrx);
 
-                auto async = provider->begin_executeSkill(exInfo.toProviderIce());
+                auto async =
+                    provider->begin_executeSkill(provider_executionRequest.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
-                auto up = provider->end_executeSkill(async);
+                auto provider_statusUpdate_ice = provider->end_executeSkill(async);
 
                 // convert to manager view
-                return skills::SkillStatusUpdate::FromIce(up, provderId.providerName);
+                auto statusUpdate =
+                    skills::SkillStatusUpdate::FromIce(provider_statusUpdate_ice, provderId);
+                return statusUpdate;
             }
             catch (...)
             {
@@ -147,23 +154,20 @@ namespace armarx::plugins
         }
     }
 
-    skills::SkillExecutionId
+    skills::SkillExecutionID
     SkillManagerComponentPlugin::executeSkillAsync(
-        const skills::SkillExecutionRequest& req,
-        const skills::callback::dti::SkillProviderCallbackInterfacePrx& myPrx)
+        const skills::SkillExecutionRequest& executionRequest)
     {
+        ARMARX_CHECK(executionRequest.skillId.fullySpecified());
+
         std::unique_lock l(skillProviderMapMutex);
 
-        skills::ProviderID provderId("INVALID PROVIDER NAME");
+        skills::ProviderID provderId(executionRequest.skillId);
 
         // TODO: Really support regexes!
-        if (req.skillId.providerName == "*")
+        if (executionRequest.skillId.providerId->providerName == "*")
         {
-            provderId = getFirstProviderNameThatHasSkill(req.skillId.skillName);
-        }
-        else if (not(req.skillId.providerName.empty()))
-        {
-            provderId = req.skillId.providerName;
+            provderId = getFirstProviderNameThatHasSkill(executionRequest.skillId.skillName);
         }
 
 
@@ -185,15 +189,22 @@ namespace armarx::plugins
 
             try
             {
-                skills::SkillExecutionRequest exInfo(
-                    req.skillId, req.executorName, req.params, myPrx);
+                skills::SkillExecutionRequest provider_executionRequest(
+                    executionRequest.skillId,
+                    executionRequest.executorName,
+                    executionRequest.params,
+                    myPrx);
 
-                auto async = provider->begin_executeSkillAsync(exInfo.toProviderIce());
+                auto async =
+                    provider->begin_executeSkillAsync(provider_executionRequest.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
-                auto up = provider->end_executeSkillAsync(async);
+                auto provider_executionID_ice = provider->end_executeSkillAsync(async);
 
                 // convert to manager view
-                return skills::SkillExecutionId::FromIce(up, provderId.providerName);
+                auto executionId =
+                    skills::SkillExecutionID::FromIce(provider_executionID_ice, provderId);
+                executionId.skillId.providerId = provderId;
+                return executionId;
             }
             catch (...)
             {
@@ -218,70 +229,137 @@ namespace armarx::plugins
     }
 
     void
-    SkillManagerComponentPlugin::addSkillParameters(const skills::SkillExecutionId& id,
+    SkillManagerComponentPlugin::addSkillParameters(const skills::SkillExecutionID& executionId,
                                                     const aron::data::DictPtr& data)
     {
+        ARMARX_CHECK(executionId.skillId.fullySpecified());
+
         std::unique_lock l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(skills::ProviderID(id.skillId.providerName));
+        if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
             it != skillProviderMap.end())
         {
-            const auto& providerName = it->first;
+            const auto& providerId = it->first;
             const auto& provider = it->second;
 
             if (!provider)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
-                               << providerName << "'. Removing it from skills.";
+                               << providerId << "'. Removing it from skills.";
                 skillProviderMap.erase(it);
                 return;
             }
 
             try
             {
-                auto async =
-                    provider->begin_addSkillParameters(id.toProviderIce(), data->toAronDictDTO());
+                auto async = provider->begin_addSkillParameters(executionId.toProviderIce(),
+                                                                data->toAronDictDTO());
                 l.unlock(); // allow parallel e.g. stopping
-                return provider->end_addSkillParameters(async);
+                provider->end_addSkillParameters(async);
+                return;
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
-                               << providerName << "'. Removing it from skills on next execute.";
+                               << providerId << "'. Removing it from skills on next execute.";
             }
         }
     }
 
     void
-    SkillManagerComponentPlugin::abortSkill(const skills::SkillExecutionId& id)
+    SkillManagerComponentPlugin::abortSkill(const skills::SkillExecutionID& executionId)
     {
+        ARMARX_CHECK(executionId.skillId.fullySpecified());
+
         std::unique_lock l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(id.skillId.providerName); it != skillProviderMap.end())
+        if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
+            it != skillProviderMap.end())
         {
-            const auto& providerName = it->first;
+            const auto& providerId = it->first;
             const auto& provider = it->second;
 
             if (!provider)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
-                               << providerName << "'. Removing it from skills.";
+                               << providerId << "'. Removing it from skills.";
                 skillProviderMap.erase(it);
                 return;
             }
 
             try
             {
-                auto async = provider->begin_abortSkill(id.toProviderIce());
+                auto async = provider->begin_abortSkill(executionId.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
-                return provider->end_abortSkill(async);
+                provider->end_abortSkill(async);
+                return;
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
-                               << providerName << "'. Removing it from skills on next execute.";
+                               << providerId << "'. Removing it from skills on next execute.";
             }
         }
     }
 
+    std::optional<skills::SkillDescription>
+    SkillManagerComponentPlugin::getSkillDescription(const skills::SkillID& skillId)
+    {
+        ARMARX_CHECK(skillId.fullySpecified());
+
+        std::unique_lock l(skillProviderMapMutex);
+        if (auto it = skillProviderMap.find(*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);
+
+                throw skills::error::SkillException(__PRETTY_FUNCTION__,
+                                                    "Skill execution failed. Could not query a "
+                                                    "status update of a skill of provider '" +
+                                                        providerId.toString() +
+                                                        "' because the provider does not exist.");
+            }
+
+            try
+            {
+                auto async = provider->begin_getSkillDescription(skillId.toProviderIce());
+                l.unlock(); // allow parallel e.g. stopping
+                auto provider_desc_ice = provider->end_getSkillDescription(async);
+
+                if (not provider_desc_ice)
+                {
+                    return std::nullopt;
+                }
+
+                // convert to manager view
+                auto desc =
+                    skills::SkillDescription::FromIce(provider_desc_ice.value(), providerId);
+                return desc;
+            }
+            catch (...)
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__
+                               << ": Found disconnected or buggy skill provider '" << providerId
+                               << "' during execution. Removing it from skills.";
+                skillProviderMap.erase(it);
+
+                throw skills::error::SkillException(__PRETTY_FUNCTION__,
+                                                    "Skill execution failed. Could not query a "
+                                                    "status update of a skill of provider '" +
+                                                        providerId.toString() +
+                                                        "' because the provider does not exist.");
+            }
+        }
+        else
+        {
+            return std::nullopt;
+        }
+    }
+
     std::map<skills::SkillID, skills::SkillDescription>
     SkillManagerComponentPlugin::getSkillDescriptions()
     {
@@ -290,13 +368,13 @@ namespace armarx::plugins
         std::scoped_lock l(skillProviderMapMutex);
         for (auto it = skillProviderMap.cbegin(); it != skillProviderMap.cend();)
         {
-            const auto& providerName = it->first;
+            const auto& providerId = it->first;
             const auto& provider = it->second;
 
             if (!provider)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
-                               << providerName << "'. Removing it from skills.";
+                               << providerId << "'. Removing it from skills.";
                 it = skillProviderMap.erase(it);
                 continue;
             }
@@ -305,9 +383,11 @@ namespace armarx::plugins
             {
                 skills::provider::dto::SkillDescriptionMap m = provider->getSkillDescriptions();
 
-                for (const auto& [k, v] : m)
+                for (const auto& [provider_skillId_ice, skillDescription_ice] : m)
                 {
-                    ret.insert({skills::SkillID::FromIce(k), skills::SkillDescription::FromIce(v)});
+                    ret.insert(
+                        {skills::SkillID::FromIce(provider_skillId_ice, providerId),
+                         skills::SkillDescription::FromIce(skillDescription_ice, providerId)});
                 }
 
                 ++it;
@@ -315,7 +395,7 @@ namespace armarx::plugins
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
-                               << providerName << "'. Removing it from skills.";
+                               << providerId << "'. Removing it from skills.";
                 it = skillProviderMap.erase(it);
             }
         }
@@ -323,10 +403,13 @@ namespace armarx::plugins
     }
 
     std::optional<skills::SkillStatusUpdate>
-    SkillManagerComponentPlugin::getSkillExecutionStatus(const skills::SkillExecutionId& execId)
+    SkillManagerComponentPlugin::getSkillExecutionStatus(
+        const skills::SkillExecutionID& executionId)
     {
+        ARMARX_CHECK(executionId.skillId.fullySpecified());
+
         std::unique_lock l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(execId.skillId.providerName);
+        if (auto it = skillProviderMap.find(*executionId.skillId.providerId);
             it != skillProviderMap.end())
         {
             const auto& providerId = it->first;
@@ -347,12 +430,19 @@ namespace armarx::plugins
 
             try
             {
-                auto async = provider->begin_getSkillExecutionStatus(execId.toProviderIce());
+                auto async = provider->begin_getSkillExecutionStatus(executionId.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
-                auto up = provider->end_getSkillExecutionStatus(async);
+                auto provider_statusUpdate_ice = provider->end_getSkillExecutionStatus(async);
+
+                if (not provider_statusUpdate_ice)
+                {
+                    return std::nullopt;
+                }
 
                 // convert to manager view
-                return skills::SkillStatusUpdate::FromIce(up, providerId.providerName);
+                auto statusUpdate = skills::SkillStatusUpdate::FromIce(
+                    provider_statusUpdate_ice.value(), providerId);
+                return statusUpdate;
             }
             catch (...)
             {
@@ -370,15 +460,14 @@ namespace armarx::plugins
         }
         else
         {
-            // no actove skill. Return null
             return std::nullopt;
         }
     }
 
-    std::map<skills::SkillExecutionId, skills::SkillStatusUpdate>
+    std::map<skills::SkillExecutionID, skills::SkillStatusUpdate>
     SkillManagerComponentPlugin::getSkillExecutionStatuses()
     {
-        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> ret;
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> ret;
 
         std::scoped_lock l(skillProviderMapMutex);
         for (auto it = skillProviderMap.cbegin(); it != skillProviderMap.cend();)
@@ -398,10 +487,12 @@ namespace armarx::plugins
             {
                 auto m = provider->getSkillExecutionStatuses();
 
-                for (const auto& [k, v] : m)
+                for (const auto& [provider_executionId_ice, provider_statusUpdate_ice] : m)
                 {
-                    ret.insert({skills::SkillExecutionId::FromIce(k, providerId.providerName),
-                                skills::SkillStatusUpdate::FromIce(v, providerId.providerName)});
+                    ret.insert(
+                        {skills::SkillExecutionID::FromIce(provider_executionId_ice, providerId),
+                         skills::SkillStatusUpdate::FromIce(provider_statusUpdate_ice,
+                                                            providerId)});
                 }
                 it++;
             }
@@ -449,11 +540,8 @@ namespace armarx
         const skills::manager::dto::SkillExecutionRequest& info,
         const Ice::Current&)
     {
-        skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx;
-        getProxy(myPrx, -1);
-
         auto e = skills::SkillExecutionRequest::FromIce(info);
-        return this->plugin->executeSkill(e, myPrx).toManagerIce();
+        return this->plugin->executeSkill(e).toManagerIce();
     }
 
     skills::manager::dto::SkillExecutionID
@@ -461,11 +549,8 @@ namespace armarx
         const skills::manager::dto::SkillExecutionRequest& info,
         const Ice::Current& current)
     {
-        skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx;
-        getProxy(myPrx, -1);
-
         auto e = skills::SkillExecutionRequest::FromIce(info);
-        return this->plugin->executeSkillAsync(e, myPrx).toManagerIce();
+        return this->plugin->executeSkillAsync(e).toManagerIce();
     }
 
     void
@@ -475,7 +560,7 @@ namespace armarx
         const Ice::Current& current)
     {
         auto a = armarx::aron::data::Dict::FromAronDictDTO(params);
-        auto e = skills::SkillExecutionId::FromIce(info);
+        auto e = skills::SkillExecutionID::FromIce(info);
         this->plugin->addSkillParameters(e, a);
     }
 
@@ -483,14 +568,14 @@ namespace armarx
     SkillManagerComponentPluginUser::abortSkill(const skills::manager::dto::SkillExecutionID& id,
                                                 const Ice::Current& current)
     {
-        auto i = skills::SkillExecutionId::FromIce(id);
+        auto i = skills::SkillExecutionID::FromIce(id);
         this->plugin->abortSkill(i);
     }
 
     void
     SkillManagerComponentPluginUser::updateStatusForSkill(
         const skills::provider::dto::SkillStatusUpdate& statusUpdate,
-        const skills::provider::dto::ProviderID& pid,
+        const skills::callback::dto::ProviderID& pid,
         const Ice::Current&)
     {
         (void)statusUpdate;
@@ -507,24 +592,37 @@ namespace armarx
 
         for (const auto& [k, v] : m)
         {
-            ret.insert({k.toManagerIce(), v.toIce()});
+            ret.insert({k.toManagerIce(), v.toManagerIce()});
         }
 
         return ret;
     }
 
-    skills::manager::dto::SkillStatusUpdate
+    IceUtil::Optional<skills::manager::dto::SkillDescription>
+    SkillManagerComponentPluginUser::getSkillDescription(const skills::manager::dto::SkillID& id,
+                                                         const Ice::Current& current)
+    {
+        auto e = skills::SkillID::FromIce(id);
+        auto o = this->plugin->getSkillDescription(e);
+        if (o.has_value())
+        {
+            return o->toManagerIce();
+        }
+        return {};
+    }
+
+    IceUtil::Optional<skills::manager::dto::SkillStatusUpdate>
     SkillManagerComponentPluginUser::getSkillExecutionStatus(
         const skills::manager::dto::SkillExecutionID& executionId,
         const Ice::Current& current)
     {
-        auto e = skills::SkillExecutionId::FromIce(executionId);
+        auto e = skills::SkillExecutionID::FromIce(executionId);
         auto o = this->plugin->getSkillExecutionStatus(e);
         if (o.has_value())
         {
             return o->toManagerIce();
         }
-        return {}; // TODO!!
+        return {};
     }
 
     skills::manager::dto::SkillStatusUpdateMap
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
index 5aaadd6e6..57b0250a1 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
@@ -11,6 +11,11 @@
 #include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
 #include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
+namespace armarx
+{
+    class SkillManagerComponentPluginUser; // forward declaration
+}
+
 namespace armarx::plugins
 {
     class SkillManagerComponentPlugin : public ComponentPlugin
@@ -28,32 +33,34 @@ namespace armarx::plugins
 
         void removeProvider(const skills::ProviderID& id);
 
-        skills::SkillStatusUpdate
-        executeSkill(const skills::SkillExecutionRequest& req,
-                     const skills::callback::dti::SkillProviderCallbackInterfacePrx& prx);
+        skills::SkillStatusUpdate executeSkill(const skills::SkillExecutionRequest& req);
 
-        skills::SkillExecutionId
-        executeSkillAsync(const skills::SkillExecutionRequest& req,
-                          const skills::callback::dti::SkillProviderCallbackInterfacePrx& prx);
+        skills::SkillExecutionID executeSkillAsync(const skills::SkillExecutionRequest& req);
 
-        void addSkillParameters(const skills::SkillExecutionId& id,
+        void addSkillParameters(const skills::SkillExecutionID& id,
                                 const aron::data::DictPtr& data);
 
-        void abortSkill(const skills::SkillExecutionId& id);
+        void abortSkill(const skills::SkillExecutionID& id);
+
+        std::optional<skills::SkillDescription> getSkillDescription(const skills::SkillID& id);
 
         std::map<skills::SkillID, skills::SkillDescription> getSkillDescriptions();
 
         std::optional<skills::SkillStatusUpdate>
-        getSkillExecutionStatus(const skills::SkillExecutionId& id);
+        getSkillExecutionStatus(const skills::SkillExecutionID& id);
 
-        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> getSkillExecutionStatuses();
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> getSkillExecutionStatuses();
 
         skills::ProviderID getFirstProviderNameThatHasSkill(const skills::SkillID& skillid);
 
-    protected:
+    private:
+        skills::manager::dti::SkillManagerInterfacePrx myPrx;
+
         std::mutex skillProviderMapMutex;
         std::map<skills::ProviderID, skills::provider::dti::SkillProviderInterfacePrx>
             skillProviderMap;
+
+        friend class armarx::SkillManagerComponentPluginUser;
     };
 } // namespace armarx::plugins
 
@@ -84,7 +91,7 @@ namespace armarx
                                 const Ice::Current& current) override;
 
         void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
-                                  const skills::provider::dto::ProviderID& id,
+                                  const skills::callback::dto::ProviderID& id,
                                   const Ice::Current& current) override;
 
         void abortSkill(const skills::manager::dto::SkillExecutionID& id,
@@ -93,7 +100,11 @@ namespace armarx
         skills::manager::dto::SkillDescriptionMap
         getSkillDescriptions(const Ice::Current& current) override;
 
-        skills::manager::dto::SkillStatusUpdate
+        IceUtil::Optional<skills::manager::dto::SkillDescription>
+        getSkillDescription(const skills::manager::dto::SkillID& id,
+                            const Ice::Current& current) override;
+
+        IceUtil::Optional<skills::manager::dto::SkillStatusUpdate>
         getSkillExecutionStatus(const skills::manager::dto::SkillExecutionID& executionId,
                                 const Ice::Current& current) override;
 
diff --git a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
index 4df38fb17..56994fb33 100644
--- a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
@@ -45,7 +45,7 @@ namespace armarx::skills
     Skill::MainResult
     PeriodicSkill::main()
     {
-        core::time::Metronome metronome(frequency);
+        armarx::core::time::Metronome metronome(frequency);
 
         while (not Skill::checkWhetherSkillShouldStopASAP())
         {
diff --git a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
index 60823be8c..b11239dcf 100644
--- a/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
@@ -43,14 +43,14 @@ namespace armarx::skills
 
         StepResult stepOfSkill();
 
-    private:
+    protected:
         /// Do not use anymore
         Skill::MainResult main() final;
 
         /// Override this method with your own step function
         virtual StepResult step();
 
-    private:
+    protected:
         const armarx::Frequency frequency;
     };
 
diff --git a/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
index 83f9ae009..1c98f1126 100644
--- a/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
@@ -56,15 +56,12 @@ namespace armarx::skills
             return this->step();
         }
 
-    private:
-        using Skill::stopped;
-        using Skill::timeoutReached;
-
+    protected:
         /// Do not use anymore
         Skill::MainResult
         main() final
         {
-            core::time::Metronome metronome(frequency);
+            armarx::core::time::Metronome metronome(frequency);
 
             while (not Skill::checkWhetherSkillShouldStopASAP())
             {
@@ -115,6 +112,10 @@ namespace armarx::skills
         }
 
     private:
+        using Skill::stopped;
+        using Skill::timeoutReached;
+
+    protected:
         const armarx::Frequency frequency;
     };
 
diff --git a/source/RobotAPI/libraries/skills/provider/SkillContext.h b/source/RobotAPI/libraries/skills/provider/SkillContext.h
index 9bdbc0f02..df5a90eb7 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillContext.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillContext.h
@@ -7,20 +7,21 @@ namespace armarx
 {
     namespace skills
     {
-        /* A 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:
             SkillContext() = default;
 
-            virtual void defineProperties(const armarx::PropertyDefinitionsPtr& defs, const std::string& prefix) {};
+            virtual void defineProperties(const armarx::PropertyDefinitionsPtr& defs,
+                                          const std::string& prefix){};
 
-            virtual void onInit(armarx::Component& parent) {};
-            virtual void onConnected(armarx::Component& parent) {};
-            virtual void onDisconnected(armarx::Component& parent) {};
-            virtual void onStopped(armarx::Component& parent) {};
+            virtual void onInit(armarx::Component& parent){};
+            virtual void onConnected(armarx::Component& parent){};
+            virtual void onDisconnected(armarx::Component& parent){};
+            virtual void onStopped(armarx::Component& parent){};
 
         private:
         };
-    }
-}
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillFactory.h b/source/RobotAPI/libraries/skills/provider/SkillFactory.h
index eadb1bab9..ea4cd5edb 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillFactory.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillFactory.h
@@ -11,9 +11,9 @@ namespace armarx
         class SkillFactory
         {
         public:
-            using FunT = std::function<std::unique_ptr<Skill>()>;
+            using FunTSkill = std::function<std::unique_ptr<Skill>()>;
 
-            SkillFactory(const SkillDescription& id, const FunT& f) : fun(f), desc(id)
+            SkillFactory(const FunTSkill& s) : createS(s)
             {
             }
 
@@ -21,66 +21,36 @@ namespace armarx
             requires isSkill<_Skill>
 
             static std::unique_ptr<SkillFactory>
-            ForSkill(const SkillDescription& id, Args&&... args)
+            ForSkill(Args&&... args)
 
             {
-                return std::make_unique<SkillFactory>(
-                    id, [&]() { return std::make_unique<_Skill>(std::forward<Args>(args)...); });
-            }
-
-
-            template <class _Skill, class... Args>
-            requires isSkill<_Skill>
+                // 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)...); };
 
-            static std::unique_ptr<SkillFactory>
-            ForSkillDescriptionGetter(Args&&... args)
-
-            {
-                return std::make_unique<SkillFactory>(
-                    _Skill::GetSkillDescription(),
-                    [&]() { return std::make_unique<_Skill>(std::forward<Args>(args)...); });
+                auto ret = std::make_unique<SkillFactory>(createS);
+                return ret;
             }
 
             virtual std::unique_ptr<Skill>
-            createSkill() const
-            {
-                return fun();
-            }
-
-            const SkillDescription&
-            getSkillDescription() const
+            createSkill(const skills::ProviderID& pid) const
             {
-                return desc;
+                auto s = createS();
+                s->setProviderId(pid);
+                return s;
             }
 
-            void
-            setOwner(const std::string& providerName)
+            virtual SkillDescription
+            createSkillDescription(const skills::ProviderID& pid) const
             {
-                ARMARX_CHECK(this->desc.skillId.providerName.empty())
-                    << "The owning provider of the factory for skill '"
-                    << this->desc.skillId.skillName << "' was already set. This is not valid.";
-                this->desc.skillId.providerName = providerName;
-            }
-
-            SkillID
-            getSkillID(const std::string& providerName) const
-            {
-                SkillID copy = getSkillID();
-                copy.providerName = providerName;
-                return copy;
-            }
-
-            const SkillID&
-            getSkillID() const
-            {
-                return desc.skillId;
+                auto s = createSkill(pid);
+                return s->getSkillDescription();
             }
 
 
         protected:
-            FunT fun;
-
-            SkillDescription desc;
+            FunTSkill createS;
         };
 
         template <class T>
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
index 3686ccb9f..c187b4ad4 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
@@ -3,6 +3,7 @@
 #include <ArmarXCore/core/Component.h>
 
 #include <RobotAPI/libraries/aron/core/data/variant/primitive/All.h>
+#include <RobotAPI/libraries/skills/core/ProviderInfo.h>
 
 namespace armarx::plugins
 {
@@ -25,11 +26,10 @@ namespace armarx::plugins
         const std::string providerName = p.getName();
 
         // register self to manager
-        skills::manager::dto::ProviderInfo i;
-        i.provider = myPrx;
-        i.providerId = {providerName};
-        i.providedSkills = p.getSkillDescriptions();
-        manager->addProvider(i); // add provider info to manager
+        skills::ProviderInfo i(skills::ProviderID(providerName), myPrx, getSkillDescriptions());
+
+        ARMARX_INFO << "Adding provider to manager: " << i.providerId;
+        manager->addProvider(i.toIce()); // add provider info to manager
     }
 
     void
@@ -53,16 +53,6 @@ namespace armarx::plugins
             "The name of the SkillManager (or SkillMemory) proxy this provider belongs to.");
     }
 
-    void
-    SkillProviderComponentPlugin::addSkillFactory(const skills::LambdaSkill::FunT& f,
-                                                  const skills::SkillDescription& desc)
-    {
-        auto fac = skills::SkillFactory::ForSkill<skills::LambdaSkill>(desc, desc, f);
-        //        std::make_unique<skills::SkillFactory>(
-        //            desc, [&]() { return std::make_unique<skills::LambdaSkill>(f, desc); });
-        addSkillFactory(std::move(fac));
-    }
-
     void
     SkillProviderComponentPlugin::addSkillFactory(std::unique_ptr<skills::SkillFactory>&& fac)
     {
@@ -72,11 +62,13 @@ namespace armarx::plugins
         }
 
         auto& p = parent<SkillProviderComponentPluginUser>();
-        const std::string providerName = p.getName();
+        const std::string componentName = p.getName();
+
+        const skills::ProviderID providerId({componentName});
 
         // lock skills map
         const std::unique_lock l(skillFactoriesMutex);
-        auto skillId = fac->getSkillID(providerName);
+        auto skillId = fac->createSkillDescription(providerId).skillId;
 
         if (skillFactories.find(skillId) != skillFactories.end())
         {
@@ -85,11 +77,9 @@ namespace armarx::plugins
             return;
         }
 
-        ARMARX_INFO << "Adding skill `" << skillId << "` and set owning provider name to `"
-                    << providerName << "` .";
-        fac->setOwner(providerName);
+        ARMARX_INFO << "Adding skill `" << skillId << "` to component `" << componentName << "` .";
 
-        skillFactories.emplace(fac->getSkillID(), std::move(fac));
+        skillFactories.emplace(skillId, std::move(fac));
 
         //        if (connected)
         //        {
@@ -101,20 +91,31 @@ namespace armarx::plugins
     }
 
     skills::SkillFactory*
-    SkillProviderComponentPlugin::getSkillFactory(const armarx::skills::SkillID& skill)
+    SkillProviderComponentPlugin::addSkillFactory(const skills::SkillDescription& desc,
+                                                  const skills::LambdaSkill::FunT& f)
     {
-        ARMARX_CHECK_GREATER(skillFactories.count(skill), 0)
-            << "Skill '" + skill.toString() + "' not found.";
+        return addSkillFactory<skills::LambdaSkill>(desc, f);
+    }
 
-        const std::unique_lock l(skillFactoriesMutex);
-        auto* facPtr = skillFactories.at(skill).get();
+    skills::SkillFactory*
+    SkillProviderComponentPlugin::getSkillFactory(const armarx::skills::SkillID& skillId)
+    {
+        // NON BLOCKING: WE ASSERT THAT THE LOCK IS ALREADY TAKEN
+        ARMARX_CHECK(skillId.fullySpecified());
+
+        ARMARX_CHECK_GREATER(skillFactories.count(skillId), 0)
+            << "Skill '" + skillId.toString() + "' not found.";
+
+        auto* facPtr = skillFactories.at(skillId).get();
         return static_cast<skills::SkillFactory*>(facPtr);
     }
 
     std::optional<skills::SkillStatusUpdate>
     SkillProviderComponentPlugin::getSkillExecutionStatus(
-        const skills::SkillExecutionId& execId) const
+        const skills::SkillExecutionID& execId) const
     {
+        ARMARX_CHECK(execId.skillId.skillSpecified());
+
         const std::unique_lock l(skillExecutionsMutex);
         if (skillExecutions.find(execId) != skillExecutions.end())
         {
@@ -126,10 +127,10 @@ namespace armarx::plugins
         return skillExecutions.at(execId).statusUpdate;
     }
 
-    std::map<skills::SkillExecutionId, skills::SkillStatusUpdate>
+    std::map<skills::SkillExecutionID, skills::SkillStatusUpdate>
     SkillProviderComponentPlugin::getSkillExecutionStatuses() const
     {
-        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> skillUpdates;
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate> skillUpdates;
 
         const std::scoped_lock l(skillExecutionsMutex);
         for (const auto& [key, impl] : skillExecutions)
@@ -143,6 +144,8 @@ namespace armarx::plugins
     std::optional<skills::SkillDescription>
     SkillProviderComponentPlugin::getSkillDescription(const skills::SkillID& skillId) const
     {
+        ARMARX_CHECK(skillId.fullySpecified());
+
         const std::unique_lock l(skillFactoriesMutex);
         if (skillFactories.find(skillId) != skillFactories.end())
         {
@@ -150,7 +153,7 @@ namespace armarx::plugins
             return std::nullopt;
         }
 
-        return skillFactories.at(skillId)->getSkillDescription();
+        return skillFactories.at(skillId)->createSkillDescription(*skillId.providerId);
     }
 
     std::map<skills::SkillID, skills::SkillDescription>
@@ -160,30 +163,34 @@ namespace armarx::plugins
         const std::unique_lock l(skillFactoriesMutex);
         for (const auto& [key, fac] : skillFactories)
         {
-            skillDesciptions.insert({key, fac->getSkillDescription()});
+            ARMARX_CHECK(key.fullySpecified());
+            skillDesciptions.insert({key, fac->createSkillDescription(*key.providerId)});
         }
         return skillDesciptions;
     }
 
     skills::SkillStatusUpdate
-    SkillProviderComponentPlugin::executeSkill(const skills::SkillExecutionRequest& executionInfo)
+    SkillProviderComponentPlugin::executeSkill(
+        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{executionInfo.params,
-                                                           executionInfo.callbackInterface};
+        skills::SkillParameterization usedParameterization{executionRequest.params,
+                                                           executionRequest.callbackInterface};
 
-        skills::SkillExecutionId execId(
-            executionInfo.skillId, executionInfo.executorName, armarx::core::time::DateTime::Now());
+        skills::SkillExecutionID executionId(executionRequest.skillId,
+                                             executionRequest.executorName,
+                                             armarx::core::time::DateTime::Now());
 
-        skills::SkillStatusUpdate ret{execId, usedParameterization};
+        skills::SkillStatusUpdate ret{executionId, usedParameterization};
         {
             auto l1 = std::unique_lock{skillFactoriesMutex};
 
-            const auto& id = executionInfo.skillId;
-            const auto& fac = getSkillFactory(id);
+            const auto& fac = getSkillFactory(executionRequest.skillId);
 
             // async start execution. But we wait for the execution to finish at the end of this method
             execution = std::thread(
@@ -194,11 +201,11 @@ namespace armarx::plugins
                         const std::unique_lock l2{skillExecutionsMutex};
                         auto it = skillExecutions.emplace(
                             std::piecewise_construct,
-                            std::make_tuple(execId),
-                            std::make_tuple(fac, execId, usedParameterization));
+                            std::make_tuple(executionId),
+                            std::make_tuple(fac, executionId, usedParameterization));
 
                         ARMARX_CHECK(it.second)
-                            << "For some reason a skill '" << execId.skillId.toString()
+                            << "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 "
@@ -221,7 +228,7 @@ namespace armarx::plugins
 
             // tidy up map of executions
             const std::unique_lock l2{skillExecutionsMutex};
-            if (auto it = skillExecutions.find(execId); it != skillExecutions.end())
+            if (auto it = skillExecutions.find(executionId); it != skillExecutions.end())
             {
                 skillExecutions.erase(it);
             }
@@ -229,25 +236,27 @@ namespace armarx::plugins
         return ret;
     }
 
-    skills::SkillExecutionId
+    skills::SkillExecutionID
     SkillProviderComponentPlugin::executeSkillAsync(
-        const skills::SkillExecutionRequest& executionInfo)
+        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{executionInfo.params,
-                                                           executionInfo.callbackInterface};
+        skills::SkillParameterization usedParameterization{executionRequest.params,
+                                                           executionRequest.callbackInterface};
 
-        skills::SkillExecutionId execId(
-            executionInfo.skillId, executionInfo.executorName, armarx::core::time::DateTime::Now());
+        skills::SkillExecutionID executionId(executionRequest.skillId,
+                                             executionRequest.executorName,
+                                             armarx::core::time::DateTime::Now());
 
         {
             auto l1 = std::unique_lock{skillFactoriesMutex};
 
-            const auto& id = executionInfo.skillId;
-            const auto& fac = getSkillFactory(id);
+            const auto& fac = getSkillFactory(executionRequest.skillId);
 
             // async start execution. But we wait for the execution to finish at the end of this method
             execution = std::thread(
@@ -258,11 +267,11 @@ namespace armarx::plugins
                         const std::unique_lock l2{skillExecutionsMutex};
                         auto it = skillExecutions.emplace(
                             std::piecewise_construct,
-                            std::make_tuple(execId),
-                            std::make_tuple(fac, execId, usedParameterization));
+                            std::make_tuple(executionId),
+                            std::make_tuple(fac, executionId, usedParameterization));
 
                         ARMARX_CHECK(it.second)
-                            << "For some reason a skill '" << execId.skillId.toString()
+                            << "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 "
@@ -278,18 +287,20 @@ namespace armarx::plugins
         } // 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
 
         execution.detach();
-        return execId;
+        return executionId;
     }
 
     void
-    SkillProviderComponentPlugin::addSkillParameters(const skills::SkillExecutionId& id,
+    SkillProviderComponentPlugin::addSkillParameters(const skills::SkillExecutionID& executionId,
                                                      const armarx::aron::data::DictPtr& input)
     {
+        ARMARX_CHECK(executionId.skillId.fullySpecified());
+
         const std::scoped_lock l{skillExecutionsMutex};
-        auto it = skillExecutions.find(id);
+        auto it = skillExecutions.find(executionId);
         if (it == skillExecutions.end())
         {
-            ARMARX_INFO << "No acive execution for skill '" + id.skillId.toString() +
+            ARMARX_INFO << "No acive execution for skill '" + executionId.skillId.toString() +
                                "' found! Ignoring prepareSkill request.";
             return;
         }
@@ -297,7 +308,7 @@ namespace armarx::plugins
         std::scoped_lock l2{it->second.skillStatusesMutex};
         if (it->second.statusUpdate.status != skills::SkillStatus::Preparing)
         {
-            ARMARX_INFO << "Could not prepare the skill '" + id.skillId.toString() +
+            ARMARX_INFO << "Could not prepare the skill '" + executionId.skillId.toString() +
                                "' because its not in preparing phase.";
             return;
         }
@@ -306,13 +317,15 @@ namespace armarx::plugins
     }
 
     void
-    SkillProviderComponentPlugin::abortSkill(const skills::SkillExecutionId& execId)
+    SkillProviderComponentPlugin::abortSkill(const skills::SkillExecutionID& executionId)
     {
+        ARMARX_CHECK(executionId.skillId.fullySpecified());
+
         const std::unique_lock l(skillExecutionsMutex);
-        auto it = skillExecutions.find(execId);
+        auto it = skillExecutions.find(executionId);
         if (it == skillExecutions.end())
         {
-            ARMARX_INFO << "No acive execution for skill '" + execId.skillId.toString() +
+            ARMARX_INFO << "No acive execution for skill '" + executionId.skillId.toString() +
                                "' found! Ignoring abortSkill request.";
             return;
         }
@@ -329,26 +342,18 @@ namespace armarx
         addPlugin(plugin);
     }
 
-    void
-    SkillProviderComponentPluginUser::addSkillFactory(std::unique_ptr<skills::SkillFactory>&& skill)
-    {
-        plugin->addSkillFactory(std::move(skill));
-    }
-
-    void
-    SkillProviderComponentPluginUser::addSkillFactory(const skills::SkillDescription& desc,
-                                                      const skills::LambdaSkill::FunT& f)
-    {
-        plugin->addSkillFactory(f, desc);
-    }
-
-    skills::provider::dto::SkillDescription
+    IceUtil::Optional<skills::provider::dto::SkillDescription>
     SkillProviderComponentPluginUser::getSkillDescription(
         const skills::provider::dto::SkillID& skillId,
         const Ice::Current& /*unused*/)
     {
         auto id = skills::SkillID::FromIce(skillId, getName());
-        return plugin->getSkillDescription(id)->toIce();
+        auto o = plugin->getSkillDescription(id);
+        if (o.has_value())
+        {
+            return o->toProviderIce();
+        }
+        return {};
     }
 
     skills::provider::dto::SkillDescriptionMap
@@ -357,23 +362,23 @@ namespace armarx
         skills::provider::dto::SkillDescriptionMap ret;
         for (const auto& [k, v] : plugin->getSkillDescriptions())
         {
-            ret.insert({k.toProviderIce(), v.toIce()});
+            ret.insert({k.toProviderIce(), v.toProviderIce()});
         }
         return ret;
     }
 
-    skills::provider::dto::SkillStatusUpdate
+    IceUtil::Optional<skills::provider::dto::SkillStatusUpdate>
     SkillProviderComponentPluginUser::getSkillExecutionStatus(
         const skills::provider::dto::SkillExecutionID& executionId,
         const Ice::Current& /*unused*/)
     {
-        auto execId = skills::SkillExecutionId::FromIce(executionId, getName());
+        auto execId = skills::SkillExecutionID::FromIce(executionId, getName());
         auto o = plugin->getSkillExecutionStatus(execId);
         if (o.has_value())
         {
             return o->toProviderIce();
         }
-        return {}; // TODO!!
+        return {};
     }
 
     skills::provider::dto::SkillStatusUpdateMap
@@ -393,7 +398,7 @@ namespace armarx
         const skills::provider::dto::SkillExecutionRequest& info,
         const Ice::Current& /*unused*/)
     {
-        auto exec = skills::SkillExecutionRequest::FromIce(info);
+        auto exec = skills::SkillExecutionRequest::FromIce(info, getName());
         auto up = this->plugin->executeSkill(exec);
         return up.toProviderIce();
     }
@@ -403,7 +408,7 @@ namespace armarx
         const skills::provider::dto::SkillExecutionRequest& info,
         const Ice::Current& current /*unused*/)
     {
-        auto exec = skills::SkillExecutionRequest::FromIce(info);
+        auto exec = skills::SkillExecutionRequest::FromIce(info, getName());
         auto id = this->plugin->executeSkillAsync(exec);
         return id.toProviderIce();
     }
@@ -414,7 +419,7 @@ namespace armarx
         const aron::data::dto::DictPtr& input,
         const Ice::Current& current /*unused*/)
     {
-        auto exec = skills::SkillExecutionId::FromIce(id, getName());
+        auto exec = skills::SkillExecutionID::FromIce(id, getName());
         auto prep = armarx::aron::data::Dict::FromAronDictDTO(input);
         this->plugin->addSkillParameters(exec, prep);
     }
@@ -423,7 +428,7 @@ namespace armarx
     SkillProviderComponentPluginUser::abortSkill(const skills::provider::dto::SkillExecutionID& id,
                                                  const Ice::Current& /*unused*/)
     {
-        auto exec = skills::SkillExecutionId::FromIce(id, getName());
+        auto exec = skills::SkillExecutionID::FromIce(id, getName());
         this->plugin->abortSkill(exec);
     }
 
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
index 881b813c2..9550dec64 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
@@ -49,24 +49,37 @@ namespace armarx::plugins
 
         void preOnDisconnectComponent() override;
 
-        void addSkillFactory(const skills::LambdaSkill::FunT&, const skills::SkillDescription&);
         void addSkillFactory(std::unique_ptr<skills::SkillFactory>&&);
 
-        template <typename T, typename... Args>
+        skills::SkillFactory* addSkillFactory(const skills::SkillDescription&,
+                                              const skills::LambdaSkill::FunT&);
 
-        requires skills::isSkillFactory<T> T*
-        addSkillFactory(const skills::SkillID& id, Args&&... args)
+        template <class _Skill, typename... Args>
+
+        requires skills::isSkill<_Skill> skills::SkillFactory*
+        addSkillFactory(Args&&... args)
         {
-            auto fac = std::make_unique<T>(id, std::forward<Args>(args)...);
+            auto fac = skills::SkillFactory::ForSkill<_Skill>(std::forward<Args>(args)...);
             auto* facPtr = fac.get();
             addSkillFactory(std::move(fac));
-            return static_cast<T*>(facPtr);
+            return static_cast<skills::SkillFactory*>(facPtr);
+        }
+
+        template <typename _FactoryT, typename... Args>
+
+        requires skills::isSkillFactory<_FactoryT> _FactoryT*
+        addCustomSkillFactory(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);
         }
 
         // Ice forwards
         std::optional<skills::SkillStatusUpdate>
-        getSkillExecutionStatus(const skills::SkillExecutionId&) const;
-        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate>
+        getSkillExecutionStatus(const skills::SkillExecutionID&) const;
+        std::map<skills::SkillExecutionID, skills::SkillStatusUpdate>
         getSkillExecutionStatuses() const;
 
         std::optional<skills::SkillDescription> getSkillDescription(const skills::SkillID&) const;
@@ -74,13 +87,13 @@ namespace armarx::plugins
 
         skills::SkillStatusUpdate executeSkill(const skills::SkillExecutionRequest& executionInfo);
 
-        skills::SkillExecutionId
+        skills::SkillExecutionID
         executeSkillAsync(const skills::SkillExecutionRequest& executionInfo);
 
-        void addSkillParameters(const skills::SkillExecutionId& id,
+        void addSkillParameters(const skills::SkillExecutionID& id,
                                 const armarx::aron::data::DictPtr& params);
 
-        void abortSkill(const skills::SkillExecutionId& execId);
+        void abortSkill(const skills::SkillExecutionID& execId);
 
     private:
         skills::SkillFactory* getSkillFactory(const armarx::skills::SkillID& name);
@@ -92,7 +105,7 @@ namespace armarx::plugins
         std::map<skills::SkillID, std::unique_ptr<skills::SkillFactory>> skillFactories;
 
         mutable std::mutex skillExecutionsMutex;
-        std::map<skills::SkillExecutionId, skills::detail::SkillImplementationWrapper>
+        std::map<skills::SkillExecutionID, skills::detail::SkillImplementationWrapper>
             skillExecutions;
 
         friend class armarx::SkillProviderComponentPluginUser;
@@ -100,6 +113,7 @@ namespace armarx::plugins
 } // namespace armarx::plugins
 
 namespace armarx
+
 {
     class SkillProviderComponentPluginUser :
         virtual public ManagedIceObject,
@@ -109,14 +123,14 @@ namespace armarx
         SkillProviderComponentPluginUser();
 
         // Ice Implementations
-        skills::provider::dto::SkillDescription
+        IceUtil::Optional<skills::provider::dto::SkillDescription>
         getSkillDescription(const skills::provider::dto::SkillID& skill,
                             const Ice::Current& current = Ice::Current()) override;
 
         skills::provider::dto::SkillDescriptionMap
         getSkillDescriptions(const Ice::Current& current = Ice::Current()) override;
 
-        skills::provider::dto::SkillStatusUpdate
+        IceUtil::Optional<skills::provider::dto::SkillStatusUpdate>
         getSkillExecutionStatus(const skills::provider::dto::SkillExecutionID& executionId,
                                 const Ice::Current& current = Ice::Current()) override;
 
@@ -144,14 +158,27 @@ namespace armarx
 
     protected:
         // utility
-        void addSkillFactory(const skills::SkillDescription&, const skills::LambdaSkill::FunT&);
-        void addSkillFactory(std::unique_ptr<skills::SkillFactory>&&);
+        skills::SkillFactory*
+        addSkillFactory(const skills::SkillDescription& desc, const skills::LambdaSkill::FunT& f)
+        {
+            auto ret = plugin->addSkillFactory(desc, f);
+            return ret;
+        }
+
+        template <class _Skill, typename... Args>
 
-        template <typename T, typename... Args>
-        T*
+        requires skills::isSkill<_Skill> skills::SkillFactory*
         addSkillFactory(Args&&... args)
         {
-            return plugin->addSkillFactory<T>(std::forward<Args>(args)...);
+            return plugin->addSkillFactory<_Skill>(std::forward<Args>(args)...);
+        }
+
+        template <typename _Fac, typename... Args>
+
+        requires skills::isSkillFactory<_Fac> _Fac*
+        addCustomSkillFactory(Args&&... args)
+        {
+            return plugin->addSkillFactory<_Fac>(std::forward<Args>(args)...);
         }
 
     private:
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
index 0c28fb5a6..3a969b281 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
@@ -6,79 +6,60 @@ namespace armarx
     {
         SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
                                const SkillID& skillId) :
-            manager(manager), skillId(skillId)
+            manager(manager),
+            skillDescription(SkillDescription::FromIce(
+                manager->getSkillDescription(skillId.toManagerIce()).value()))
         {
         }
 
         SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                               const std::string& skillProviderName,
-                               const std::string& skillName) :
-            manager(manager), skillId(skillProviderName, skillName)
-        {
-        }
-
-        SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                               const std::string& skillProviderName,
                                const SkillDescription& skillDesc) :
-            manager(manager), skillId(skillProviderName, skillDesc.skillId.skillName)
+            manager(manager), skillDescription(skillDesc)
         {
+            ARMARX_CHECK(skillDesc.skillId.fullySpecified());
         }
 
         TerminatedSkillStatusUpdate
-        SkillProxy::executeFullSkill(const std::string& executorName,
-                                     const aron::data::DictPtr& params)
+        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 = skillId.toManagerIce();
+            req.skillId = skillDescription.skillId.toManagerIce();
 
-            auto terminatingUpdate = manager->executeSkill(req);
-            return TerminatedSkillStatusUpdate::FromIce(terminatingUpdate);
+            auto terminatingUpdateIce = manager->executeSkill(req);
+            return TerminatedSkillStatusUpdate::FromIce(terminatingUpdateIce);
         }
 
-        IceInternal::Handle<Ice::AsyncResult>
-        SkillProxy::begin_executeFullSkill(const std::string& executorName,
-                                           const aron::data::DictPtr& params)
+        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 = skillId.toManagerIce();
+            req.skillId = skillDescription.skillId.toManagerIce();
 
-            auto future = manager->begin_executeSkill(req);
-            return future;
+            auto execReqIce = manager->executeSkillAsync(req);
+            return SkillExecutionID::FromIce(execReqIce);
         }
 
         void
-        SkillProxy::abortSkill(const std::string& executorName)
+        SkillProxy::abortSkill(const SkillExecutionID& id)
         {
             // TODO: This will be used in the future, do not remove it!
-            (void)executorName;
-            //manager->abortSkill();
+            manager->abortSkill(id.toManagerIce());
         }
 
         aron::data::DictPtr
         SkillProxy::getDefaultParameters(const std::string& profileName)
         {
-            // fabian.peller TODO:
+            if (profileName == "root")
+            {
+                return skillDescription.rootProfileParameterization;
+            }
+            // TODO @fabianPK
             return nullptr;
         }
-
-        TerminatedSkillStatusUpdate
-        SkillProxy::executeFullSkillWithDefaultParams(const std::string& executorName,
-                                                      const std::string& profileName,
-                                                      const aron::data::DictPtr& params)
-        {
-            return executeFullSkill(executorName, params);
-        }
-
-        IceInternal::Handle<Ice::AsyncResult>
-        SkillProxy::begin_executeFullSkillWithDefaultParams(const std::string& executorName,
-                                                            const std::string& profileName,
-                                                            const aron::data::DictPtr& params)
-        {
-            return begin_executeFullSkill(executorName, params);
-        }
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProxy.h b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
index a77c86037..4cb09be79 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProxy.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
@@ -13,38 +13,23 @@ namespace armarx
             SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
                        const SkillID& skillId);
             SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                       const std::string& skillProviderName,
-                       const std::string& skillName);
-            SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
-                       const std::string& skillProviderName,
                        const SkillDescription& skillDesc);
 
             // Provide a similar API as the skillprovider
-            TerminatedSkillStatusUpdate
-            executeFullSkill(const std::string& executorName,
-                             const aron::data::DictPtr& params = nullptr);
-            IceInternal::Handle<Ice::AsyncResult>
-            begin_executeFullSkill(const std::string& executorName,
-                                   const aron::data::DictPtr& params = nullptr);
+            TerminatedSkillStatusUpdate executeSkill(const std::string& executorName,
+                                                const aron::data::DictPtr& params = nullptr);
 
-            void abortSkill(const std::string& executorName);
+            SkillExecutionID executeSkillAsync(const std::string& executorName,
+                                          const aron::data::DictPtr& params = nullptr);
 
-            // Utiliy methods
-            aron::data::DictPtr getDefaultParameters(const std::string& profileName);
+            void abortSkill(const SkillExecutionID& executorName);
 
-            TerminatedSkillStatusUpdate
-            executeFullSkillWithDefaultParams(const std::string& executorName,
-                                              const std::string& profileName,
-                                              const aron::data::DictPtr& params = nullptr);
-            IceInternal::Handle<Ice::AsyncResult>
-            begin_executeFullSkillWithDefaultParams(const std::string& executorName,
-                                                    const std::string& profileName,
-                                                    const aron::data::DictPtr& params = nullptr);
+            // Utiliy methods
+            aron::data::DictPtr getDefaultParameters(const std::string& profileName = "root");
 
         private:
-            const manager::dti::SkillManagerInterfacePrx& manager;
-
-            const SkillID skillId;
+            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 c56953e46..9fc2beba6 100644
--- a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
@@ -14,6 +14,7 @@ namespace armarx
         class SpecializedSkill : public Skill
         {
         public:
+            using Base = Skill;
             using ParamType = AronT;
 
             struct SpecializedMainInput
@@ -34,30 +35,9 @@ namespace armarx
             }
 
 
-        private:
-            /// Do not use anymore
-            Skill::InitResult
-            init() final
-            {
-                return InitResult{.status = TerminatedSkillStatus::Succeeded};
-            }
-
-            /// Do not use anymore
-            Skill::MainResult
-            main() final
-            {
-                ARMARX_IMPORTANT << "Dummy executing skill '" << description.skillId
-                                 << "'. Please overwrite this method.";
-                return Skill::MainResult{.status = TerminatedSkillStatus::Succeeded,
-                                         .data = nullptr};
-            }
-
-            /// Do not use anymore
-            Skill::ExitResult
-            exit() final
-            {
-                return ExitResult{.status = TerminatedSkillStatus::Succeeded};
-            }
+        protected:
+            mutable std::mutex parametersMutex;
+            AronT parameters;
         };
     } // 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 bbe71e6ae..6846cca66 100644
--- a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
+++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
@@ -6,7 +6,7 @@ namespace armarx
     {
         SkillImplementationWrapper::SkillImplementationWrapper(
             const skills::SkillFactory* fac,
-            const skills::SkillExecutionId& execId,
+            const skills::SkillExecutionID& execId,
             const skills::SkillParameterization& param) :
             factory(fac), statusUpdate(execId, param)
         {
@@ -57,11 +57,13 @@ 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());
+
             const auto initial_aron_params = statusUpdate.usedParameterization.parameterization;
             const auto callback_interface = statusUpdate.usedParameterization.callbackInterface;
             const auto skillId = statusUpdate.executionId.skillId;
             const auto skillName = skillId.skillName;
-            const auto providerName = skillId.providerName;
+            const auto providerId = *skillId.providerId;
             const auto executorName = statusUpdate.executionId.executorName;
 
             ARMARX_INFO_S << "Executing skill: " << skillName;
@@ -72,11 +74,15 @@ namespace armarx
                 std::unique_lock l(skillStatusesMutex);
                 statusUpdate.status = status;
                 statusUpdate.data = data;
-                statusUpdate.usedParameterization.parameterization = skill->parameters;
+                if (skill) // if skill has been constructed
+                {
+                    // update parameterization
+                    statusUpdate.usedParameterization.parameterization = skill->getParameters();
+                }
 
-                if (callback_interface)
+                if (callback_interface) // if callback interface is used
                 {
-                    skills::provider::dto::ProviderID pid({providerName});
+                    auto pid = providerId.toCallbackIce();
                     callback_interface->updateStatusForSkill(statusUpdate.toProviderIce(), pid);
                 }
             };
@@ -110,7 +116,7 @@ namespace armarx
             // construct skill
             // -------------------------------------------------------------------------------------
             updateStatus(SkillStatus::Constructing);
-            this->skill = this->factory->createSkill();
+            this->skill = this->factory->createSkill(providerId);
             this->skill->executorName = (executorName);
             this->skill->callback = [&](const SkillStatus s, const armarx::aron::data::DictPtr& d)
             { updateStatus(s, d); };
@@ -131,15 +137,16 @@ namespace armarx
             // -------------------------------------------------------------------------------------
             // Check params
             // -------------------------------------------------------------------------------------
-            if (skill->description.acceptedType && initial_aron_params &&
-                not(initial_aron_params->fullfillsType(skill->description.acceptedType)))
-            {
-                std::string message =
-                    "SkillError 002: The Skill '" + skillName +
-                    "' has a type and got parameters but the input does not match the type.";
-                ARMARX_ERROR_S << message;
-                return makeTerminationResult(message);
-            }
+            // NOT RELEVANT ANYMORE!!
+            //            if (skill->getSkillDescription().acceptedType && initial_aron_params &&
+            //                not(initial_aron_params->fullfillsType(skill->getSkillDescription().acceptedType)))
+            //            {
+            //                std::string message =
+            //                    "SkillError 002: The Skill '" + skillName +
+            //                    "' has a type and got parameters but the input does not match the type.";
+            //                ARMARX_ERROR_S << message;
+            //                return makeTerminationResult(message);
+            //            }
 
 
             auto exitAndMakeTerminationResult = [&](const std::string& message)
@@ -181,11 +188,22 @@ namespace armarx
 
                 // set initial parameters that were attached to the execution request
                 skill->addParameters(initial_aron_params);
-                while (not skill->skillPreparationFinished())
+                auto prepareRet = skill->prepareSkill();
+                while (prepareRet.status == ActiveOrTerminatedSkillStatus::Running)
                 {
+                    ARMARX_INFO << deactivateSpam() << "Not all requirements for skill "
+                                << skillName << " fulfilled. Waiting...";
+
                     // wait...
-                    skill->prepareSkill();
-                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
+                    prepareRet = skill->prepareSkill();
+                    std::this_thread::sleep_for(std::chrono::milliseconds(50));
+                }
+
+                if (prepareRet.status != ActiveOrTerminatedSkillStatus::Succeeded)
+                {
+                    std::string message = "SkillError 201: The prepare method of skill '" +
+                                          skillName + "' did not succeed.";
+                    return exitAndMakeTerminationResult(message);
                 }
             }
 
diff --git a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
index 8ae7dcf77..c57a05485 100644
--- a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
+++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
@@ -32,7 +32,7 @@ namespace armarx
 
                 // ctor
                 SkillImplementationWrapper(const skills::SkillFactory* fac,
-                                           const skills::SkillExecutionId&,
+                                           const skills::SkillExecutionID&,
                                            const skills::SkillParameterization&);
 
                 // execute a skill. The parameterization is copied. T
-- 
GitLab