diff --git a/scenarios/SkillProviderTest/config/SkillsMemory.cfg b/scenarios/SkillProviderTest/config/SkillsMemory.cfg
index 57d1fbc563156ae096bdaad0324321323a1a0724..fc086fbe56a016013571883b41f8f8fb721f55b6 100644
--- a/scenarios/SkillProviderTest/config/SkillsMemory.cfg
+++ b/scenarios/SkillProviderTest/config/SkillsMemory.cfg
@@ -18,6 +18,15 @@
 # ArmarX.ApplicationName = ""
 
 
+# ArmarX.AutodiscoverPackages:  If enabled, will discover all ArmarX packages based on the environment variables. Otherwise, the `DefaultPackages` and `AdditionalPackages` properties are used.
+#  Attributes:
+#  - Default:            true
+#  - Case sensitivity:   yes
+#  - Required:           no
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.AutodiscoverPackages = true
+
+
 # ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
@@ -175,21 +184,13 @@
 # ArmarX.SkillMemory.mem.ltm.configuration = {"SnapshotFrequencyFilter": { "WaitingTimeInMs": 1000}, "PngConverter": {}}
 
 
-# ArmarX.SkillMemory.mem.ltm.enable_querying:  
+# ArmarX.SkillMemory.mem.ltm.enabled:  
 #  Attributes:
 #  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
 #  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.enable_querying = false
-
-
-# ArmarX.SkillMemory.mem.ltm.mode:  
-#  Attributes:
-#  - Default:            DISABLED
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.SkillMemory.mem.ltm.mode = DISABLED
+# ArmarX.SkillMemory.mem.ltm.enabled = false
 
 
 # ArmarX.SkillMemory.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
index 7ebd7960d7db1239182b064aaa1b082a20bdbe41..00f5da8322d38c9acdbaf43207c5c159497fb688 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
@@ -135,42 +135,35 @@ namespace armarx
     }
 
     void
-    SkillsMemory::removeProvider(const std::string& skillProviderName, const Ice::Current& current)
+    SkillsMemory::removeProvider(const skills::manager::dto::ProviderID& provider,
+                                 const Ice::Current& current)
     {
-        executableSkillCoreSegment.removeSkillProvider(skillProviderName);
+        executableSkillCoreSegment.removeSkillProvider(provider.providerName);
 
         // remove skills from memory
-        SkillManagerComponentPluginUser::removeProvider(skillProviderName, current);
+        SkillManagerComponentPluginUser::removeProvider(provider, current);
     }
 
     skills::manager::dto::SkillStatusUpdate
     SkillsMemory::executeSkill(const skills::manager::dto::SkillExecutionRequest& info,
                                const Ice::Current& current)
     {
-        skills::manager::dto::SkillExecutionRequest requestCopy = info;
-        if (requestCopy.skillId.providerName == "*")
-        {
-            // sanitize the provider name if set to 'any'
-            requestCopy.skillId.providerName =
-                getFirstProviderNameThatHasSkill(requestCopy.skillId.skillName);
-        }
-
-        skillExecutionRequestCoreSegment.addSkillExecutionRequest(requestCopy);
-        return SkillManagerComponentPluginUser::executeSkill(requestCopy, current);
+        skillExecutionRequestCoreSegment.addSkillExecutionRequest(info);
+        return SkillManagerComponentPluginUser::executeSkill(info, current);
     }
 
     void
     SkillsMemory::updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
-                                       const std::string& providerName,
+                                       const skills::provider::dto::ProviderID& providerId,
                                        const Ice::Current& current)
     {
-        skillEventCoreSegment.addSkillUpdateEvent(update, providerName);
+        skillEventCoreSegment.addSkillUpdateEvent(update, providerId.providerName);
     }
 
-    skills::provider::dto::SkillStatusUpdateList
+    skills::provider::dto::SkillStatusUpdateMap
     SkillsMemory::getLatestSkillExecutionStatuses(int n, const Ice::Current& current)
     {
-        return {};
+        return {}; // TODO
     }
 
     /*
diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
index d0b92b485024b7c80ab11b52d4ff28b9893aca23..da7e3df478f3a81d864868c5c489a73af45e15df 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h
@@ -77,14 +77,19 @@ namespace armarx
         // Override SkillManager to add memory functions
         void addProvider(const skills::manager::dto::ProviderInfo& info,
                          const Ice::Current& current) override;
-        void removeProvider(const std::string&, const Ice::Current& current) override;
+
+        void removeProvider(const skills::manager::dto::ProviderID& provider,
+                            const Ice::Current& current) override;
+
         skills::manager::dto::SkillStatusUpdate
         executeSkill(const skills::manager::dto::SkillExecutionRequest& info,
                      const Ice::Current& current) override;
-        void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& statusUpdate,
-                                  const std::string& providerName,
+
+        void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
+                                  const skills::provider::dto::ProviderID& id,
                                   const Ice::Current& current) override;
-        skills::provider::dto::SkillStatusUpdateList
+
+        skills::provider::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 5e5fb58b7ea03440fa7eb69ae8ccd12bc3752cd5..401335868abd5fceddd0d57c05e689e618dbd3e8 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
@@ -2,11 +2,10 @@
 
 #include "SkillProviderExample.h"
 
+#include <RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.aron.generated.h>
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 #include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
 #include <RobotAPI/libraries/aron/core/type/variant/primitive/String.h>
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-
-#include <RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.aron.generated.h>
 
 namespace armarx::skills::provider
 {
@@ -24,24 +23,20 @@ namespace armarx::skills::provider
         root_profile_params.some_list_of_matrices.push_back(Eigen::Matrix3f::Zero());
         //default_params.some_matrix = Eigen::Matrix3f::Zero();
 
-        SkillProfile rootProfile{SkillProfile::ROOT_PROFILE_NAME,
-                                 SkillProfile::NO_PREDECESSOR,
-                                 root_profile_params.toAron()};
-
-        return SkillDescription{"HelloWorld",
+        return SkillDescription{{"HelloWorld"},
                                 "This skill logs a message on ARMARX_IMPORTANT",
-                                {{rootProfile.profileName, rootProfile}},
+                                root_profile_params.toAron(),
                                 armarx::core::time::Duration::MilliSeconds(1000),
                                 armarx::skills::Example::HelloWorldAcceptedType::ToAronType()};
     }
 
     Skill::MainResult
-    HelloWorldSkill::main(const MainInput& in)
+    HelloWorldSkill::main()
     {
         ARMARX_IMPORTANT << "Hi, from the Hello World Skill.\n"
                          << "I received the following data: \n"
                          << aron::data::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(
-                                in.params)
+                                parameters)
                                 .dump(2)
                          << "\n"
                          << "(executed at: " << IceUtil::Time::now() << ")";
@@ -55,7 +50,7 @@ namespace armarx::skills::provider
     SkillDescription
     ChainingSkill::GetSkillDescription()
     {
-        return SkillDescription{"ChainingSkill",
+        return SkillDescription{{"ChainingSkill"},
                                 "This skill calls the HelloWorld skill three times.",
                                 {},
                                 armarx::core::time::Duration::MilliSeconds(3000),
@@ -63,7 +58,7 @@ namespace armarx::skills::provider
     }
 
     Skill::MainResult
-    ChainingSkill::main(const MainInput& in)
+    ChainingSkill::main()
     {
         armarx::skills::Example::HelloWorldAcceptedType exec1;
         armarx::skills::Example::HelloWorldAcceptedType exec2;
@@ -90,7 +85,7 @@ namespace armarx::skills::provider
     SkillDescription
     TimeoutSkill::GetSkillDescription()
     {
-        return SkillDescription{"Timeout",
+        return SkillDescription{{"Timeout"},
                                 "This fails with timeout reached",
                                 {},
                                 armarx::core::time::Duration::MilliSeconds(1000),
@@ -98,7 +93,7 @@ namespace armarx::skills::provider
     }
 
     PeriodicSkill::StepResult
-    TimeoutSkill::step(const MainInput& in)
+    TimeoutSkill::step()
     {
         // do heavy work
         std::this_thread::sleep_for(std::chrono::milliseconds(200));
@@ -113,7 +108,7 @@ namespace armarx::skills::provider
     SkillDescription
     CallbackSkill::GetSkillDescription()
     {
-        return SkillDescription{"ShowMeCallbacks",
+        return SkillDescription{{"ShowMeCallbacks"},
                                 "This skill does shows callbacks",
                                 {},
                                 armarx::core::time::Duration::MilliSeconds(1000),
@@ -121,20 +116,21 @@ namespace armarx::skills::provider
     }
 
     Skill::MainResult
-    CallbackSkill::main(const MainInput& in)
+    CallbackSkill::main()
     {
         ARMARX_IMPORTANT << "Logging three updates via the callback";
         auto up1 = std::make_shared<aron::data::Dict>();
         up1->addElement("updateInfo", std::make_shared<aron::data::String>("Update 1"));
-        in.callback(up1);
+
+        this->callback(skills::SkillStatus::Running, up1);
 
         auto up2 = std::make_shared<aron::data::Dict>();
         up2->addElement("updateInfo", std::make_shared<aron::data::String>("Update 2"));
-        in.callback(up2);
+        this->callback(skills::SkillStatus::Running, up2);
 
         auto up3 = std::make_shared<aron::data::Dict>();
         up3->addElement("updateInfo", std::make_shared<aron::data::String>("Update 3"));
-        in.callback(up3);
+        this->callback(skills::SkillStatus::Running, up3);
 
         return {TerminatedSkillStatus::Succeeded, nullptr};
     }
@@ -161,51 +157,31 @@ namespace armarx::skills::provider
     SkillProviderExample::onInitComponent()
     {
         // Add example skill
-        addSkill(std::make_unique<HelloWorldSkill>());
-
-        // Add another lambda example skill
-        {
-            skills::SkillDescription fooDesc;
-            fooDesc.acceptedType = nullptr; // accept everything
-            fooDesc.description = "This skill does exactly nothing.";
-            fooDesc.skillName = "Foo";
-            fooDesc.timeout = armarx::core::time::Duration::MilliSeconds(1000);
-            addSkill(
-                [](const std::string& clientId, const aron::data::DictPtr&)
-                {
-                    std::cout << "Hello from Foo. The skill was called from " << clientId << "."
-                              << std::endl;
-                    return TerminatedSkillStatus::Succeeded;
-                },
-                fooDesc);
-        }
+        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<HelloWorldSkill>());
 
         // Add another lambda example skill
         {
-            skills::SkillDescription fooDesc;
-            fooDesc.acceptedType = nullptr; // accept everything
-            fooDesc.description = "This skill dies hard.";
-            fooDesc.skillName = "Die";
-            fooDesc.timeout = armarx::core::time::Duration::MilliSeconds(1000);
-            addSkill(
-                [](const std::string& clientId, const aron::data::DictPtr&)
-                {
-                    std::cout << "bye bye... segfaulting on purpose now!" << std::endl;
-                    Skill* nullSkill = NULL;
-                    nullSkill->getSkillId(); // DEAD!
-                    return TerminatedSkillStatus::Succeeded;
-                },
-                fooDesc);
+            skills::SkillDescription fooDesc({"Foo"},
+                                             "This skill does exactly nothing.",
+                                             nullptr,
+                                             armarx::core::time::Duration::MilliSeconds(1000),
+                                             nullptr);
+            addSkillFactory(fooDesc,
+                            []()
+                            {
+                                std::cout << "Hello from Foo." << std::endl;
+                                return TerminatedSkillStatus::Succeeded;
+                            });
         }
 
         // Add another example skill
-        addSkill(std::make_unique<CallbackSkill>());
+        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<CallbackSkill>());
 
         // Add timeout skill
-        addSkill(std::make_unique<TimeoutSkill>());
+        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<TimeoutSkill>());
 
         // chaining
-        addSkill(std::make_unique<ChainingSkill>());
+        addSkillFactory(SkillFactory::ForSkillDescriptionGetter<ChainingSkill>());
     }
 
     void
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
index 2aad033f1f00a2523dd8dcf15b03979eab92b339..ea8f114eb76453a4a23511d0aa24ba4b511d0eb8 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h
@@ -41,7 +41,7 @@ namespace armarx::skills::provider
         static SkillDescription GetSkillDescription();
 
     private:
-        Skill::MainResult main(const MainInput& in) final;
+        Skill::MainResult main() final;
     };
 
     class ChainingSkill : public Skill
@@ -52,7 +52,7 @@ namespace armarx::skills::provider
         static SkillDescription GetSkillDescription();
 
     private:
-        Skill::MainResult main(const MainInput& in) final;
+        Skill::MainResult main() final;
     };
 
     class TimeoutSkill : public PeriodicSkill
@@ -63,7 +63,7 @@ namespace armarx::skills::provider
         static SkillDescription GetSkillDescription();
 
     private:
-        PeriodicSkill::StepResult step(const MainInput& in) final;
+        PeriodicSkill::StepResult step() final;
     };
 
     class CallbackSkill : public Skill
@@ -74,7 +74,7 @@ namespace armarx::skills::provider
         static SkillDescription GetSkillDescription();
 
     private:
-        Skill::MainResult main(const MainInput& in) final;
+        Skill::MainResult main() final;
     };
 
     /**
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
index d2a43c02ebcc3997b6e8bb3acf86e2445cf864c7..127db31f07149e430abb8442eb4383d5d9adc28d 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
@@ -24,7 +24,7 @@
 
 #include <string>
 
-#include <RobotAPI/libraries/skills/provider/Skill.h>
+#include <RobotAPI/libraries/skills/core/Skill.h>
 
 #include "aronTreeWidget/visitors/AronTreeWidgetConverter.h"
 #include "aronTreeWidget/visitors/AronTreeWidgetCreator.h"
@@ -41,7 +41,7 @@
 
 #include "aronTreeWidget/Data.h"
 
-//config
+//configSk
 namespace armarx
 {
     QPointer<QDialog>
@@ -202,15 +202,14 @@ namespace armarx
 
             auto managerSkills = manager->getSkillDescriptions();
 
-            std::vector<std::string> removedProviders;
+            std::vector<armarx::skills::manager::dto::SkillID> removedSkills;
             for (auto it = skills.begin(); it != skills.end();)
             {
-                // TODO: iterate over skills, not just over providers!
-                std::string providerName = it->first;
-                if (managerSkills.find(providerName) == managerSkills.end())
+                auto pid = it->first;
+                if (managerSkills.find(pid) == managerSkills.end())
                 {
-                    ARMARX_DEBUG << "REMOVE " << providerName;
-                    removedProviders.push_back(providerName);
+                    ARMARX_DEBUG << "REMOVE " << pid;
+                    removedSkills.push_back(pid);
                     it = skills.erase(it);
                 }
                 else
@@ -220,13 +219,13 @@ namespace armarx
             }
 
             // add new ones
-            std::vector<std::string> newProviders;
-            for (const auto& [providerName, providerSkills] : managerSkills)
+            std::vector<armarx::skills::manager::dto::SkillID> newSkills;
+            for (const auto& [skillID, providerSkills] : managerSkills)
             {
-                if (skills.find(providerName) == skills.end())
+                if (skills.find(skillID) == skills.end())
                 {
-                    skills.insert(std::make_pair(providerName, providerSkills));
-                    newProviders.push_back(providerName);
+                    skills.insert(std::make_pair(skillID, providerSkills));
+                    newSkills.push_back(skillID);
                 }
             }
 
@@ -236,10 +235,9 @@ namespace armarx
             while (i < widget.treeWidgetSkills->topLevelItemCount())
             {
                 QTreeWidgetItem* item = widget.treeWidgetSkills->topLevelItem(i);
-                if (auto it = std::find(removedProviders.begin(),
-                                        removedProviders.end(),
-                                        item->text(0).toStdString());
-                    it != removedProviders.end())
+                if (auto it = std::find(
+                        removedSkills.begin(), removedSkills.end(), item->text(0).toStdString());
+                    it != removedSkills.end())
                 {
                     delete widget.treeWidgetSkills->takeTopLevelItem(i);
                 }
@@ -252,8 +250,8 @@ namespace armarx
             // add new providers
             for (const auto& [providerName, providerSkills] : skills)
             {
-                if (auto it = std::find(newProviders.begin(), newProviders.end(), providerName);
-                    it != newProviders.end())
+                if (auto it = std::find(newSkills.begin(), newSkills.end(), providerName);
+                    it != newSkills.end())
                 {
                     auto item = new QTreeWidgetItem(widget.treeWidgetSkills);
                     item->setText(0, QString::fromStdString(providerName));
@@ -282,9 +280,10 @@ namespace armarx
             {skills::SkillStatus::Succeeded, "Succeeded"},
 
             // Others
-            {skills::SkillStatus::Idle, "Not yet started"},
+            {skills::SkillStatus::Constructing, "Under construction"},
             {skills::SkillStatus::Running, "Running"},
-            {skills::SkillStatus::Scheduled, "Scheduled"}};
+            {skills::SkillStatus::Initializing, "Initializing"},
+            {skills::SkillStatus::Preparing, "Preparing"}};
 
         if (!manager)
         {
@@ -311,7 +310,7 @@ namespace armarx
                     item->setText(0, QString::fromStdString("TODO:"));
                     item->setText(
                         1, QString::fromStdString(statusUpdate.executionId.skillId.toString()));
-                    if (statusUpdate.hasBeenScheduled())
+                    if (statusUpdate.hasBeenInitialized())
                     {
                         item->setText(
                             2, QString::fromStdString("YES (TODO:)")); // when was skill scheduled
@@ -419,7 +418,10 @@ namespace armarx
 
         ARMARX_INFO << "Stopping skill from GUI: " << selectedSkill.providerName << "/"
                     << selectedSkill.skillName;
-        manager->abortSkill(selectedSkill.providerName, selectedSkill.skillName);
+
+        auto id =
+            skills::manager::dto::SkillID{selectedSkill.providerName, selectedSkill.skillName};
+        manager->abortSkill(id);
     }
 
     void
@@ -468,17 +470,17 @@ namespace armarx
         auto skillDesc = skills.at(selectedSkill.providerName).at(selectedSkill.skillName);
 
         {
-            auto it = new QTreeWidgetItem(
-                widget.treeWidgetSkillDetails,
-                {QString::fromStdString("Name"), QString::fromStdString(skillDesc.skillName)});
+            auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
+                                          {QString::fromStdString("Name"),
+                                           QString::fromStdString(skillDesc.skillId.skillName)});
             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), ", "))});
+                                           QString::fromStdString("" /*simox::alg::join(
+                                               simox::alg::get_keys(skillDesc.profiles), ", ")*/)});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
@@ -490,10 +492,13 @@ 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(skillDesc.timeoutMs)) + " ms"});
+                 QString::fromStdString(std::to_string(d.toMilliSeconds())) + " ms"});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
index 821000d85ecfb6c7f2b2d25cd6db812ab0061125..d3fb1250f0d32b5f78c96c94c6b37bfd570fb3f1 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
@@ -38,7 +38,7 @@
 #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/provider/SkillStatusUpdate.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 #include "aronTreeWidget/AronTreeWidgetController.h"
 
@@ -111,7 +111,7 @@ namespace armarx
 
         // Data taken from observer (snapshot of it)
         mutable std::mutex updateMutex;
-        skills::manager::dto::SkillDescriptionMapMap skills = {};
+        skills::manager::dto::SkillDescriptionMap skills = {};
         std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> pastSkillStatusUpdates = {};
 
         // User Input
diff --git a/source/RobotAPI/interface/skills/SkillManagerInterface.ice b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
index 17a07d8bcdf22678a551c56bf4b17a97c939532c..adda483ada28b7957bd2de1d3fa9e8e5e00d7e6d 100644
--- a/source/RobotAPI/interface/skills/SkillManagerInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
@@ -39,6 +39,18 @@ module armarx
                     string skillName;
                 };
 
+                struct ProviderID
+                {
+                    string providerName;
+                };
+
+                struct ProviderInfo
+                {
+                    ProviderID providerId;
+                    provider::dti::SkillProviderInterface* provider;
+                    provider::dto::SkillDescriptionMap providedSkills;
+                };
+
                 // The minimum information that is needed to uniquely identifying a past skill execution
                 struct SkillExecutionID
                 {
@@ -47,6 +59,7 @@ module armarx
                         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
+                    string uuid;
                 };
 
                 // Status updates of a skill (similar to the status update of the providers except the skillID)
@@ -67,7 +80,7 @@ module armarx
                         data; // data, attached to the status update. If send via a callback, this data may be used by the callback interface
                 };
 
-                sequence<SkillStatusUpdate> SkillStatusUpdateList;
+                dictionary<SkillExecutionID, SkillStatusUpdate> SkillStatusUpdateMap;
 
                 struct SkillExecutionRequest
                 {
@@ -78,15 +91,8 @@ module armarx
                         params; // the parameters for the skill. Can be nullptr if the skill does not require parameters
                 };
 
-                struct ProviderInfo
-                {
-                    string providerName;
-                    provider::dti::SkillProviderInterface* provider;
-                    provider::dto::SkillDescriptionMap providedSkills;
-                };
-
                 // Provider data types
-                dictionary<string, provider::dto::SkillDescriptionMap> SkillDescriptionMapMap;
+                dictionary<SkillID, provider::dto::SkillDescription> SkillDescriptionMap;
             }
 
             module dti
@@ -94,25 +100,33 @@ module armarx
                 interface SkillManagerInterface extends
                     callback::dti::SkillProviderCallbackInterface
                 {
-                    // !! There is by design no method to get the ProviderInfo. You should only communicate with the manager !!
+                    // !! There is by design no method to get a proxy of the provider. You should only communicate with the manager !!
 
                     void addProvider(dto::ProviderInfo providerInfo);
 
-                    void removeProvider(string providerName);
+                    void removeProvider(dto::ProviderID provider);
 
-                    dto::SkillDescriptionMapMap
+                    dto::SkillDescriptionMap
                     getSkillDescriptions(); // get all skilldescriptions from all providers
 
                     dto::SkillStatusUpdate
                     getSkillExecutionStatus(dto::SkillExecutionID executionId);
 
-                    dto::SkillStatusUpdateList
+                    dto::SkillStatusUpdateMap
                     getSkillExecutionStatuses(); // returns the current executions from all providers
 
                     dto::SkillStatusUpdate
-                    executeSkill(dto::SkillExecutionRequest skillExecutionInfo);
+                    executeSkill(dto::SkillExecutionRequest
+                                     skillExecutionInfo); // blocks until skill is finished.
+
+                    dto::SkillExecutionID executeSkillAsync(
+                        dto::SkillExecutionRequest
+                            skillExecutionRequest); // directly returns the execution id
+
+                    void addSkillParameters(dto::SkillExecutionID executionId,
+                                            aron::data::dto::Dict params); // add params to a skill
 
-                    void abortSkill(string providerName, string skillName);
+                    void abortSkill(dto::SkillExecutionID execId); // notify a skill to stop ASAP.
                 };
             }
         }
diff --git a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice
index 09e5db8712062f63759c11d92bc66d6af5875470..15a3dc3798bf695607c4e8a2c870b63910ed47c7 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::SkillStatusUpdateList getLatestSkillExecutionStatuses(
+                provider::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 300054875b5948ba23a75563928e9b7cd55237d6..31449a86d2cbccaabe4c2c5ecf9f9950f529d353 100644
--- a/source/RobotAPI/interface/skills/SkillProviderInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillProviderInterface.ice
@@ -53,36 +53,51 @@ module armarx
             {
                 sequence<string> StringList;
 
-                // A parameterization profile
-                struct SkillProfile
+                // A profile is something that is client side!
+                //                // A parameterization profile
+                //                struct SkillProfile
+                //                {
+                //                    string profileName;
+                //                    string predecessorProfileName; // may be empty
+                //                    aron::data::dto::Dict
+                //                        parameterization; // may be only a partial set of accepted type
+                //                };
+
+                //                // A list of parameterization profiles. Note that the first element is recognized as root. Following elements overwrite the previous.
+                //                dictionary<string, SkillProfile> SkillProfileDict;
+
+                // A skill ID. Must be unique within one SkillManager
+                struct SkillID
                 {
-                    string profileName;
-                    string predecessorProfileName; // may be empty
-                    aron::data::dto::Dict parameterization;
+                    string skillName;
                 };
 
-                // A list of parameterization profiles. Note that the first element is recognized as root. Following elements overwrite the previous.
-                dictionary<string, SkillProfile> SkillProfileDict;
+                // 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
                 {
-                    string skillName; // the name of the skill
+                    SkillID skillId; // the id of the skill
                     string
                         description; // a human readable description of what the skill does. Used in GUI
-                    SkillProfileDict profiles; // a dict of profiles
-                    long timeoutMs; // in milliseconds, can be set to -1 for infinite
+                    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
                 };
 
-                dictionary<string, SkillDescription> SkillDescriptionMap;
+                dictionary<SkillID, SkillDescription> SkillDescriptionMap;
 
                 // Input to a provider to execute a skill
                 struct SkillExecutionRequest
                 {
-                    string skillName; // the id of the skill
+                    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
@@ -95,11 +110,12 @@ module armarx
                 {
                     enum Status
                     {
-                        Idle,
-                        Scheduled,
+                        Constructing,
+                        Initializing,
+                        Preparing,
                         Running,
 
-                        // terminating values, after execution a skill goes back to idle
+                        // terminating values
                         Failed,
                         Succeeded,
                         Aborted
@@ -109,11 +125,12 @@ module armarx
                 // The minimum information that is needed to uniquely identifying a past skill execution
                 struct SkillExecutionID
                 {
-                    string skillName; // the name of the skill
+                    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
+                    string uuid;
                 };
 
                 // Status updates of a skill
@@ -133,27 +150,36 @@ module armarx
                         data; // data, attached to the status update. If send via a callback, this data may be used by the callback interface
                 };
 
-                sequence<SkillStatusUpdate> SkillStatusUpdateList;
+                dictionary<SkillExecutionID, SkillStatusUpdate> SkillStatusUpdateMap;
             }
 
             module dti
             {
                 interface SkillProviderInterface
                 {
-                    dto::SkillDescription getSkillDescription(string name);
+                    dto::SkillDescription getSkillDescription(dto::SkillID skill);
+
                     dto::SkillDescriptionMap getSkillDescriptions();
+
                     dto::SkillStatusUpdate
                     getSkillExecutionStatus(dto::SkillExecutionID executionId);
-                    dto::SkillStatusUpdateList
-                    getSkillExecutionStatuses(); // returns all current skill executions chronologically
+
+                    dto::SkillStatusUpdateMap
+                    getSkillExecutionStatuses(); // returns all current skill executions
 
                     // execute skill will ALWAYS fully execute the skill and wait, until the skill is finished.
-                    // Use the _begin() method, if you want to call a skill async
+                    // TODO: Explain skill phases
                     // This method returns a status update where the status is ALWAYS one of the terminating values
                     dto::SkillStatusUpdate executeSkill(dto::SkillExecutionRequest executionInfo);
 
+                    dto::SkillExecutionID
+                    executeSkillAsync(dto::SkillExecutionRequest executionInfo);
+
+                    void addSkillParameters(dto::SkillExecutionID executionId,
+                                            aron::data::dto::Dict params); // add params to a skill
+
                     // try to kill a skill as soon as possible. When the skill is stopped depends on the implementation.
-                    void abortSkill(string skill);
+                    void abortSkill(dto::SkillExecutionID skill);
                 };
             }
         }
@@ -167,13 +193,17 @@ module armarx
     {
         module callback
         {
+            module dto
+            {
+            }
+
             module dti
             {
                 interface SkillProviderCallbackInterface
                 {
                     // used for callbacks from providers to update their skill execution status
                     void updateStatusForSkill(provider::dto::SkillStatusUpdate statusUpdate,
-                                              string providerName);
+                                              provider::dto::ProviderID providerId);
                 }
             }
         }
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
index a5822667f61138a40a9f581de8dc68fb7fd812d6..d6635696acd4f72d3c3342423233a459baf89af0 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
@@ -1119,6 +1119,12 @@ namespace armarx::armem::server::obj::instance
 
         for (const auto& object : scene.objects)
         {
+            if (simox::alg::starts_with(object.className, "#"))
+            {
+                // marked to be ignored
+                continue;
+            }
+
             const ObjectID classID = object.getClassID(objectFinder);
 
             objpose::ObjectPose& pose = objectPoses.emplace_back();
diff --git a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
index a4f7400e94ae9ee33d5eb82034b1c6eb37799484..9b218af037e355e1682fae745d7528ed2ce1ce45 100644
--- a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
+++ b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml
@@ -37,18 +37,16 @@ The memory should look like the following:
                 <String />
             </ObjectChild>
 
-            <ObjectChild key='profiles'>
-                <Dict>
-                    <armarx::skills::arondto::SkillProfile />
-                </Dict>
+            <ObjectChild key='rootProfileParameterization'>
+                <AnyObject shared_ptr="1" />
             </ObjectChild>
 
             <ObjectChild key='iceInfo'>
                 <String />
             </ObjectChild>
 
-            <ObjectChild key='timeoutMs'>
-                <int64 />
+            <ObjectChild key='timeout'>
+                <Duration />
             </ObjectChild>
 
             <ObjectChild key='acceptedType'>
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp
index 89660232b7d16f7cbdf4f4ceef0c6d666e1d8ecd..51d783b81d880f27a22cfdeef6a538f9d9a60596 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp
@@ -2,6 +2,8 @@
 
 #include <SimoxUtility/algorithm/string.h>
 
+#include <ArmarXCore/core/time/ice_conversions.h>
+
 #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
 #include <RobotAPI/libraries/aron/converter/datatype/DatatypeConverterVisitor.h>
@@ -35,23 +37,19 @@ namespace armarx::skills::segment
         // add skills
         auto skills = info.providedSkills;
 
-        auto provId = id().withProviderSegmentName(info.providerName);
+        auto provId = id().withProviderSegmentName(info.providerId.providerName);
 
         for (const auto& [key, desc] : skills)
         {
             armarx::skills::arondto::SkillDescription skillDescription;
-            skillDescription.skillName = desc.skillName;
+            skillDescription.skillName = desc.skillId.skillName;
             skillDescription.description = desc.description;
             skillDescription.iceInfo = info.provider->ice_toString();
-            for (const auto& [key, p] : desc.profiles)
-            {
-                skillDescription.profiles[key] = {};
-                skillDescription.profiles[key].profileName = p.profileName;
-                skillDescription.profiles[key].predecessorProfileName = p.predecessorProfileName;
-                skillDescription.profiles[key].parameterization =
-                    aron::data::Dict::FromAronDictDTO(p.parameterization);
-            }
-            skillDescription.timeoutMs = desc.timeoutMs;
+
+            skillDescription.rootProfileParameterization =
+                armarx::aron::data::Dict::FromAronDictDTO(desc.rootProfileDefaults);
+
+            armarx::core::time::fromIce(desc.timeout, skillDescription.timeout);
 
             if (desc.acceptedType)
             {
diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
index 8eb81c1647460d19e6a09ece3bd2acaa6551afd8..8960afd4b9aa84e9b93e132e648d35c465b7f371 100644
--- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
+++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp
@@ -5,7 +5,7 @@
 #include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h>
 #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h>
 #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-#include <RobotAPI/libraries/skills/provider/SkillStatusUpdate.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 namespace armarx::skills::segment
 {
@@ -37,8 +37,9 @@ namespace armarx::skills::segment
         // add update for skill to memory
         static std::map<armarx::skills::provider::dto::Execution::Status, std::string>
             ExecutionStatus2String = {
-                {armarx::skills::provider::dto::Execution::Status::Idle, "Idle"},
-                {armarx::skills::provider::dto::Execution::Status::Scheduled, "Scheduled"},
+                {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"},
@@ -51,7 +52,7 @@ namespace armarx::skills::segment
         event.providerName = up.executionId.skillId.providerName;
         event.skillName = up.executionId.skillId.skillName;
         event.status = ExecutionStatus2String.at(update.header.status);
-        event.params = up.usedParameterization.usedInputParams;
+        event.params = up.usedParameterization.parameterization;
         event.data = up.data;
 
         armem::MemoryID commitId = id();
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 21235afefb794e8c78443e840a240f56c6720b14..bed88039981cf50fd3897619d60981085c9c4738 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
@@ -193,6 +193,36 @@ namespace armarx::aron::data
         setElementCopy(key, data);
     }
 
+    void
+    Dict::mergeAndReplace(const DictPtr& d)
+    {
+        if (d == nullptr)
+        {
+            return;
+        }
+
+        // merge and overwrite
+        for (const auto& [k, v] : getElements())
+        {
+            this->setElement(k, v);
+        }
+    }
+
+    void
+    Dict::mergeAndReplaceCopy(const DictPtr& d)
+    {
+        if (d == nullptr)
+        {
+            return;
+        }
+
+        // merge and overwrite
+        for (const auto& [k, v] : getElements())
+        {
+            this->setElementCopy(k, v);
+        }
+    }
+
     bool
     Dict::hasElement(const std::string& key) const
     {
@@ -231,8 +261,9 @@ namespace armarx::aron::data
             const auto& p = data->getPath();
             if (not p.hasDirectPrefix(this->getPath()))
             {
-                ARMARX_WARNING << "An element added to a dict does not have a correct path set. This "
-                                  "may cause errors. Please use setElemetCopy() instead.";
+                ARMARX_WARNING
+                    << "An element added to a dict does not have a correct path set. This "
+                       "may cause errors. Please use setElemetCopy() instead.";
             }
         }
 
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h
index f6c2d93955f53af91a04364ada5f3da724ae7033..a49add482dc4e7e6f1a1d5308d76e571785dbe73 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h
@@ -73,6 +73,9 @@ namespace armarx::aron::data
         VariantPtr getElement(const std::string&) const;
         std::map<std::string, VariantPtr> getElements() const;
 
+        void mergeAndReplace(const DictPtr& d);
+        void mergeAndReplaceCopy(const DictPtr& d);
+
         VariantPtr at(const std::string&) const;
         void removeElement(const std::string& key);
         void clear();
diff --git a/source/RobotAPI/libraries/robotapi/CMakeLists.txt b/source/RobotAPI/libraries/robotapi/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d62c2b5f8297012bfb4be7c6a90f74ac6d542c11
--- /dev/null
+++ b/source/RobotAPI/libraries/robotapi/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(core)
+add_subdirectory(client)
+add_subdirectory(server)
diff --git a/source/RobotAPI/libraries/skills/core/CMakeLists.txt b/source/RobotAPI/libraries/skills/core/CMakeLists.txt
index ae56efbde0909b63f5e75e9f33a49700ec163c20..66795b7ecdf0b0aa0897a07f5e47e5f5d489d4a1 100644
--- a/source/RobotAPI/libraries/skills/core/CMakeLists.txt
+++ b/source/RobotAPI/libraries/skills/core/CMakeLists.txt
@@ -15,31 +15,28 @@ armarx_add_library(
 
     SOURCES  
         error/Exception.cpp
+        SkillID.cpp
+        ProviderID.cpp
+        ProviderInfo.cpp
+        SkillExecutionRequest.cpp
+        SkillStatusUpdate.cpp
+        SkillExecutionID.cpp
+        SkillPreparationInput.cpp
+        SkillParameterization.cpp
         Skill.cpp
-        SkillProxy.cpp
-        PeriodicSkill.cpp
-        SpecializedSkill.cpp
-        PeriodicSpecializedSkill.cpp
         SkillDescription.cpp
-        SkillContext.cpp
     HEADERS
         error/Exception.h
+        SkillID.h
+        ProviderID.h
+        ProviderInfo.h
+        SkillExecutionRequest.h
+        SkillStatusUpdate.h
+        SkillExecutionID.h
+        SkillPreparationInput.h
+        SkillParameterization.h
         Skill.h
-        SkillProxy.h
-        PeriodicSkill.h
-        SpecializedSkill.h
-        PeriodicSpecializedSkill.h
         SkillDescription.h
-        SkillContext.h
-
-        mixins/All.h
-        mixins/ArvizSkillMixin.h
-        mixins/MNSSkillMixin.h
-        mixins/MemoryReadingSkillMixin.h
-        mixins/RobotReadingSkillMixin.h
-        mixins/ObjectReadingSkillMixin.h
-        mixins/ObjectWritingSkillMixin.h
-        mixins/GraspReadingSkillMixin.h
 )
 
 add_library(RobotAPI::skills::core ALIAS RobotAPISkillsCore)
diff --git a/source/RobotAPI/libraries/skills/core/ProviderID.cpp b/source/RobotAPI/libraries/skills/core/ProviderID.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c347dcf2fbf967f88fcd26eb8838193324f68c50
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/ProviderID.cpp
@@ -0,0 +1,69 @@
+#include "ProviderID.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        ProviderID::ProviderID(const std::string& pname) : providerName(pname)
+        {
+        }
+
+        ProviderID::ProviderID(const skills::SkillID& skillid) : providerName(skillid.providerName)
+        {
+        }
+
+        bool
+        ProviderID::operator==(const ProviderID& other) const
+        {
+            return providerName == other.providerName;
+        }
+
+        bool
+        ProviderID::operator!=(const ProviderID& other) const
+        {
+            return not(*this == other);
+        }
+
+        bool
+        ProviderID::operator<(const ProviderID& other) const
+        {
+            return toString() < other.toString();
+        }
+
+        ProviderID
+        ProviderID::FromIce(const manager::dto::ProviderID& s)
+        {
+            return ProviderID(s.providerName);
+        }
+
+        ProviderID
+        ProviderID::FromIce(const provider::dto::ProviderID& s)
+        {
+            return ProviderID(s.providerName);
+        }
+
+        manager::dto::ProviderID
+        ProviderID::toManagerIce() const
+        {
+            return {providerName};
+        }
+
+        provider::dto::ProviderID
+        ProviderID::toProviderIce() const
+        {
+            return {providerName};
+        }
+
+        std::string
+        ProviderID::toString(const std::string& prefix) const
+        {
+            return (prefix.empty() ? std::string("") : (prefix + PREFIX_SEPARATOR)) + providerName;
+        }
+    } // namespace skills
+
+    std::ostream&
+    skills::operator<<(std::ostream& os, const ProviderID& id)
+    {
+        return os << "'" << id.toString() << "'";
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/ProviderID.h b/source/RobotAPI/libraries/skills/core/ProviderID.h
new file mode 100644
index 0000000000000000000000000000000000000000..7aee01fd7a9a86fa1abf34f401fcbbbf3a7b6a7b
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/ProviderID.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <RobotAPI/interface/skills/SkillManagerInterface.h>
+#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
+
+#include "SkillID.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        class ProviderID
+        {
+        public:
+            static const constexpr char* PREFIX_SEPARATOR = "->";
+
+            std::string providerName;
+
+            ProviderID() = delete;
+            ProviderID(const skills::SkillID& skillid);
+            ProviderID(const std::string& pName);
+
+            bool operator==(const ProviderID& other) const;
+            bool operator!=(const ProviderID& other) const;
+            bool operator<(const ProviderID& other) const;
+
+            manager::dto::ProviderID toManagerIce() const;
+            provider::dto::ProviderID toProviderIce() const;
+
+            static ProviderID FromIce(const manager::dto::ProviderID&);
+            static ProviderID FromIce(const provider::dto::ProviderID&);
+
+            std::string toString(const std::string& prefix = "") const;
+        };
+
+        std::ostream& operator<<(std::ostream& os, const ProviderID& id);
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp b/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec12cb9ae684323f2142cf3d433c02a2c4af42f1
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/ProviderInfo.cpp
@@ -0,0 +1,26 @@
+#include "ProviderInfo.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        ProviderInfo::ProviderInfo(const ProviderID& pid,
+                                   const provider::dti::SkillProviderInterfacePrx& i,
+                                   const std::map<SkillID, SkillDescription>& skills) :
+            providerId(pid), provider(i), providedSkills(skills)
+        {
+        }
+
+        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)});
+            }
+            return ProviderInfo(skills::ProviderID::FromIce(i.providerId), i.provider, m);
+        }
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/ProviderInfo.h b/source/RobotAPI/libraries/skills/core/ProviderInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..2213d1615819256242c05d50207d4dae5001c8e7
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/ProviderInfo.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <SimoxUtility/algorithm/string.h>
+
+#include <RobotAPI/interface/skills/SkillManagerInterface.h>
+
+#include "ProviderID.h"
+#include "SkillDescription.h"
+#include "SkillID.h"
+#include "error/Exception.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        class ProviderInfo
+        {
+        public:
+            ProviderID providerId;
+            provider::dti::SkillProviderInterfacePrx provider;
+            std::map<SkillID, SkillDescription> providedSkills;
+
+            ProviderInfo() = delete;
+            ProviderInfo(const ProviderID& pid,
+                         const provider::dti::SkillProviderInterfacePrx& i,
+                         const std::map<SkillID, SkillDescription>& skills);
+
+            static ProviderInfo FromIce(const manager::dto::ProviderInfo&);
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/Skill.cpp b/source/RobotAPI/libraries/skills/core/Skill.cpp
index ba48923e7beab1876c6477d04845d05ce64883b9..e104ef656072cc0dd536a0ef3a8f924c2c0280ec 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.cpp
+++ b/source/RobotAPI/libraries/skills/core/Skill.cpp
@@ -4,110 +4,79 @@ namespace armarx
 {
     namespace skills
     {
-        Skill::Skill(const SkillDescription& desc):
-            description(desc)
+        Skill::Skill(const SkillDescription& desc) : description(desc)
         {
             // replace constructor if you want to have a specific logging tag
-            Logging::setTag("armarx::skills::" + description.skillName);
+            Logging::setTag("armarx::skills::" + description.skillId.toString());
         }
 
         // install a local condition via a lambda
-        void Skill::installConditionWithCallback(std::function<bool()>&& f, std::function<void()>&& cb)
+        void
+        Skill::installConditionWithCallback(std::function<bool()>&& f, std::function<void()>&& cb)
         {
-            std::lock_guard l(callbacksMutex);
-            callbacks.push_back({f, cb});
+            std::lock_guard l(conditionCallbacksMutex);
+            conditionCallbacks.push_back({f, cb});
         }
 
-        bool Skill::isSkillAvailable(const InitInput &in) const
-        {
-            return this->isAvailable(in);
-        }
-
-        bool Skill::isAvailable(const InitInput& in) const
-        {
-            (void) in;
-            return true;
-        }
-
-        void Skill::resetSkill()
-        {
-            //ARMARX_IMPORTANT << "Resetting skill '" << description.skillName << "'";
-
-            // resetting log times
-            started = armarx::core::time::DateTime::Invalid();
-            exited = armarx::core::time::DateTime::Invalid();
-
-            // resetting master running variable
-            running = false;
-
-            // resetting conditional variables
-            stopped = false;
-            timeoutReached = false;
-
-            this->reset();
-        }
-
-        void Skill::waitForDependenciesOfSkill()
-        {
-            //ARMARX_IMPORTANT << "Waiting for dependencies of skill '" << description.skillName << "'";
-            this->waitForDependencies();
-        }
-
-        void Skill::_init()
+        void
+        Skill::_init()
         {
             //ARMARX_IMPORTANT << "Initializing skill '" << description.skillName << "'";
-            callbacks.clear();
+            conditionCallbacks.clear();
             running = true;
             started = armarx::core::time::DateTime::Now();
 
             // install timeout condition
             installConditionWithCallback(
-                        [&](){ return (armarx::core::time::DateTime::Now() >= (started + description.timeout)); },
-                        [&](){ notifyTimeoutReached(); }
-            );
+                [&]() {
+                    return (armarx::core::time::DateTime::Now() >= (started + description.timeout));
+                },
+                [&]() { notifyTimeoutReached(); });
 
-            conditionCheckingThread = std::thread([&]()
-            {
-                armarx::core::time::Metronome metronome(conditionCheckingThreadFrequency);
-                while (running) // when the skill ends/aborts this variable will be set to false
+            conditionCheckingThread = std::thread(
+                [&]()
                 {
+                    armarx::core::time::Metronome metronome(conditionCheckingThreadFrequency);
+                    while (running) // when the skill ends/aborts this variable will be set to false
                     {
-                        std::scoped_lock l(callbacksMutex);
-                        for (auto& p : callbacks)
                         {
-                            auto& f = p.first;
-                            auto& cb = p.second;
-                            if (f())
+                            std::scoped_lock l(conditionCallbacksMutex);
+                            for (auto& p : conditionCallbacks)
                             {
-                                cb();
+                                auto& f = p.first;
+                                auto& cb = p.second;
+                                if (f())
+                                {
+                                    cb();
+                                }
                             }
                         }
+                        const auto sleepDuration = metronome.waitForNextTick();
+                        if (not sleepDuration.isPositive())
+                        {
+                            ARMARX_WARNING
+                                << deactivateSpam() << "PeriodicSkill: execution took too long ("
+                                << -sleepDuration << " vs "
+                                << conditionCheckingThreadFrequency.toCycleDuration() << ")";
+                        }
                     }
-                    const auto sleepDuration = metronome.waitForNextTick();
-                    if (not sleepDuration.isPositive())
-                    {
-                        ARMARX_WARNING << deactivateSpam() << "PeriodicSkill: execution took too long (" << -sleepDuration << " vs " << conditionCheckingThreadFrequency.toCycleDuration() << ")";
-                    }
-                }
-            });
-        }
-        Skill::InitResult Skill::initSkill(const InitInput& in)
-        {
-            this->_init();
-            return this->init(in);
+                });
         }
 
-        void Skill::_main()
+        void
+        Skill::_prepare()
         {
             // Nothing here yet...
         }
-        Skill::MainResult Skill::mainOfSkill(const MainInput& in)
+
+        void
+        Skill::_main()
         {
-            this->_main();
-            return this->main(in);
+            // Nothing here yet...
         }
 
-        void Skill::_exit()
+        void
+        Skill::_exit()
         {
             // ARMARX_IMPORTANT << "Exiting Skill '" << description.skillName << "'";
             running = false; // stop checking conditions
@@ -118,20 +87,51 @@ namespace armarx
             }
             exited = armarx::core::time::DateTime::Now();
         }
-        Skill::ExitResult Skill::exitSkill(const ExitInput& in)
+
+        Skill::InitResult
+        Skill::initSkill()
+        {
+            this->_init();
+            return this->init();
+        }
+
+        bool
+        Skill::skillPreparationFinished() const
+        {
+            return this->preparationFinished();
+        }
+
+        Skill::PrepareResult
+        Skill::prepareSkill()
         {
-            auto ret = this->exit(in);
+            this->_prepare();
+            return this->prepare();
+        }
+
+        Skill::MainResult
+        Skill::mainOfSkill()
+        {
+            this->_main();
+            return this->main();
+        }
+
+        Skill::ExitResult
+        Skill::exitSkill()
+        {
+            auto ret = this->exit();
             this->_exit();
             return ret;
         }
 
-        void Skill::notifyTimeoutReached()
+        void
+        Skill::notifyTimeoutReached()
         {
             timeoutReached = true;
             onTimeoutReached();
         }
 
-        Skill::MainResult Skill::MakeAbortedResult(aron::data::DictPtr data)
+        Skill::MainResult
+        Skill::MakeAbortedResult(aron::data::DictPtr data)
         {
             return MainResult{
                 .status = TerminatedSkillStatus::Aborted,
@@ -139,65 +139,81 @@ namespace armarx
             };
         }
 
-        void Skill::notifySkillToStopASAP()
+        void
+        Skill::notifySkillToStopASAP()
         {
             stopped = true;
             onStopRequested();
         }
 
-        bool Skill::checkWhetherSkillShouldStopASAP() const
+        bool
+        Skill::checkWhetherSkillShouldStopASAP() const
         {
             return stopped || timeoutReached;
         }
 
         // condition effects
-        void Skill::onTimeoutReached()
+        void
+        Skill::onTimeoutReached()
         {
         }
-        void Skill::onStopRequested()
+
+        void
+        Skill::onStopRequested()
         {
         }
 
-        // reset all local variables
-        void Skill::reset()
+        // always called before prepare (should not take longer than 100ms)
+        Skill::InitResult
+        Skill::init()
         {
-            // Default nothing to reset
+            // Default nothing to init
+            return {.status = TerminatedSkillStatus::Succeeded};
         }
 
-        // Wait if needed
-        void Skill::waitForDependencies()
+        bool
+        Skill::preparationFinished() const
         {
-            // Default wait for nothing
+            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 execute (should not take longer than 100ms)
-        Skill::InitResult Skill::init(const InitInput&)
+        // always called before main (should not take longer than 100ms)
+        Skill::PrepareResult
+        Skill::prepare()
         {
-            // Default nothing to init
-            return {.status = TerminatedSkillStatus::Succeeded};
+            // Default nothing to prepare
+            return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
         }
 
-        // always called after execute or if skill fails (should not take longer than 100ms)
-        Skill::ExitResult Skill::exit(const ExitInput&)
+        // always called after main or if skill fails (should not take longer than 100ms)
+        Skill::ExitResult
+        Skill::exit()
         {
             // Default nothing to exit
             return {.status = TerminatedSkillStatus::Succeeded};
         }
 
-        Skill::MainResult Skill::main(const MainInput& in)
+        Skill::MainResult
+        Skill::main()
         {
             // This is just a dummy implementation
-            ARMARX_IMPORTANT << "Dummy executing skill '" << description.skillName << "'. Please overwrite this method.";
+            ARMARX_IMPORTANT << "Dummy executing skill '" << description.skillId
+                             << "'. Please overwrite this method.";
             return {.status = TerminatedSkillStatus::Succeeded, .data = nullptr};
         }
-
-        Skill::MainResult Skill::executeFullSkill(const MainInput& in)
-        {
-            this->resetSkill();
-            this->initSkill(InitInput{.executorName = in.executorName, .params = in.params});
-            auto ret = this->mainOfSkill(in);
-            this->exitSkill(ExitInput{.executorName = in.executorName, .params = in.params});
-            return ret;
-        }
-    }
-}
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/Skill.h b/source/RobotAPI/libraries/skills/core/Skill.h
index bfba4d4cce7c37a880ea93b919373bdd3e126402..30f1f666e59a8f86421299aa30025b16fcbb7411 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.h
+++ b/source/RobotAPI/libraries/skills/core/Skill.h
@@ -1,10 +1,10 @@
 #pragma once
 
 // std/stl
+#include <functional>
 #include <mutex>
 #include <queue>
 #include <thread>
-#include <functional>
 
 // base class
 #include <ArmarXCore/core/logging/Logging.h>
@@ -16,11 +16,11 @@
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
 #include <RobotAPI/libraries/aron/core/data/variant/All.h>
 
-#include "../error/Exception.h"
-
+#include "SkillDescription.h"
 #include "SkillID.h"
+#include "SkillPreparationInput.h"
 #include "SkillStatusUpdate.h"
-#include "SkillDescription.h"
+#include "error/Exception.h"
 
 namespace armarx
 {
@@ -36,17 +36,9 @@ namespace armarx
                 TerminatedSkillStatus status;
             };
 
-            struct InitInput
-            {
-                std::string executorName;
-                aron::data::DictPtr params;
-            };
-
-            struct MainInput
+            struct PrepareResult
             {
-                std::string executorName;
-                aron::data::DictPtr params;
-                CallbackT callback;
+                ActiveOrTerminatedSkillStatus status;
             };
 
             struct MainResult
@@ -60,41 +52,26 @@ namespace armarx
                 TerminatedSkillStatus status;
             };
 
-            struct ExitInput
-            {
-                std::string executorName;
-                aron::data::DictPtr params;
-            };
-
             Skill() = delete;
             Skill(const SkillDescription&);
             virtual ~Skill() = default;
 
             /// The id of the skill (combination of provider and name must be unique).
-            SkillID getSkillId() const
+            SkillID
+            getSkillId() const
             {
-                return {providerName, description.skillName};
+                return {providerName, description.skillId.providerName};
             }
 
-            // Non virtual base methods. They internally call the virtual methods
-            // Lifecycle of a skill:
-            // 1. check if it is available
-            bool isSkillAvailable(const InitInput& in) const;
+            PrepareResult prepareSkill();
 
-            // 2. reset skill
-            void resetSkill();
+            bool skillPreparationFinished() const;
 
-            // 3. Set skill scheduled. Wait for dependencies
-            void waitForDependenciesOfSkill();
+            InitResult initSkill();
 
-            // 4. All dependencies resolved. Init skill
-            InitResult initSkill(const InitInput& in);
+            MainResult mainOfSkill();
 
-            // 5. Execute main function of skill
-            MainResult mainOfSkill(const MainInput& in);
-
-            // 6. Exit skill. This method is called in any case once the skill is scheduled.
-            ExitResult exitSkill(const ExitInput& in);
+            ExitResult exitSkill();
 
             // Condition listeners
             // used to notify the skill from extern to stop
@@ -103,8 +80,28 @@ namespace armarx
             // returns whether the skill should terminate as soon as possible
             bool checkWhetherSkillShouldStopASAP() const;
 
-            /// Do init, main, exit together
-            MainResult executeFullSkill(const MainInput& in);
+            // merge parameters to the local parameters of the skill
+            void
+            addParameters(const aron::data::DictPtr& d)
+            {
+                std::scoped_lock l(this->parametersMutex);
+                if (this->parameters == nullptr)
+                {
+                    this->parameters = d;
+                }
+                else
+                {
+                    this->parameters->mergeAndReplaceCopy(d);
+                }
+            }
+
+            // get the parameters
+            aron::data::DictPtr
+            getParameters() const
+            {
+                std::scoped_lock l(this->parametersMutex);
+                return this->parameters;
+            }
 
         protected:
             static MainResult MakeAbortedResult(aron::data::DictPtr data = nullptr);
@@ -114,27 +111,25 @@ namespace armarx
 
             // helper methods to do all the static initialization stuff
             void _init();
+            void _prepare();
             void _main();
             void _exit();
 
         private:
-            /// Override if your skill can be unavailable. It receives the same input as the init method
-            virtual bool isAvailable(const InitInput& in) const;
-
-            /// Override if you have special members that needs to be resetted. It is called before the skill ititializes
-            virtual void reset();
-
-            /// Override if you have special dependencies you have to wait for
-            virtual void waitForDependencies();
+            /// Override this method with the actual implementation.
+            virtual InitResult init();
 
             /// Override this method with the actual implementation.
-            virtual InitResult init(const InitInput& in);
+            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(const MainInput& in);
+            virtual MainResult main();
 
             /// Override this method with the actual implementation.
-            virtual ExitResult exit(const ExitInput& in);
+            virtual ExitResult exit();
 
             /// Override these methods if you want to do something special when notification comes
             virtual void onTimeoutReached();
@@ -142,35 +137,49 @@ namespace armarx
 
         protected:
             /// install a condition which is frequently checked from the conditionCheckingThread
-            void installConditionWithCallback(std::function<bool()>&& f, std::function<void()>&& cb);
+            void installConditionWithCallback(std::function<bool()>&& f,
+                                              std::function<void()>&& cb);
 
         public:
-            /// The descripion of the skill, which will be available via the provider/manager
+            // The descripion of the skill, which will be available via the provider/manager
             const SkillDescription description;
 
-            /// running params
+            // running params
             armarx::core::time::DateTime started = armarx::core::time::DateTime::Invalid();
             armarx::core::time::DateTime exited = armarx::core::time::DateTime::Invalid();
 
-            /// proxy that called the skills. Will be set from provider and is const afterwards
+            // parameterization.Will be set from implementation wrapper.
+            // const params after initialization
+            std::function<void(const SkillStatus s, const armarx::aron::data::DictPtr&)> callback;
             manager::dti::SkillManagerInterfacePrx manager = nullptr;
-
-            /// the provider that owns this skill. Will be set from provider and is const afterwards
             std::string providerName = "INVALID PROVIDER NAME";
+            std::string executorName = "INVALID EXECUTOR NAME";
+
+            // non-const params
+            mutable std::mutex parametersMutex;
+            armarx::aron::data::DictPtr parameters;
 
         protected:
-            /// active conditions. First is condition (bool return func)
-            std::vector<std::pair<std::function<bool()>, std::function<void()>>> callbacks;
-            mutable std::mutex callbacksMutex;
+            // active conditions. First is condition (bool return func)
+            mutable std::mutex conditionCallbacksMutex;
+            std::vector<std::pair<std::function<bool()>, std::function<void()>>> conditionCallbacks;
+
 
             /// Use conditions this way
+            std::atomic_bool initializing = false;
+            std::atomic_bool preparing = false;
             std::atomic_bool running = false;
             std::atomic_bool stopped = false;
             std::atomic_bool timeoutReached = false;
 
+
         private:
             std::thread conditionCheckingThread; // A therad that checks the conditions frequently
             armarx::Frequency conditionCheckingThreadFrequency = armarx::Frequency::Hertz(20);
         };
-    }
-}
+
+        template <class T>
+        concept isSkill = std::is_base_of<Skill, T>::value;
+
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillDescription.cpp b/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
index 3fec65dd9e1d1edf405202c3aaa0bc6df89392ad..fb5f6f0622b8aeec861087d8040b18a2c62b6b5c 100644
--- a/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillDescription.cpp
@@ -1,20 +1,34 @@
 #include "SkillDescription.h"
 
 #include <ArmarXCore/core/ice_conversions.h>
+#include <ArmarXCore/core/time/ice_conversions.h>
 
 namespace armarx
 {
     namespace skills
     {
 
-        provider::dto::SkillProfile
-        SkillProfile::toIce() const
+        //        provider::dto::SkillProfile
+        //        SkillProfile::toIce() const
+        //        {
+        //            provider::dto::SkillProfile ret;
+        //            ret.profileName = profileName;
+        //            ret.predecessorProfileName = predecessorProfileName;
+        //            ret.parameterization = parameterization->toAronDictDTO();
+        //            return ret;
+        //        }
+
+        SkillDescription::SkillDescription(const SkillID& id,
+                                           const std::string& desc,
+                                           const aron::data::DictPtr& data,
+                                           const armarx::core::time::Duration& timeout,
+                                           const aron::type::ObjectPtr& acceptedType) :
+            skillId(id),
+            description(desc),
+            rootProfileParameterization(data),
+            timeout(timeout),
+            acceptedType(acceptedType)
         {
-            provider::dto::SkillProfile ret;
-            ret.profileName = profileName;
-            ret.predecessorProfileName = predecessorProfileName;
-            ret.parameterization = parameterization->toAronDictDTO();
-            return ret;
         }
 
         provider::dto::SkillDescription
@@ -23,13 +37,24 @@ namespace armarx
             provider::dto::SkillDescription ret;
             ret.acceptedType = aron::type::Object::ToAronObjectDTO(acceptedType);
             ret.description = description;
-            ret.skillName = skillName;
-            for (const auto& [key, p] : profiles)
-            {
-                ret.profiles[key] = p.toIce();
-            }
-            ret.timeoutMs = timeout.toMilliSeconds();
+            ret.skillId = skillId.toProviderIce();
+            ret.rootProfileDefaults = rootProfileParameterization->toAronDictDTO();
+
+            armarx::core::time::toIce(ret.timeout, timeout);
             return ret;
         }
+
+        SkillDescription
+        SkillDescription::FromIce(const provider::dto::SkillDescription& i)
+        {
+            armarx::core::time::Duration _d;
+            armarx::core::time::fromIce(i.timeout, _d);
+            return SkillDescription(
+                SkillID::FromIce(i.skillId),
+                i.description,
+                armarx::aron::data::Dict::FromAronDictDTO(i.rootProfileDefaults),
+                _d,
+                armarx::aron::type::Object::FromAronObjectDTO(i.acceptedType));
+        }
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillDescription.h b/source/RobotAPI/libraries/skills/core/SkillDescription.h
index 42dbd46e8661fb1c1e23e223139835e2524b8fb0..e1e5b4fcf5f44280aef624c8a9d78521b9b87e6f 100644
--- a/source/RobotAPI/libraries/skills/core/SkillDescription.h
+++ b/source/RobotAPI/libraries/skills/core/SkillDescription.h
@@ -9,33 +9,44 @@
 #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
 #include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
 
+#include "SkillID.h"
+
 namespace armarx
 {
     namespace skills
     {
-        struct SkillProfile
-        {
-            static const constexpr char* ROOT_PROFILE_NAME = "root";
-            static const constexpr char* NO_PREDECESSOR = "";
+        //        struct SkillProfile
+        //        {
+        //            static const constexpr char* ROOT_PROFILE_NAME = "root";
+        //            static const constexpr char* NO_PREDECESSOR = "";
 
-            std::string profileName = ROOT_PROFILE_NAME;
-            std::string predecessorProfileName = "";
-            aron::data::DictPtr parameterization = nullptr;
+        //            std::string profileName = ROOT_PROFILE_NAME;
+        //            std::string predecessorProfileName = "";
+        //            aron::data::DictPtr parameterization = nullptr;
 
-            provider::dto::SkillProfile toIce() const;
-        };
+        //            provider::dto::SkillProfile toIce() const;
+        //        };
 
         struct SkillDescription
         {
-            static const constexpr char* SKILL_NOT_INITIALIZED = "NOT INITIALIZED YET";
+            SkillDescription() = delete;
+            SkillDescription(const SkillID& id,
+                             const std::string& desc,
+                             const aron::data::DictPtr& data = nullptr,
+                             const armarx::core::time::Duration& timeout =
+                                 armarx::core::time::Duration::MilliSeconds(-1),
+                             const aron::type::ObjectPtr& acceptedType = nullptr);
 
-            std::string skillName = SKILL_NOT_INITIALIZED;
-            std::string description = SKILL_NOT_INITIALIZED;
-            std::map<std::string, SkillProfile> profiles = {};
-            armarx::core::time::Duration timeout = armarx::core::time::Duration::MilliSeconds(-1);
-            aron::type::ObjectPtr acceptedType = nullptr;
+
+            SkillID skillId;
+            std::string description;
+            aron::data::DictPtr rootProfileParameterization;
+            armarx::core::time::Duration timeout;
+            aron::type::ObjectPtr acceptedType;
 
             provider::dto::SkillDescription toIce() const;
+
+            static SkillDescription FromIce(const provider::dto::SkillDescription& i);
         };
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp b/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3efb06d9e50e1d55bccf238e282d20366c4f7298
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionID.cpp
@@ -0,0 +1,52 @@
+#include "SkillExecutionID.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        SkillExecutionId::SkillExecutionId(const SkillID& id,
+                                           const std::string& executorName,
+                                           const armarx::core::time::DateTime& time) :
+            skillId(id), executorName(executorName), executionStartedTime(time)
+        {
+        }
+
+        skills::manager::dto::SkillExecutionID
+        SkillExecutionId::toManagerIce() const
+        {
+            skills::manager::dto::SkillExecutionID ret;
+            ret.skillId.skillName = skillId.skillName;
+            ret.skillId.providerName = skillId.providerName;
+            ret.executorName = executorName;
+            armarx::core::time::toIce(ret.executionStartedTime, executionStartedTime);
+            return ret;
+        }
+
+        skills::provider::dto::SkillExecutionID
+        SkillExecutionId::toProviderIce() const
+        {
+            skills::provider::dto::SkillExecutionID ret;
+            ret.skillId = skillId.toProviderIce();
+            ret.executorName = executorName;
+            armarx::core::time::toIce(ret.executionStartedTime, executionStartedTime);
+            return ret;
+        }
+
+        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)
+        {
+            armarx::core::time::DateTime t;
+            armarx::core::time::fromIce(i.executionStartedTime, t);
+            return {skills::SkillID::FromIce(i.skillId, providerName), i.executorName, t};
+        }
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionID.h b/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
new file mode 100644
index 0000000000000000000000000000000000000000..356aec6116b10e9b5ce9c686d01201364a9619b5
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionID.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <ArmarXCore/core/time/DateTime.h>
+#include <ArmarXCore/core/time/ice_conversions.h>
+
+#include <RobotAPI/interface/skills/SkillProviderInterface.h>
+#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
+
+#include "SkillID.h"
+#include "SkillParameterization.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        struct SkillExecutionId
+        {
+            SkillID skillId;
+            std::string executorName;
+            armarx::core::time::DateTime executionStartedTime;
+
+            SkillExecutionId() = delete;
+            SkillExecutionId(const SkillID&,
+                             const std::string& executorName,
+                             const armarx::core::time::DateTime&);
+
+            bool
+            operator==(const SkillExecutionId& other) const
+            {
+                if (skillId != other.skillId)
+                {
+                    return false;
+                }
+                if (executionStartedTime != other.executionStartedTime)
+                {
+                    return false;
+                }
+                if (executorName != other.executorName)
+                {
+                    return false;
+                }
+                return true;
+            }
+
+            bool
+            operator<(const SkillExecutionId& other) const
+            {
+                // We explicitly do not compare skillIds as we ONLY want to bring the executionids in some (temporal) order
+                return executionStartedTime < other.executionStartedTime;
+            }
+
+            skills::manager::dto::SkillExecutionID toManagerIce() const;
+
+            skills::provider::dto::SkillExecutionID toProviderIce() const;
+
+            static SkillExecutionId FromIce(const skills::manager::dto::SkillExecutionID&);
+
+            static SkillExecutionId FromIce(const skills::provider::dto::SkillExecutionID&,
+                                            const std::string& providerName);
+        };
+
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d045cc2395b8863de8a3352b25969dff78ed191f
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.cpp
@@ -0,0 +1,56 @@
+#include "SkillExecutionRequest.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        SkillExecutionRequest::SkillExecutionRequest(
+            const skills::SkillID& skill,
+            const std::string executorName,
+            const armarx::aron::data::DictPtr& params,
+            const callback::dti::SkillProviderCallbackInterfacePrx& callback) :
+            skillId(skill), executorName(executorName), params(params), callbackInterface(callback)
+        {
+        }
+
+        manager::dto::SkillExecutionRequest
+        SkillExecutionRequest::toManagerIce() const
+        {
+            manager::dto::SkillExecutionRequest ret;
+            ret.skillId = skillId.toManagerIce();
+            ret.executorName = executorName;
+            ret.params = params->toAronDictDTO();
+            return ret;
+        }
+
+        provider::dto::SkillExecutionRequest
+        SkillExecutionRequest::toProviderIce() const
+        {
+            provider::dto::SkillExecutionRequest ret;
+            ret.skillId = skillId.toProviderIce();
+            ret.executorName = executorName;
+            ret.params = params->toAronDictDTO();
+            ret.callbackInterface = callbackInterface;
+            return ret;
+        }
+
+        SkillExecutionRequest
+        SkillExecutionRequest::FromIce(const manager::dto::SkillExecutionRequest& req)
+        {
+            return {skills::SkillID::FromIce(req.skillId),
+                    req.executorName,
+                    armarx::aron::data::Dict::FromAronDictDTO(req.params),
+                    nullptr};
+        }
+
+        SkillExecutionRequest
+        SkillExecutionRequest::FromIce(const provider::dto::SkillExecutionRequest& req)
+        {
+            return {skills::SkillID::FromIce(req.skillId),
+                    req.executorName,
+                    armarx::aron::data::Dict::FromAronDictDTO(req.params),
+                    req.callbackInterface};
+        }
+
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec39e2f44d2faab47932abd89e878ff9996dafc0
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillExecutionRequest.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <SimoxUtility/algorithm/string.h>
+
+#include <ArmarXCore/core/time/DateTime.h>
+#include <ArmarXCore/core/time/ice_conversions.h>
+
+#include <RobotAPI/interface/skills/SkillManagerInterface.h>
+#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
+
+#include "SkillID.h"
+#include "error/Exception.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+        class SkillExecutionRequest
+        {
+        public:
+            skills::SkillID skillId;
+            std::string executorName;
+            armarx::aron::data::DictPtr params;
+            callback::dti::SkillProviderCallbackInterfacePrx callbackInterface;
+
+            SkillExecutionRequest() = delete;
+            SkillExecutionRequest(const skills::SkillID& skill,
+                                  const std::string executorName,
+                                  const armarx::aron::data::DictPtr& params,
+                                  const callback::dti::SkillProviderCallbackInterfacePrx& callback);
+
+            manager::dto::SkillExecutionRequest toManagerIce() const;
+            provider::dto::SkillExecutionRequest toProviderIce() const;
+
+            static SkillExecutionRequest FromIce(const manager::dto::SkillExecutionRequest&);
+            static SkillExecutionRequest
+            FromIce(const provider::dto::SkillExecutionRequest&);
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillID.cpp b/source/RobotAPI/libraries/skills/core/SkillID.cpp
similarity index 76%
rename from source/RobotAPI/libraries/skills/provider/SkillID.cpp
rename to source/RobotAPI/libraries/skills/core/SkillID.cpp
index a384261f876673b680d8bd102a1439ef05744fcb..80373376a4438af2143b4c0ecc395a3ca67f5da9 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillID.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillID.cpp
@@ -4,6 +4,10 @@ namespace armarx
 {
     namespace skills
     {
+        SkillID::SkillID(const std::string& skillName) : SkillID(NOT_YET_KNOWN, skillName)
+        {
+        }
+
         SkillID::SkillID(const std::string& providerName, const std::string& skillName) :
             providerName(providerName), skillName(skillName)
         {
@@ -44,12 +48,30 @@ namespace armarx
             return toString() < other.toString();
         }
 
+        SkillID
+        SkillID::FromIce(const manager::dto::SkillID& s)
+        {
+            return SkillID(s.providerName, s.skillName);
+        }
+
+        SkillID
+        SkillID::FromIce(const provider::dto::SkillID& s, const std::string& providerName)
+        {
+            return SkillID(providerName, s.skillName);
+        }
+
         manager::dto::SkillID
-        SkillID::toIce() const
+        SkillID::toManagerIce() const
         {
             return {providerName, skillName};
         }
 
+        provider::dto::SkillID
+        SkillID::toProviderIce() const
+        {
+            return {skillName};
+        }
+
         std::string
         SkillID::toString(const std::string& prefix) const
         {
diff --git a/source/RobotAPI/libraries/skills/provider/SkillID.h b/source/RobotAPI/libraries/skills/core/SkillID.h
similarity index 65%
rename from source/RobotAPI/libraries/skills/provider/SkillID.h
rename to source/RobotAPI/libraries/skills/core/SkillID.h
index 3eb1fd6f4dac0d7fdb9e2d7b258a968f548e8a14..a65765f0cb6336c732b22f3c2b323fce6d32cbe3 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillID.h
+++ b/source/RobotAPI/libraries/skills/core/SkillID.h
@@ -6,9 +6,8 @@
 #include <SimoxUtility/algorithm/string.h>
 
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
-#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
 
-#include "../error/Exception.h"
+#include "error/Exception.h"
 
 namespace armarx
 {
@@ -19,18 +18,26 @@ 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";
 
             std::string providerName;
             std::string skillName;
 
             SkillID() = delete;
+            SkillID(const std::string& skillName);
             SkillID(const std::string& providerName, const std::string& skillName);
 
             bool operator==(const SkillID& other) const;
             bool operator!=(const SkillID& other) const;
             bool operator<(const SkillID& other) const;
 
-            manager::dto::SkillID toIce() const;
+            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);
+
             std::string toString(const std::string& prefix = "") const;
         };
 
diff --git a/source/RobotAPI/libraries/skills/provider/SkillParameterization.cpp b/source/RobotAPI/libraries/skills/core/SkillParameterization.cpp
similarity index 100%
rename from source/RobotAPI/libraries/skills/provider/SkillParameterization.cpp
rename to source/RobotAPI/libraries/skills/core/SkillParameterization.cpp
diff --git a/source/RobotAPI/libraries/skills/core/SkillParameterization.h b/source/RobotAPI/libraries/skills/core/SkillParameterization.h
new file mode 100644
index 0000000000000000000000000000000000000000..5358eafa7591ad2ea7331b65427f0be062d1d194
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillParameterization.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <RobotAPI/interface/skills/SkillProviderInterface.h>
+#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
+
+namespace armarx
+{
+    namespace skills
+    {
+        struct SkillParameterization
+        {
+            SkillParameterization() = delete;
+
+            SkillParameterization(const aron::data::DictPtr& params,
+                                  const callback::dti::SkillProviderCallbackInterfacePrx& i) :
+                parameterization(params), callbackInterface(i)
+            {
+            }
+
+            static SkillParameterization
+            FromIce(const armarx::aron::data::dto::DictPtr& params,
+                    const callback::dti::SkillProviderCallbackInterfacePrx& i)
+            {
+                return SkillParameterization(armarx::aron::data::Dict::FromAronDictDTO(params), i);
+            }
+
+            aron::data::DictPtr parameterization;
+            callback::dti::SkillProviderCallbackInterfacePrx callbackInterface;
+        };
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/SkillPreparationInput.cpp b/source/RobotAPI/libraries/skills/core/SkillPreparationInput.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0ec681e2b772aa773a6cc890198e24c28714207
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/core/SkillPreparationInput.cpp
@@ -0,0 +1,8 @@
+#include "SkillParameterization.h"
+
+namespace armarx
+{
+    namespace skills
+    {
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillParameterization.h b/source/RobotAPI/libraries/skills/core/SkillPreparationInput.h
similarity index 56%
rename from source/RobotAPI/libraries/skills/provider/SkillParameterization.h
rename to source/RobotAPI/libraries/skills/core/SkillPreparationInput.h
index 65261a5cb939f72b69ea46c1807e52640752c9cb..b5cc2bb20c392864ccb31607e1ef02e9174fb211 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillParameterization.h
+++ b/source/RobotAPI/libraries/skills/core/SkillPreparationInput.h
@@ -10,10 +10,6 @@ namespace armarx
 {
     namespace skills
     {
-        struct SkillParameterization
-        {
-            aron::data::DictPtr usedInputParams = nullptr;
-            callback::dti::SkillProviderCallbackInterfacePrx usedCallbackInterface = nullptr;
-        };
+
     } // namespace skills
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.cpp b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
similarity index 58%
rename from source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.cpp
rename to source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
index 8a7ac2ab532bb0d0817e1894ae2565014f1940fa..df5950ac34a0a724d7464801aaef5f37d3743134 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.cpp
@@ -41,11 +41,14 @@ namespace armarx
         {
             switch (status)
             {
-                case SkillStatus::Idle:
-                    ret = provider::dto::Execution::Status::Idle;
+                case SkillStatus::Constructing:
+                    ret = provider::dto::Execution::Status::Constructing;
                     return;
-                case SkillStatus::Scheduled:
-                    ret = provider::dto::Execution::Status::Scheduled;
+                case SkillStatus::Initializing:
+                    ret = provider::dto::Execution::Status::Initializing;
+                    return;
+                case SkillStatus::Preparing:
+                    ret = provider::dto::Execution::Status::Preparing;
                     return;
                 case SkillStatus::Running:
                     ret = provider::dto::Execution::Status::Running;
@@ -107,9 +110,11 @@ namespace armarx
         {
             switch (status)
             {
-                case provider::dto::Execution::Status::Idle:
+                case provider::dto::Execution::Status::Constructing:
+                    [[fallthrough]];
+                case provider::dto::Execution::Status::Initializing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Scheduled:
+                case provider::dto::Execution::Status::Preparing:
                     [[fallthrough]];
                 case provider::dto::Execution::Status::Running:
                     break;
@@ -133,9 +138,11 @@ namespace armarx
         {
             switch (status)
             {
-                case provider::dto::Execution::Status::Idle:
+                case provider::dto::Execution::Status::Constructing:
                     [[fallthrough]];
-                case provider::dto::Execution::Status::Scheduled:
+                case provider::dto::Execution::Status::Initializing:
+                    [[fallthrough]];
+                case provider::dto::Execution::Status::Preparing:
                     break;
                 case provider::dto::Execution::Status::Running:
                     ret = ActiveOrTerminatedSkillStatus::Running;
@@ -160,11 +167,14 @@ namespace armarx
         {
             switch (status)
             {
-                case provider::dto::Execution::Status::Idle:
-                    ret = SkillStatus::Idle;
+                case provider::dto::Execution::Status::Constructing:
+                    ret = SkillStatus::Constructing;
+                    return;
+                case provider::dto::Execution::Status::Initializing:
+                    ret = SkillStatus::Initializing;
                     return;
-                case provider::dto::Execution::Status::Scheduled:
-                    ret = SkillStatus::Scheduled;
+                case provider::dto::Execution::Status::Preparing:
+                    ret = SkillStatus::Preparing;
                     return;
                 case provider::dto::Execution::Status::Running:
                     ret = SkillStatus::Running;
@@ -182,189 +192,98 @@ namespace armarx
             throw error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
         }
 
-        skills::manager::dto::SkillExecutionID
-        SkillExecutionId::toIce() const
-        {
-            skills::manager::dto::SkillExecutionID ret;
-            ret.skillId.skillName = skillId.skillName;
-            ret.skillId.providerName = skillId.providerName;
-            ret.executorName = executorName;
-            armarx::core::time::toIce(ret.executionStartedTime, executionStartedTime);
-            return ret;
-        }
-
-        skills::provider::dto::SkillExecutionID
-        SkillExecutionId::toIceProviderView() const
-        {
-            skills::provider::dto::SkillExecutionID ret;
-            ret.skillName = skillId.skillName;
-            ret.executorName = executorName;
-            armarx::core::time::toIce(ret.executionStartedTime, executionStartedTime);
-            return ret;
-        }
-
-        void
-        SkillExecutionId::fromIce(const skills::manager::dto::SkillExecutionID& i)
-        {
-            skillId.skillName = i.skillId.skillName;
-            skillId.providerName = i.skillId.providerName;
-            executorName = i.executorName;
-            armarx::core::time::fromIce(i.executionStartedTime, executionStartedTime);
-        }
-
-        void
-        SkillExecutionId::fromIce(const skills::provider::dto::SkillExecutionID& i,
-                                  const std::string& providerName)
-        {
-            skillId.skillName = i.skillName;
-            skillId.providerName = providerName;
-            executorName = i.executorName;
-            armarx::core::time::fromIce(i.executionStartedTime, executionStartedTime);
-        }
-
-        SkillExecutionId
-        SkillExecutionId::FromIce(const skills::manager::dto::SkillExecutionID& i)
+        SkillStatusUpdateBase::SkillStatusUpdateBase(const SkillExecutionId& exec,
+                                                     const SkillParameterization& param) :
+            executionId(exec), usedParameterization(param)
         {
-            SkillExecutionId ret;
-            ret.fromIce(i);
-            return ret;
-        }
-
-        SkillExecutionId
-        SkillExecutionId::FromIce(const skills::provider::dto::SkillExecutionID& i,
-                                  const std::string& providerName)
-        {
-            SkillExecutionId ret;
-            ret.fromIce(i, providerName);
-            return ret;
         }
 
         manager::dto::SkillStatusUpdate
-        SkillStatusUpdateBase::toIce() const
+        SkillStatusUpdateBase::toManagerIce() const
         {
             manager::dto::SkillStatusUpdate ret;
-            ret.header.executionId.skillId = executionId.skillId.toIce();
+            ret.header.executionId.skillId = executionId.skillId.toManagerIce();
             ret.header.executionId.executorName = executionId.executorName;
             armarx::core::time::toIce(ret.header.executionId.executionStartedTime,
                                       executionId.executionStartedTime);
             ret.header.usedParams =
-                aron::data::Dict::ToAronDictDTO(usedParameterization.usedInputParams);
-            ret.header.usedCallbackInterface = usedParameterization.usedCallbackInterface;
+                aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
+            ret.header.usedCallbackInterface = usedParameterization.callbackInterface;
             ret.data = aron::data::Dict::ToAronDictDTO(data);
             return ret;
         }
 
         provider::dto::SkillStatusUpdate
-        SkillStatusUpdateBase::toIceProviderView() const
+        SkillStatusUpdateBase::toProviderIce() const
         {
             provider::dto::SkillStatusUpdate ret;
-            ret.header.executionId.skillName = executionId.skillId.skillName;
+            ret.header.executionId.skillId = executionId.skillId.toProviderIce();
             ret.header.executionId.executorName = executionId.executorName;
             armarx::core::time::toIce(ret.header.executionId.executionStartedTime,
                                       executionId.executionStartedTime);
             ret.header.usedParams =
-                aron::data::Dict::ToAronDictDTO(usedParameterization.usedInputParams);
-            ret.header.usedCallbackInterface = usedParameterization.usedCallbackInterface;
+                aron::data::Dict::ToAronDictDTO(usedParameterization.parameterization);
+            ret.header.usedCallbackInterface = usedParameterization.callbackInterface;
             ret.data = aron::data::Dict::ToAronDictDTO(data);
             return ret;
         }
 
-        void
-        SkillStatusUpdateBase::fromIce(const manager::dto::SkillStatusUpdate& update)
-        {
-            executionId.skillId = {update.header.executionId.skillId.providerName,
-                                   update.header.executionId.skillId.skillName};
-            executionId.executorName = update.header.executionId.executorName;
-            armarx::core::time::fromIce(update.header.executionId.executionStartedTime,
-                                        executionId.executionStartedTime);
-            usedParameterization.usedInputParams =
-                armarx::aron::data::Dict::FromAronDictDTO(update.header.usedParams);
-            usedParameterization.usedCallbackInterface = update.header.usedCallbackInterface;
-            data = armarx::aron::data::Dict::FromAronDictDTO(update.data);
-        }
-
-        void
-        SkillStatusUpdateBase::fromIce(const provider::dto::SkillStatusUpdate& update,
-                                       const std::string& providerName)
-        {
-            executionId.skillId = {providerName, update.header.executionId.skillName};
-            executionId.executorName = update.header.executionId.executorName;
-            armarx::core::time::fromIce(update.header.executionId.executionStartedTime,
-                                        executionId.executionStartedTime);
-            usedParameterization.usedInputParams =
-                armarx::aron::data::Dict::FromAronDictDTO(update.header.usedParams);
-            usedParameterization.usedCallbackInterface = update.header.usedCallbackInterface;
-            data = armarx::aron::data::Dict::FromAronDictDTO(update.data);
-        }
-
         manager::dto::SkillStatusUpdate
-        TerminatedSkillStatusUpdate::toIce() const
+        TerminatedSkillStatusUpdate::toManagerIce() const
         {
-            manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toIce();
+            manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toManagerIce();
             skills::toIce(ret.header.status, status);
             return ret;
         }
 
         provider::dto::SkillStatusUpdate
-        TerminatedSkillStatusUpdate::toIceProviderView() const
+        TerminatedSkillStatusUpdate::toProviderIce() const
         {
-            provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toIceProviderView();
+            provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toProviderIce();
             skills::toIce(ret.header.status, status);
             return ret;
         }
 
         manager::dto::SkillStatusUpdate
-        SkillStatusUpdate::toIce() const
+        SkillStatusUpdate::toManagerIce() const
         {
-            manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toIce();
+            manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toManagerIce();
             skills::toIce(ret.header.status, status);
             return ret;
         }
 
         provider::dto::SkillStatusUpdate
-        SkillStatusUpdate::toIceProviderView() const
+        SkillStatusUpdate::toProviderIce() const
         {
-            provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toIceProviderView();
+            provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toProviderIce();
             skills::toIce(ret.header.status, status);
             return ret;
         }
 
         manager::dto::SkillStatusUpdate
-        ActiveOrTerminatedSkillStatusUpdate::toIce() const
+        ActiveOrTerminatedSkillStatusUpdate::toManagerIce() const
         {
-            manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toIce();
+            manager::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toManagerIce();
             skills::toIce(ret.header.status, status);
             return ret;
         }
 
         provider::dto::SkillStatusUpdate
-        ActiveOrTerminatedSkillStatusUpdate::toIceProviderView() const
+        ActiveOrTerminatedSkillStatusUpdate::toProviderIce() const
         {
-            provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toIceProviderView();
+            provider::dto::SkillStatusUpdate ret = SkillStatusUpdateBase::toProviderIce();
             skills::toIce(ret.header.status, status);
             return ret;
         }
 
-        void
-        TerminatedSkillStatusUpdate::fromIce(const manager::dto::SkillStatusUpdate& update)
-        {
-            SkillStatusUpdateBase::fromIce(update);
-            skills::fromIce(update.header.status, status);
-        }
-
-        void
-        TerminatedSkillStatusUpdate::fromIce(const provider::dto::SkillStatusUpdate& update,
-                                             const std::string& providerName)
-        {
-            SkillStatusUpdateBase::fromIce(update, providerName);
-            skills::fromIce(update.header.status, status);
-        }
-
         TerminatedSkillStatusUpdate
         TerminatedSkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            TerminatedSkillStatusUpdate ret;
-            ret.fromIce(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);
             return ret;
         }
 
@@ -372,31 +291,22 @@ namespace armarx
         TerminatedSkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
                                              const std::string& providerName)
         {
-            TerminatedSkillStatusUpdate ret;
-            ret.fromIce(update, providerName);
+            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);
             return ret;
         }
 
-        void
-        SkillStatusUpdate::fromIce(const manager::dto::SkillStatusUpdate& update)
-        {
-            SkillStatusUpdateBase::fromIce(update);
-            skills::fromIce(update.header.status, status);
-        }
-
-        void
-        SkillStatusUpdate::fromIce(const provider::dto::SkillStatusUpdate& update,
-                                   const std::string& providerName)
-        {
-            SkillStatusUpdateBase::fromIce(update, providerName);
-            skills::fromIce(update.header.status, status);
-        }
-
         SkillStatusUpdate
         SkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            SkillStatusUpdate ret;
-            ret.fromIce(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);
             return ret;
         }
 
@@ -404,31 +314,22 @@ namespace armarx
         SkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
                                    const std::string& providerName)
         {
-            SkillStatusUpdate ret;
-            ret.fromIce(update, providerName);
+            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);
             return ret;
         }
 
-        void
-        ActiveOrTerminatedSkillStatusUpdate::fromIce(const manager::dto::SkillStatusUpdate& update)
-        {
-            SkillStatusUpdateBase::fromIce(update);
-            skills::fromIce(update.header.status, status);
-        }
-
-        void
-        ActiveOrTerminatedSkillStatusUpdate::fromIce(const provider::dto::SkillStatusUpdate& update,
-                                                     const std::string& providerName)
-        {
-            SkillStatusUpdateBase::fromIce(update, providerName);
-            skills::fromIce(update.header.status, status);
-        }
-
         ActiveOrTerminatedSkillStatusUpdate
         ActiveOrTerminatedSkillStatusUpdate::FromIce(const manager::dto::SkillStatusUpdate& update)
         {
-            ActiveOrTerminatedSkillStatusUpdate ret;
-            ret.fromIce(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);
             return ret;
         }
 
@@ -436,8 +337,11 @@ namespace armarx
         ActiveOrTerminatedSkillStatusUpdate::FromIce(const provider::dto::SkillStatusUpdate& update,
                                                      const std::string& providerName)
         {
-            ActiveOrTerminatedSkillStatusUpdate ret;
-            ret.fromIce(update, providerName);
+            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);
             return ret;
         }
     } // namespace skills
diff --git a/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.h b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
similarity index 54%
rename from source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.h
rename to source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
index 7c83877df3ef4c046df3e4991ec9b61da1805cab..536a169f620062f461aa0e11577de4cd6106ac84 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.h
+++ b/source/RobotAPI/libraries/skills/core/SkillStatusUpdate.h
@@ -9,6 +9,7 @@
 #include <RobotAPI/interface/skills/SkillProviderInterface.h>
 #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
 
+#include "SkillExecutionID.h"
 #include "SkillID.h"
 #include "SkillParameterization.h"
 
@@ -18,12 +19,13 @@ namespace armarx
     {
         enum class SkillStatus
         {
-            Idle = 0,
-            Scheduled = 1,
-            Running = 2,
-            Failed = 4,
-            Succeeded = 8,
-            Aborted = 16
+            Constructing = 0,
+            Initializing = 1,
+            Preparing = 2,
+            Running = 4,
+            Failed = 8,
+            Succeeded = 16,
+            Aborted = 32
         };
 
         enum class ActiveOrTerminatedSkillStatus
@@ -54,71 +56,21 @@ namespace armarx
                      ActiveOrTerminatedSkillStatus& ret);
         void fromIce(const provider::dto::Execution::Status& status, SkillStatus& ret);
 
-        struct SkillExecutionId
-        {
-            static const constexpr char* NOT_INITIALIZED = "NOT INITIALIZED YET";
-            SkillID skillId = {NOT_INITIALIZED, NOT_INITIALIZED};
-            std::string executorName = "";
-            armarx::core::time::DateTime executionStartedTime =
-                armarx::core::time::DateTime::Invalid();
-
-            bool
-            operator==(const SkillExecutionId& other) const
-            {
-                if (skillId != other.skillId)
-                {
-                    return false;
-                }
-                if (executionStartedTime != other.executionStartedTime)
-                {
-                    return false;
-                }
-                if (executorName != other.executorName)
-                {
-                    return false;
-                }
-                return true;
-            }
-
-            bool
-            operator<(const SkillExecutionId& other) const
-            {
-                // We explicitly do not compare skillIds as we ONLY want to bring the executionids in some (temporal) order
-                return executionStartedTime < other.executionStartedTime;
-            }
-
-            skills::manager::dto::SkillExecutionID toIce() const;
-
-            skills::provider::dto::SkillExecutionID toIceProviderView() const;
-
-            void fromIce(const skills::manager::dto::SkillExecutionID&);
-
-            void fromIce(const skills::provider::dto::SkillExecutionID&,
-                         const std::string& providerName);
-
-            static SkillExecutionId FromIce(const skills::manager::dto::SkillExecutionID&);
-
-            static SkillExecutionId FromIce(const skills::provider::dto::SkillExecutionID&,
-                                            const std::string& providerName);
-        };
-
         struct SkillStatusUpdateBase
         {
             // header
             SkillExecutionId executionId;
             SkillParameterization usedParameterization;
 
+            SkillStatusUpdateBase() = delete;
+            SkillStatusUpdateBase(const SkillExecutionId& exec, const SkillParameterization& param);
+
             // data
             aron::data::DictPtr data = nullptr;
 
-            manager::dto::SkillStatusUpdate toIce() const;
-
-            provider::dto::SkillStatusUpdate toIceProviderView() const;
+            manager::dto::SkillStatusUpdate toManagerIce() const;
 
-            void fromIce(const provider::dto::SkillStatusUpdate& update,
-                         const std::string& providerName);
-
-            void fromIce(const manager::dto::SkillStatusUpdate& update);
+            provider::dto::SkillStatusUpdate toProviderIce() const;
         };
 
         // Will be returned after the execution of a skill
@@ -126,20 +78,17 @@ namespace armarx
         {
             TerminatedSkillStatus status = TerminatedSkillStatus::Failed;
 
+            using SkillStatusUpdateBase::SkillStatusUpdateBase;
+
             bool
             hasBeenTerminated() const
             {
                 return true;
             }
 
-            manager::dto::SkillStatusUpdate toIce() const;
-
-            provider::dto::SkillStatusUpdate toIceProviderView() const;
+            manager::dto::SkillStatusUpdate toManagerIce() const;
 
-            void fromIce(const provider::dto::SkillStatusUpdate& update,
-                         const std::string& providerName);
-
-            void fromIce(const manager::dto::SkillStatusUpdate& update);
+            provider::dto::SkillStatusUpdate toProviderIce() const;
 
             static TerminatedSkillStatusUpdate
             FromIce(const provider::dto::SkillStatusUpdate& update,
@@ -154,6 +103,8 @@ namespace armarx
         {
             ActiveOrTerminatedSkillStatus status = ActiveOrTerminatedSkillStatus::Failed;
 
+            using SkillStatusUpdateBase::SkillStatusUpdateBase;
+
             bool
             hasBeenTerminated() const
             {
@@ -162,14 +113,9 @@ namespace armarx
                        status == ActiveOrTerminatedSkillStatus::Aborted;
             }
 
-            manager::dto::SkillStatusUpdate toIce() const;
-
-            provider::dto::SkillStatusUpdate toIceProviderView() const;
+            manager::dto::SkillStatusUpdate toManagerIce() const;
 
-            void fromIce(const provider::dto::SkillStatusUpdate& update,
-                         const std::string& providerName);
-
-            void fromIce(const manager::dto::SkillStatusUpdate& update);
+            provider::dto::SkillStatusUpdate toProviderIce() const;
 
             static ActiveOrTerminatedSkillStatusUpdate
             FromIce(const provider::dto::SkillStatusUpdate& update,
@@ -182,18 +128,32 @@ namespace armarx
         // Will be used as status updates from skills to the callback interface
         struct SkillStatusUpdate : public SkillStatusUpdateBase
         {
-            SkillStatus status = SkillStatus::Idle;
+            SkillStatus status = SkillStatus::Constructing;
+
+            using SkillStatusUpdateBase::SkillStatusUpdateBase;
 
             bool
-            hasBeenScheduled() const
+            hasBeenConstructed() const
             {
-                return status == SkillStatus::Scheduled || hasBeenRunning();
+                return status != SkillStatus::Constructing;
+            }
+
+            bool
+            hasBeenInitialized() const
+            {
+                return status != SkillStatus::Initializing && hasBeenConstructed();
+            }
+
+            bool
+            hasBeenPrepared() const
+            {
+                return status != SkillStatus::Preparing && hasBeenInitialized();
             }
 
             bool
             hasBeenRunning() const
             {
-                return status == SkillStatus::Running || hasBeenTerminated();
+                return status != SkillStatus::Running || hasBeenPrepared();
             }
 
             bool
@@ -203,14 +163,9 @@ namespace armarx
                        status == SkillStatus::Aborted;
             }
 
-            manager::dto::SkillStatusUpdate toIce() const;
-
-            provider::dto::SkillStatusUpdate toIceProviderView() const;
-
-            void fromIce(const provider::dto::SkillStatusUpdate& update,
-                         const std::string& providerName);
+            manager::dto::SkillStatusUpdate toManagerIce() const;
 
-            void fromIce(const manager::dto::SkillStatusUpdate& update);
+            provider::dto::SkillStatusUpdate toProviderIce() const;
 
             static SkillStatusUpdate FromIce(const provider::dto::SkillStatusUpdate& update,
                                              const std::string& providerName);
diff --git a/source/RobotAPI/libraries/skills/core/SpecializedSkill.h b/source/RobotAPI/libraries/skills/core/SpecializedSkill.h
deleted file mode 100644
index 3f2b9371e2b087b4a5da77fb06e898bca525c320..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/skills/core/SpecializedSkill.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#pragma once
-
-#include "Skill.h"
-
-#include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
-
-// Debug
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-
-namespace armarx
-{
-    namespace skills
-    {
-        template <class AronT>
-        class SpecializedSkill : public Skill
-        {
-        public:
-            using ParamType = AronT;
-
-            struct SpecializedInitInput
-            {
-                std::string executorName;
-                AronT params;
-            };
-
-            struct SpecializedMainInput
-            {
-                std::string executorName;
-                AronT params;
-                CallbackT callback;
-            };
-
-            struct SpecializedExitInput
-            {
-                std::string executorName;
-                AronT params;
-            };
-
-            using Skill::Skill;
-            virtual ~SpecializedSkill() = default;
-
-            /// returns the accepted type of the skill
-            static armarx::aron::type::ObjectPtr GetAcceptedType()
-            {
-                return AronT::ToAronType();
-            }
-
-            bool isSkillAvailable(const SpecializedInitInput& in) const
-            {
-                return this->isAvailable();
-            }
-
-            Skill::InitResult initSkill(const SpecializedInitInput& in)
-            {
-                Skill::_init();
-                return this->init(in);
-            }
-            Skill::MainResult mainOfSkill(const SpecializedMainInput& in)
-            {
-                Skill::_main();
-                return this->main(in);
-            }
-            Skill::ExitResult exitSkill(const SpecializedExitInput& in)
-            {
-                Skill::_exit();
-                return this->exit(in);
-            }
-
-            Skill::MainResult executeFullSkill(const SpecializedMainInput& in)
-            {
-                this->resetSkill();
-                this->initSkill(SpecializedInitInput({.executorName = in.executorName, .params = in.params}));
-                auto ret = this->mainOfSkill(in);
-                this->exit(SpecializedExitInput({.executorName = in.executorName, .params = in.params}));
-                return ret;
-            }
-
-        private:
-            /// Override this method if you want to disable a skill based on certain conditions
-            virtual bool isAvailable(const SpecializedInitInput&) const
-            {
-                return true;
-            }
-
-            /// Override this method with the actual implementation. The callback is for status updates to the calling instance
-            virtual Skill::InitResult init(const SpecializedInitInput&)
-            {
-                return InitResult{.status = TerminatedSkillStatus::Succeeded};
-            }
-
-            /// Override this method with the actual implementation. The callback is for status updates to the calling instance
-            virtual Skill::MainResult main(const SpecializedMainInput& in)
-            {
-                ARMARX_IMPORTANT << "Dummy executing skill '" << description.skillName << "'. Please overwrite this method.";
-                return Skill::MainResult{.status = TerminatedSkillStatus::Succeeded, .data = nullptr};
-            }
-
-            /// Override this method with the actual implementation. The callback is for status updates to the calling instance
-            virtual Skill::ExitResult exit(const SpecializedExitInput&)
-            {
-                return ExitResult{.status = TerminatedSkillStatus::Succeeded};
-            }
-
-            /// Do not use anymore
-            bool isAvailable(const InitInput& in) const final
-            {
-                AronT p;
-                p.fromAron(in.params);
-
-                return isAvailable(SpecializedInitInput({.executorName = in.executorName, .params = p}));
-            }
-
-            /// Do not use anymore
-            Skill::InitResult init(const InitInput& in) final
-            {
-                AronT p;
-                p.fromAron(in.params);
-
-                return init(SpecializedInitInput({.executorName = in.executorName, .params = p}));
-            }
-
-            /// Do not use anymore
-            Skill::MainResult main(const MainInput& in) final
-            {
-                AronT p;
-                p.fromAron(in.params);
-
-                return main(SpecializedMainInput({.executorName = in.executorName, .params = p, .callback = in.callback}));
-            }
-
-            /// Do not use anymore
-            Skill::ExitResult exit(const ExitInput& in) final
-            {
-                AronT p;
-                p.fromAron(in.params);
-
-                return exit(SpecializedExitInput({.executorName = in.executorName, .params = p}));
-            }
-        };
-    }
-}
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 5fbc2e925f5461514d4bec656762920935600ec3..057715f98f5f316fb6c6fd7e84b4fa096ddf766c 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -4,9 +4,9 @@
 #include <ArmarXCore/core/time/DateTime.h>
 #include <ArmarXCore/core/time/ice_conversions.h>
 
-#include <RobotAPI/libraries/skills/error/Exception.h>
-#include <RobotAPI/libraries/skills/provider/SkillID.h>
-#include <RobotAPI/libraries/skills/provider/SkillStatusUpdate.h>
+#include <RobotAPI/libraries/skills/core/SkillID.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
+#include <RobotAPI/libraries/skills/core/error/Exception.h>
 
 namespace armarx::plugins
 {
@@ -24,155 +24,206 @@ namespace armarx::plugins
     SkillManagerComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties)
     {
     }
-} // namespace armarx::plugins
 
-namespace armarx
-{
-    SkillManagerComponentPluginUser::SkillManagerComponentPluginUser()
+    skills::ProviderID
+    SkillManagerComponentPlugin::getFirstProviderNameThatHasSkill(const skills::SkillID& skillId)
     {
-        addPlugin(plugin);
+        // NON LOCKING! WE ASSERT THAT THE CALLER HOLDS LOCK
+        for (const auto& [providerName, providerPrx] : skillProviderMap)
+        {
+            auto allSkills = providerPrx->getSkillDescriptions();
+            for (const auto& [currentSkillID, skillDesc] : allSkills)
+            {
+                if (currentSkillID.skillName == skillId.skillName)
+                {
+                    return {providerName};
+                }
+            }
+        }
+        return {"INVALID PROVIDER NAME"};
     }
 
     void
-    SkillManagerComponentPluginUser::addProvider(const skills::manager::dto::ProviderInfo& info,
-                                                 const Ice::Current&)
+    SkillManagerComponentPlugin::addProvider(const skills::ProviderInfo& info)
     {
-        std::lock_guard l(skillProviderMapMutex);
-        if (skillProviderMap.find(info.providerName) == skillProviderMap.end())
+        std::scoped_lock l(skillProviderMapMutex);
+        if (skillProviderMap.find(info.providerId.providerName) == skillProviderMap.end())
         {
-            ARMARX_INFO << "Adding a provider with name '" << info.providerName << "'.";
-            skillProviderMap.insert({info.providerName, info.provider});
+            ARMARX_INFO << "Adding a provider with name '" << info.providerId.providerName << "'.";
+            skillProviderMap.insert({info.providerId.providerName, info.provider});
         }
         else
         {
-            ARMARX_INFO << "Trying to add a provider with name '" << info.providerName
+            ARMARX_INFO << "Trying to add a provider with name '" << info.providerId.providerName
                         << "' but the provider already exists. "
                         << "Overwriting the old provider info.";
-            skillProviderMap[info.providerName] = info.provider;
+            skillProviderMap[info.providerId.providerName] = info.provider;
         }
     }
 
     void
-    SkillManagerComponentPluginUser::removeProvider(const std::string& providerName,
-                                                    const Ice::Current&)
+    SkillManagerComponentPlugin::removeProvider(const skills::ProviderID& id)
     {
-        std::lock_guard l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
+        std::scoped_lock l(skillProviderMapMutex);
+        if (auto it = skillProviderMap.find(id.providerName); it != skillProviderMap.end())
         {
-            ARMARX_INFO << "Removing a provider with name '" << providerName << "'.";
+            ARMARX_INFO << "Removing a provider with name '" << id.providerName << "'.";
             skillProviderMap.erase(it);
         }
         else
         {
-            ARMARX_INFO << "Trying to remove a provider with name '" << providerName
+            ARMARX_INFO << "Trying to remove a provider with name '" << id.providerName
                         << "' but it couldn't be found.";
         }
     }
 
-    std::string
-    SkillManagerComponentPluginUser::getFirstProviderNameThatHasSkill(const std::string& skillName)
+    skills::SkillStatusUpdate
+    SkillManagerComponentPlugin::executeSkill(
+        const skills::SkillExecutionRequest& req,
+        const skills::callback::dti::SkillProviderCallbackInterfacePrx& myPrx)
     {
-        // NON LOCKING! WE ASSERT THAT THE CALLER HOLDS LOCK
-        for (const auto& [providerName, providerPrx] : skillProviderMap)
+        std::unique_lock l(skillProviderMapMutex);
+
+        skills::ProviderID provderId("INVALID PROVIDER NAME");
+
+        // TODO: Really support regexes!
+        if (req.skillId.providerName == "*")
         {
-            auto allSkills = providerPrx->getSkillDescriptions();
-            for (const auto& [currentSkillName, skillDesc] : allSkills)
+            provderId = getFirstProviderNameThatHasSkill(req.skillId.skillName);
+        }
+        else if (not(req.skillId.providerName.empty()))
+        {
+            provderId = skills::ProviderID(req.skillId);
+        }
+
+
+        if (auto it = skillProviderMap.find(provderId); it != skillProviderMap.end())
+        {
+            const auto& provider = it->second;
+
+            if (!provider)
             {
-                if (currentSkillName == skillName)
-                {
-                    return providerName;
-                }
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
+                               << provderId << "'. Removing it from skills.";
+                skillProviderMap.erase(it);
+
+                throw skills::error::SkillException(
+                    __PRETTY_FUNCTION__,
+                    "Skill execution failed. Could not execute a skill of provider '" +
+                        provderId.toString() + "' because the provider does not exist.");
             }
+
+            try
+            {
+                skills::SkillExecutionRequest exInfo(
+                    req.skillId, req.executorName, req.params, myPrx);
+
+                auto async = provider->begin_executeSkill(exInfo.toProviderIce());
+                l.unlock(); // allow parallel e.g. stopping
+                auto up = provider->end_executeSkill(async);
+
+                // convert to manager view
+                return skills::SkillStatusUpdate::FromIce(up, provderId.providerName);
+            }
+            catch (...)
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__
+                               << ": Found disconnected or buggy skill provider '" << provderId
+                               << "' during execution. Removing it from skills.";
+                skillProviderMap.erase(it);
+
+                throw skills::error::SkillException(
+                    __PRETTY_FUNCTION__,
+                    "Skill execution failed. Could not execute a skill of provider '" +
+                        provderId.toString() + "' because the provider does not exist.");
+            }
+        }
+        else
+        {
+            throw skills::error::SkillException(
+                __PRETTY_FUNCTION__,
+                "Skill execution failed. Could not execute a skill of provider '" +
+                    provderId.toString() + "' because the provider does not exist.");
         }
-        return "INVALID PROVIDER NAME";
     }
 
-    using SkillProviderInterfacePrxMap =
-        std::map<std::string, skills::provider::dti::SkillProviderInterfacePrx>;
-
-    skills::manager::dto::SkillStatusUpdate
-    SkillManagerComponentPluginUser::executeSkill(
-        const skills::manager::dto::SkillExecutionRequest& info,
-        const Ice::Current&)
+    skills::SkillExecutionId
+    SkillManagerComponentPlugin::executeSkillAsync(
+        const skills::SkillExecutionRequest& req,
+        const skills::callback::dti::SkillProviderCallbackInterfacePrx& myPrx)
     {
         std::unique_lock l(skillProviderMapMutex);
 
-        std::string providerName = "INVALID PROVIDER NAME";
+        skills::ProviderID provderId("INVALID PROVIDER NAME");
 
         // TODO: Really support regexes!
-        if (info.skillId.providerName == "*")
+        if (req.skillId.providerName == "*")
         {
-            providerName = getFirstProviderNameThatHasSkill(info.skillId.skillName);
+            provderId = getFirstProviderNameThatHasSkill(req.skillId.skillName);
         }
-        else if (not(info.skillId.providerName.empty()))
+        else if (not(req.skillId.providerName.empty()))
         {
-            providerName = info.skillId.providerName;
+            provderId = req.skillId.providerName;
         }
 
 
-        if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
+        if (auto it = skillProviderMap.find(provderId); it != skillProviderMap.end())
         {
             const auto& provider = it->second;
 
             if (!provider)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
-                               << providerName << "'. Removing it from skills.";
+                               << provderId << "'. Removing it from skills.";
                 skillProviderMap.erase(it);
 
                 throw skills::error::SkillException(
                     __PRETTY_FUNCTION__,
                     "Skill execution failed. Could not execute a skill of provider '" +
-                        providerName + "' because the provider does not exist.");
+                        provderId.toString() + "' because the provider does not exist.");
             }
 
             try
             {
-                skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx;
-                getProxy(myPrx, -1);
-
-                skills::provider::dto::SkillExecutionRequest exInfo;
-                exInfo.skillName = info.skillId.skillName;
-                exInfo.executorName = info.executorName;
-                exInfo.callbackInterface = myPrx;
-                exInfo.params = info.params;
+                skills::SkillExecutionRequest exInfo(
+                    req.skillId, req.executorName, req.params, myPrx);
 
-                auto async = provider->begin_executeSkill(exInfo);
+                auto async = provider->begin_executeSkillAsync(exInfo.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
-                auto up = provider->end_executeSkill(async);
+                auto up = provider->end_executeSkillAsync(async);
 
                 // convert to manager view
-                return skills::SkillStatusUpdate::FromIce(up, providerName).toIce();
+                return skills::SkillExecutionId::FromIce(up, provderId.providerName);
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__
-                               << ": Found disconnected or buggy skill provider '" << providerName
+                               << ": Found disconnected or buggy skill provider '" << provderId
                                << "' during execution. Removing it from skills.";
                 skillProviderMap.erase(it);
 
                 throw skills::error::SkillException(
                     __PRETTY_FUNCTION__,
                     "Skill execution failed. Could not execute a skill of provider '" +
-                        providerName + "' because the provider does not exist.");
+                        provderId.toString() + "' because the provider does not exist.");
             }
         }
         else
         {
             throw skills::error::SkillException(
                 __PRETTY_FUNCTION__,
-                "Skill execution failed. Could not execute a skill of provider '" + providerName +
-                    "' because the provider does not exist.");
+                "Skill execution failed. Could not execute a skill of provider '" +
+                    provderId.toString() + "' because the provider does not exist.");
         }
     }
 
     void
-    SkillManagerComponentPluginUser::abortSkill(const std::string& providerName,
-                                                const std::string& skillName,
-                                                const Ice::Current& current)
+    SkillManagerComponentPlugin::addSkillParameters(const skills::SkillExecutionId& id,
+                                                    const aron::data::DictPtr& data)
     {
         std::unique_lock l(skillProviderMapMutex);
-        if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
+        if (auto it = skillProviderMap.find(skills::ProviderID(id.skillId.providerName));
+            it != skillProviderMap.end())
         {
             const auto& providerName = it->first;
             const auto& provider = it->second;
@@ -187,9 +238,10 @@ namespace armarx
 
             try
             {
-                auto async = provider->begin_abortSkill(skillName);
+                auto async =
+                    provider->begin_addSkillParameters(id.toProviderIce(), data->toAronDictDTO());
                 l.unlock(); // allow parallel e.g. stopping
-                return provider->end_abortSkill(async);
+                return provider->end_addSkillParameters(async);
             }
             catch (...)
             {
@@ -200,20 +252,40 @@ namespace armarx
     }
 
     void
-    SkillManagerComponentPluginUser::updateStatusForSkill(
-        const skills::provider::dto::SkillStatusUpdate& statusUpdate,
-        const std::string& providerName,
-        const Ice::Current&)
+    SkillManagerComponentPlugin::abortSkill(const skills::SkillExecutionId& id)
     {
-        (void)statusUpdate;
-        (void)providerName;
-        // If you want to use the status, implement this method!
+        std::unique_lock l(skillProviderMapMutex);
+        if (auto it = skillProviderMap.find(id.skillId.providerName); it != skillProviderMap.end())
+        {
+            const auto& providerName = it->first;
+            const auto& provider = it->second;
+
+            if (!provider)
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
+                               << providerName << "'. Removing it from skills.";
+                skillProviderMap.erase(it);
+                return;
+            }
+
+            try
+            {
+                auto async = provider->begin_abortSkill(id.toProviderIce());
+                l.unlock(); // allow parallel e.g. stopping
+                return provider->end_abortSkill(async);
+            }
+            catch (...)
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
+                               << providerName << "'. Removing it from skills on next execute.";
+            }
+        }
     }
 
-    skills::manager::dto::SkillDescriptionMapMap
-    SkillManagerComponentPluginUser::getSkillDescriptions(const Ice::Current& current)
+    std::map<skills::SkillID, skills::SkillDescription>
+    SkillManagerComponentPlugin::getSkillDescriptions()
     {
-        skills::manager::dto::SkillDescriptionMapMap ret;
+        std::map<skills::SkillID, skills::SkillDescription> ret;
 
         std::scoped_lock l(skillProviderMapMutex);
         for (auto it = skillProviderMap.cbegin(); it != skillProviderMap.cend();)
@@ -232,7 +304,12 @@ namespace armarx
             try
             {
                 skills::provider::dto::SkillDescriptionMap m = provider->getSkillDescriptions();
-                ret.insert({providerName, m});
+
+                for (const auto& [k, v] : m)
+                {
+                    ret.insert({skills::SkillID::FromIce(k), skills::SkillDescription::FromIce(v)});
+                }
+
                 ++it;
             }
             catch (...)
@@ -245,103 +322,223 @@ namespace armarx
         return ret;
     }
 
-    skills::manager::dto::SkillStatusUpdate
-    SkillManagerComponentPluginUser::getSkillExecutionStatus(
-        const skills::manager::dto::SkillExecutionID& executionId,
-        const Ice::Current& current)
+    std::optional<skills::SkillStatusUpdate>
+    SkillManagerComponentPlugin::getSkillExecutionStatus(const skills::SkillExecutionId& execId)
     {
-        skills::SkillExecutionId execId = skills::SkillExecutionId::FromIce(executionId);
-
         std::unique_lock l(skillProviderMapMutex);
         if (auto it = skillProviderMap.find(execId.skillId.providerName);
             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);
 
                 throw skills::error::SkillException(__PRETTY_FUNCTION__,
                                                     "Skill execution failed. Could not query a "
                                                     "status update of a skill of provider '" +
-                                                        providerName +
+                                                        providerId.toString() +
                                                         "' because the provider does not exist.");
             }
 
             try
             {
-                auto async = provider->begin_getSkillExecutionStatus(execId.toIceProviderView());
+                auto async = provider->begin_getSkillExecutionStatus(execId.toProviderIce());
                 l.unlock(); // allow parallel e.g. stopping
                 auto up = provider->end_getSkillExecutionStatus(async);
 
                 // convert to manager view
-                return skills::SkillStatusUpdate::FromIce(up, providerName).toIce();
+                return skills::SkillStatusUpdate::FromIce(up, providerId.providerName);
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__
-                               << ": Found disconnected or buggy skill provider '" << providerName
+                               << ": 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 '" +
-                                                        providerName +
+                                                        providerId.toString() +
                                                         "' because the provider does not exist.");
             }
         }
         else
         {
-            // no actove skill. Return idle
-            skills::SkillStatusUpdate idle;
-            idle.executionId = execId;
-            return idle.toIce();
+            // no actove skill. Return null
+            return std::nullopt;
         }
     }
 
-    skills::manager::dto::SkillStatusUpdateList
-    SkillManagerComponentPluginUser::getSkillExecutionStatuses(const Ice::Current& current)
+    std::map<skills::SkillExecutionId, skills::SkillStatusUpdate>
+    SkillManagerComponentPlugin::getSkillExecutionStatuses()
     {
-        skills::manager::dto::SkillStatusUpdateList ret;
+        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> ret;
 
         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;
             }
 
             try
             {
-                skills::provider::dto::SkillStatusUpdateList m =
-                    provider->getSkillExecutionStatuses();
+                auto m = provider->getSkillExecutionStatuses();
 
-                for (const auto& up : m)
+                for (const auto& [k, v] : m)
                 {
-                    // convert provider view to manager view
-                    ret.push_back(skills::SkillStatusUpdate::FromIce(up, providerName).toIce());
+                    ret.insert({skills::SkillExecutionId::FromIce(k, providerId.providerName),
+                                skills::SkillStatusUpdate::FromIce(v, providerId.providerName)});
                 }
                 it++;
             }
             catch (...)
             {
                 ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found buggy skill provider '"
-                               << providerName << "'. Removing it from skills.";
+                               << providerId << "'. Removing it from skills.";
                 it = skillProviderMap.erase(it);
             }
         }
         return ret;
     }
+
+} // namespace armarx::plugins
+
+namespace armarx
+{
+    SkillManagerComponentPluginUser::SkillManagerComponentPluginUser()
+    {
+        addPlugin(plugin);
+    }
+
+    void
+    SkillManagerComponentPluginUser::addProvider(const skills::manager::dto::ProviderInfo& info,
+                                                 const Ice::Current&)
+    {
+        auto i = skills::ProviderInfo::FromIce(info);
+        this->plugin->addProvider(i);
+    }
+
+    void
+    SkillManagerComponentPluginUser::removeProvider(
+        const skills::manager::dto::ProviderID& provider,
+        const Ice::Current&)
+    {
+        auto i = skills::ProviderID::FromIce(provider);
+        this->plugin->removeProvider(i);
+    }
+
+    using SkillProviderInterfacePrxMap =
+        std::map<std::string, skills::provider::dti::SkillProviderInterfacePrx>;
+
+    skills::manager::dto::SkillStatusUpdate
+    SkillManagerComponentPluginUser::executeSkill(
+        const skills::manager::dto::SkillExecutionRequest& info,
+        const Ice::Current&)
+    {
+        skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx;
+        getProxy(myPrx, -1);
+
+        auto e = skills::SkillExecutionRequest::FromIce(info);
+        return this->plugin->executeSkill(e, myPrx).toManagerIce();
+    }
+
+    skills::manager::dto::SkillExecutionID
+    SkillManagerComponentPluginUser::executeSkillAsync(
+        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();
+    }
+
+    void
+    SkillManagerComponentPluginUser::addSkillParameters(
+        const skills::manager::dto::SkillExecutionID& info,
+        const aron::data::dto::DictPtr& params,
+        const Ice::Current& current)
+    {
+        auto a = armarx::aron::data::Dict::FromAronDictDTO(params);
+        auto e = skills::SkillExecutionId::FromIce(info);
+        this->plugin->addSkillParameters(e, a);
+    }
+
+    void
+    SkillManagerComponentPluginUser::abortSkill(const skills::manager::dto::SkillExecutionID& id,
+                                                const Ice::Current& current)
+    {
+        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 Ice::Current&)
+    {
+        (void)statusUpdate;
+        (void)pid;
+        // If you want to use the status, implement this method!
+    }
+
+    skills::manager::dto::SkillDescriptionMap
+    SkillManagerComponentPluginUser::getSkillDescriptions(const Ice::Current& current)
+    {
+        skills::manager::dto::SkillDescriptionMap ret;
+
+        auto m = this->plugin->getSkillDescriptions();
+
+        for (const auto& [k, v] : m)
+        {
+            ret.insert({k.toManagerIce(), v.toIce()});
+        }
+
+        return ret;
+    }
+
+    skills::manager::dto::SkillStatusUpdate
+    SkillManagerComponentPluginUser::getSkillExecutionStatus(
+        const skills::manager::dto::SkillExecutionID& executionId,
+        const Ice::Current& current)
+    {
+        auto e = skills::SkillExecutionId::FromIce(executionId);
+        auto o = this->plugin->getSkillExecutionStatus(e);
+        if (o.has_value())
+        {
+            return o->toManagerIce();
+        }
+        return {}; // TODO!!
+    }
+
+    skills::manager::dto::SkillStatusUpdateMap
+    SkillManagerComponentPluginUser::getSkillExecutionStatuses(const Ice::Current& current)
+    {
+        skills::manager::dto::SkillStatusUpdateMap ret;
+
+        auto m = this->plugin->getSkillExecutionStatuses();
+
+        for (const auto& [k, v] : m)
+        {
+            ret.insert({k.toManagerIce(), v.toManagerIce()});
+        }
+
+        return ret;
+    }
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
index cd3a576dec2cb53ee419f29de5db6546ac66ea09..5aaadd6e6dc35038b0aaf1dbff259cdf934e88c8 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
@@ -6,6 +6,10 @@
 #include <ArmarXCore/core/ManagedIceObject.h>
 
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
+#include <RobotAPI/libraries/skills/core/ProviderID.h>
+#include <RobotAPI/libraries/skills/core/ProviderInfo.h>
+#include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
 
 namespace armarx::plugins
 {
@@ -19,6 +23,37 @@ namespace armarx::plugins
         void preOnConnectComponent() override;
 
         void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override;
+
+        void addProvider(const skills::ProviderInfo& info);
+
+        void removeProvider(const skills::ProviderID& id);
+
+        skills::SkillStatusUpdate
+        executeSkill(const skills::SkillExecutionRequest& req,
+                     const skills::callback::dti::SkillProviderCallbackInterfacePrx& prx);
+
+        skills::SkillExecutionId
+        executeSkillAsync(const skills::SkillExecutionRequest& req,
+                          const skills::callback::dti::SkillProviderCallbackInterfacePrx& prx);
+
+        void addSkillParameters(const skills::SkillExecutionId& id,
+                                const aron::data::DictPtr& data);
+
+        void abortSkill(const skills::SkillExecutionId& id);
+
+        std::map<skills::SkillID, skills::SkillDescription> getSkillDescriptions();
+
+        std::optional<skills::SkillStatusUpdate>
+        getSkillExecutionStatus(const skills::SkillExecutionId& id);
+
+        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> getSkillExecutionStatuses();
+
+        skills::ProviderID getFirstProviderNameThatHasSkill(const skills::SkillID& skillid);
+
+    protected:
+        std::mutex skillProviderMapMutex;
+        std::map<skills::ProviderID, skills::provider::dti::SkillProviderInterfacePrx>
+            skillProviderMap;
     };
 } // namespace armarx::plugins
 
@@ -33,36 +68,39 @@ namespace armarx
 
         void addProvider(const skills::manager::dto::ProviderInfo& providerInfo,
                          const Ice::Current& current) override;
-        void removeProvider(const std::string&, const Ice::Current& current) override;
+        void removeProvider(const skills::manager::dto::ProviderID& provider,
+                            const Ice::Current& current) override;
 
         skills::manager::dto::SkillStatusUpdate
         executeSkill(const skills::manager::dto::SkillExecutionRequest& info,
                      const Ice::Current& current) override;
+
+        skills::manager::dto::SkillExecutionID
+        executeSkillAsync(const skills::manager::dto::SkillExecutionRequest& skillExecutionRequest,
+                          const Ice::Current& current) override;
+
+        void addSkillParameters(const skills::manager::dto::SkillExecutionID& executionId,
+                                const aron::data::dto::DictPtr& params,
+                                const Ice::Current& current) override;
+
         void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update,
-                                  const std::string& providerName,
+                                  const skills::provider::dto::ProviderID& id,
                                   const Ice::Current& current) override;
-        void abortSkill(const std::string& providerName,
-                        const std::string& skillName,
+
+        void abortSkill(const skills::manager::dto::SkillExecutionID& id,
                         const Ice::Current& current) override;
 
-        skills::manager::dto::SkillDescriptionMapMap
+        skills::manager::dto::SkillDescriptionMap
         getSkillDescriptions(const Ice::Current& current) override;
 
         skills::manager::dto::SkillStatusUpdate
         getSkillExecutionStatus(const skills::manager::dto::SkillExecutionID& executionId,
                                 const Ice::Current& current) override;
 
-        skills::manager::dto::SkillStatusUpdateList
+        skills::manager::dto::SkillStatusUpdateMap
         getSkillExecutionStatuses(const Ice::Current& current) override;
 
-    protected:
-        std::string getFirstProviderNameThatHasSkill(const std::string& skillName);
-
     private:
         armarx::plugins::SkillManagerComponentPlugin* plugin = nullptr;
-
-    protected:
-        std::mutex skillProviderMapMutex;
-        std::map<std::string, skills::provider::dti::SkillProviderInterfacePrx> skillProviderMap;
     };
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/CMakeLists.txt b/source/RobotAPI/libraries/skills/provider/CMakeLists.txt
index 46fae9591072d31c9d40e97728ed9c849c3ba0d4..4ba71803f991a7ba83aa1562299a08c1090f4587 100644
--- a/source/RobotAPI/libraries/skills/provider/CMakeLists.txt
+++ b/source/RobotAPI/libraries/skills/provider/CMakeLists.txt
@@ -17,19 +17,34 @@ armarx_add_library(
 
     SOURCES  
         SkillProviderComponentPlugin.cpp
-        SkillStatusUpdate.cpp
-        SkillParameterization.cpp
+        SkillFactory.cpp
         LambdaSkill.cpp
-        SkillID.cpp
+        SkillProxy.cpp
+        PeriodicSkill.cpp
+        SpecializedSkill.cpp
+        PeriodicSpecializedSkill.cpp
         detail/SkillImplementationWrapper.cpp
+        SkillContext.cpp
         
     HEADERS
         SkillProviderComponentPlugin.h
-        SkillStatusUpdate.h
-        SkillParameterization.h
+        SkillFactory.h
         LambdaSkill.h
-        SkillID.h
+        SkillProxy.h
+        PeriodicSkill.h
+        SpecializedSkill.h
+        PeriodicSpecializedSkill.h
         detail/SkillImplementationWrapper.h
+        SkillContext.h
+
+        mixins/All.h
+        mixins/ArvizSkillMixin.h
+        mixins/MNSSkillMixin.h
+        mixins/MemoryReadingSkillMixin.h
+        mixins/RobotReadingSkillMixin.h
+        mixins/ObjectReadingSkillMixin.h
+        mixins/ObjectWritingSkillMixin.h
+        mixins/GraspReadingSkillMixin.h
 )
 
 add_library(RobotAPI::skills::provider ALIAS RobotAPISkillsProvider)
diff --git a/source/RobotAPI/libraries/skills/provider/LambdaSkill.cpp b/source/RobotAPI/libraries/skills/provider/LambdaSkill.cpp
index 280cdb93e5eb62413a159f232b20c5da0b7e3bd7..804042b8ac47b2b1c0ec762c87c4e4ce186daf97 100644
--- a/source/RobotAPI/libraries/skills/provider/LambdaSkill.cpp
+++ b/source/RobotAPI/libraries/skills/provider/LambdaSkill.cpp
@@ -5,11 +5,12 @@ namespace armarx
     namespace skills
     {
 
-        Skill::MainResult LambdaSkill::main(const MainInput& in)
+        Skill::MainResult
+        LambdaSkill::main()
         {
-            TerminatedSkillStatus res = fun(in.executorName, in.params);
+            TerminatedSkillStatus res = fun();
 
             return {.status = res, .data = nullptr};
         }
-    }
-}
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/LambdaSkill.h b/source/RobotAPI/libraries/skills/provider/LambdaSkill.h
index 01e3a3897e78b444c222b352556bea118f5bc50f..dda6c472c711f9cae1c3d6ac396218ef10f50ca5 100644
--- a/source/RobotAPI/libraries/skills/provider/LambdaSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/LambdaSkill.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Skill.h"
+#include <RobotAPI/libraries/skills/core/Skill.h>
 
 namespace armarx
 {
@@ -9,19 +9,16 @@ namespace armarx
         class LambdaSkill : public Skill
         {
         public:
-            using FunT = std::function<TerminatedSkillStatus(const std::string clientId, const aron::data::DictPtr&)>;
+            using FunT = std::function<TerminatedSkillStatus()>;
 
             LambdaSkill() = delete;
-            LambdaSkill(const FunT& f, const SkillDescription& desc) :
-                Skill(desc),
-                fun(f)
-            {};
+            LambdaSkill(const SkillDescription& desc, const FunT& f) : Skill(desc), fun(f){};
 
         private:
-            MainResult main(const MainInput& in) override;
+            MainResult main() override;
 
         private:
             FunT fun;
         };
-    }
-}
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/core/PeriodicSkill.cpp b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
similarity index 81%
rename from source/RobotAPI/libraries/skills/core/PeriodicSkill.cpp
rename to source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
index 70daa959f0256646125c8477768f304db5555312..4df38fb17050ad444472327ae14dca744c559a3c 100644
--- a/source/RobotAPI/libraries/skills/core/PeriodicSkill.cpp
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.cpp
@@ -26,27 +26,30 @@
 #include "ArmarXCore/core/time/Frequency.h"
 #include <ArmarXCore/core/time/Metronome.h>
 
-#include "RobotAPI/libraries/skills/provider/Skill.h"
+#include "RobotAPI/libraries/skills/core/Skill.h"
 
 namespace armarx::skills
 {
-    PeriodicSkill::PeriodicSkill(const SkillDescription& skillDescription, const armarx::Frequency& frequency) :
+    PeriodicSkill::PeriodicSkill(const SkillDescription& skillDescription,
+                                 const armarx::Frequency& frequency) :
         Skill(skillDescription), frequency(frequency)
     {
     }
 
-    PeriodicSkill::StepResult PeriodicSkill::stepOfSkill(const MainInput& in)
+    PeriodicSkill::StepResult
+    PeriodicSkill::stepOfSkill()
     {
-        return this->step(in);
+        return this->step();
     }
 
-    Skill::MainResult PeriodicSkill::main(const MainInput& in)
+    Skill::MainResult
+    PeriodicSkill::main()
     {
         core::time::Metronome metronome(frequency);
 
         while (not Skill::checkWhetherSkillShouldStopASAP())
         {
-            const auto res = stepOfSkill(in);
+            const auto res = stepOfSkill();
             switch (res.status)
             {
                 case ActiveOrTerminatedSkillStatus::Running:
@@ -63,7 +66,9 @@ namespace armarx::skills
             const auto sleepDuration = metronome.waitForNextTick();
             if (not sleepDuration.isPositive())
             {
-                ARMARX_INFO << deactivateSpam() << "PeriodicSkill: execution took too long (" << -sleepDuration << " too long. Expected " << frequency.toCycleDuration() << ")";
+                ARMARX_INFO << deactivateSpam() << "PeriodicSkill: execution took too long ("
+                            << -sleepDuration << " too long. Expected "
+                            << frequency.toCycleDuration() << ")";
             }
         }
 
@@ -81,10 +86,11 @@ namespace armarx::skills
         throw skills::error::SkillException(__PRETTY_FUNCTION__, "Should not happen!");
     }
 
-
-    PeriodicSkill::StepResult PeriodicSkill::step(const MainInput& in)
+    PeriodicSkill::StepResult
+    PeriodicSkill::step()
     {
-        ARMARX_IMPORTANT << "Dummy executing once skill '" << description.skillName << "'. Please overwrite this method!";
+        ARMARX_IMPORTANT << "Dummy executing once skill '" << description.skillId
+                         << "'. Please overwrite this method!";
         return {ActiveOrTerminatedSkillStatus::Succeeded, nullptr};
     }
 
diff --git a/source/RobotAPI/libraries/skills/core/PeriodicSkill.h b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
similarity index 88%
rename from source/RobotAPI/libraries/skills/core/PeriodicSkill.h
rename to source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
index 5df6e07e9b7304b8e7c4db10141d3980f31a041c..60823be8cdd6881b02ca4cad905d2bc30908ae15 100644
--- a/source/RobotAPI/libraries/skills/core/PeriodicSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSkill.h
@@ -23,7 +23,8 @@
 
 #include <ArmarXCore/core/time/Frequency.h>
 
-#include "Skill.h"
+#include <RobotAPI/libraries/skills/core/Skill.h>
+
 #include "SpecializedSkill.h"
 
 namespace armarx::skills
@@ -40,19 +41,18 @@ namespace armarx::skills
 
         PeriodicSkill(const SkillDescription& skillDescription, const armarx::Frequency& frequency);
 
-        StepResult stepOfSkill(const MainInput& in);
+        StepResult stepOfSkill();
 
     private:
         /// Do not use anymore
-        Skill::MainResult main(const MainInput& in) final;
+        Skill::MainResult main() final;
 
         /// Override this method with your own step function
-        virtual StepResult step(const MainInput& in);
+        virtual StepResult step();
 
     private:
         const armarx::Frequency frequency;
     };
 
 
-  
 } // namespace armarx::skills
diff --git a/source/RobotAPI/libraries/skills/core/PeriodicSpecializedSkill.cpp b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.cpp
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/PeriodicSpecializedSkill.cpp
rename to source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.cpp
diff --git a/source/RobotAPI/libraries/skills/core/PeriodicSpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
similarity index 84%
rename from source/RobotAPI/libraries/skills/core/PeriodicSpecializedSkill.h
rename to source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
index 4efac5d6d3ff33206063b928cd202e45476b0b63..83f9ae009d1245511d222240c0fc185a2aefea70 100644
--- a/source/RobotAPI/libraries/skills/core/PeriodicSpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/PeriodicSpecializedSkill.h
@@ -24,7 +24,8 @@
 #include <ArmarXCore/core/time/Frequency.h>
 #include <ArmarXCore/core/time/Metronome.h>
 
-#include "Skill.h"
+#include <RobotAPI/libraries/skills/core/Skill.h>
+
 #include "PeriodicSkill.h"
 #include "SpecializedSkill.h"
 
@@ -42,15 +43,17 @@ namespace armarx::skills
         using StepResult = PeriodicSkill::StepResult;
 
         PeriodicSpecializedSkill() = delete;
-        PeriodicSpecializedSkill(const SkillDescription& skillDescription, const armarx::Frequency& frequency) :
+
+        PeriodicSpecializedSkill(const SkillDescription& skillDescription,
+                                 const armarx::Frequency& frequency) :
             Base(skillDescription), frequency(frequency)
         {
         }
 
-
-        StepResult stepOfSkill(const typename Base::SpecializedMainInput& in)
+        StepResult
+        stepOfSkill()
         {
-            return this->step(in);
+            return this->step();
         }
 
     private:
@@ -58,13 +61,14 @@ namespace armarx::skills
         using Skill::timeoutReached;
 
         /// Do not use anymore
-        Skill::MainResult main(const typename Base::SpecializedMainInput& in) final
+        Skill::MainResult
+        main() final
         {
             core::time::Metronome metronome(frequency);
 
             while (not Skill::checkWhetherSkillShouldStopASAP())
             {
-                const auto statusUpdate = stepOfSkill(in);
+                const auto statusUpdate = stepOfSkill();
                 switch (statusUpdate.status)
                 {
                     case ActiveOrTerminatedSkillStatus::Running:
@@ -81,7 +85,9 @@ namespace armarx::skills
                 const auto sleepDuration = metronome.waitForNextTick();
                 if (not sleepDuration.isPositive())
                 {
-                    ARMARX_INFO << deactivateSpam() << "PeriodicSkill: execution took too long (" << -sleepDuration << " too long. Expected " << frequency.toCycleDuration() << ")";
+                    ARMARX_INFO << deactivateSpam() << "PeriodicSkill: execution took too long ("
+                                << -sleepDuration << " too long. Expected "
+                                << frequency.toCycleDuration() << ")";
                 }
             }
 
@@ -100,9 +106,11 @@ namespace armarx::skills
         }
 
         /// Override this method with your own step function
-        virtual StepResult step(const typename Base::SpecializedMainInput& in)
+        virtual StepResult
+        step()
         {
-            ARMARX_IMPORTANT << "Dummy executing once skill '" << this->description.skillName << "'. Please overwrite this method!";
+            ARMARX_IMPORTANT << "Dummy executing once skill '" << this->description.skillName
+                             << "'. Please overwrite this method!";
             return {ActiveOrTerminatedSkillStatus::Succeeded, nullptr};
         }
 
diff --git a/source/RobotAPI/libraries/skills/core/SkillContext.cpp b/source/RobotAPI/libraries/skills/provider/SkillContext.cpp
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/SkillContext.cpp
rename to source/RobotAPI/libraries/skills/provider/SkillContext.cpp
diff --git a/source/RobotAPI/libraries/skills/core/SkillContext.h b/source/RobotAPI/libraries/skills/provider/SkillContext.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/SkillContext.h
rename to source/RobotAPI/libraries/skills/provider/SkillContext.h
diff --git a/source/RobotAPI/libraries/skills/provider/SkillFactory.cpp b/source/RobotAPI/libraries/skills/provider/SkillFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78ec9ef6d60dabdf1dab84964aa3722cec9256e5
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SkillFactory.cpp
@@ -0,0 +1,6 @@
+#include "SkillFactory.h"
+
+namespace armarx
+{
+
+}
diff --git a/source/RobotAPI/libraries/skills/provider/SkillFactory.h b/source/RobotAPI/libraries/skills/provider/SkillFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..eadb1bab9300ee5c0b527f8fa8095bc540ca55c1
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SkillFactory.h
@@ -0,0 +1,90 @@
+#pragma once
+
+#include <tuple>
+
+#include <RobotAPI/libraries/skills/core/Skill.h>
+
+namespace armarx
+{
+    namespace skills
+    {
+        class SkillFactory
+        {
+        public:
+            using FunT = std::function<std::unique_ptr<Skill>()>;
+
+            SkillFactory(const SkillDescription& id, const FunT& f) : fun(f), desc(id)
+            {
+            }
+
+            template <class _Skill, class... Args>
+            requires isSkill<_Skill>
+
+            static std::unique_ptr<SkillFactory>
+            ForSkill(const SkillDescription& id, 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>
+
+            static std::unique_ptr<SkillFactory>
+            ForSkillDescriptionGetter(Args&&... args)
+
+            {
+                return std::make_unique<SkillFactory>(
+                    _Skill::GetSkillDescription(),
+                    [&]() { return std::make_unique<_Skill>(std::forward<Args>(args)...); });
+            }
+
+            virtual std::unique_ptr<Skill>
+            createSkill() const
+            {
+                return fun();
+            }
+
+            const SkillDescription&
+            getSkillDescription() const
+            {
+                return desc;
+            }
+
+            void
+            setOwner(const std::string& providerName)
+            {
+                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;
+            }
+
+
+        protected:
+            FunT fun;
+
+            SkillDescription desc;
+        };
+
+        template <class T>
+        concept isSkillFactory = std::is_base_of<SkillFactory, T>::value;
+
+    } // namespace skills
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
index 0e63d700d43c9aaba521a0aeb77181552a2ff2a2..3686ccb9fc32da8b6568644a6c8cb031bbb0391c 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp
@@ -24,21 +24,12 @@ namespace armarx::plugins
         auto& p = parent<SkillProviderComponentPluginUser>();
         const std::string providerName = p.getName();
 
-        // update skill ownership
-        for (auto& [skillName, impl] : skillImplementations)
-        {
-            impl.skill->manager = manager;
-            impl.skill->providerName = providerName;
-        }
-
         // register self to manager
         skills::manager::dto::ProviderInfo i;
         i.provider = myPrx;
-        i.providerName = providerName;
+        i.providerId = {providerName};
         i.providedSkills = p.getSkillDescriptions();
-        manager->addProvider(i);
-
-        connected = true;
+        manager->addProvider(i); // add provider info to manager
     }
 
     void
@@ -47,7 +38,8 @@ namespace armarx::plugins
         auto& p = parent<SkillProviderComponentPluginUser>();
         std::string providerName = p.getName();
 
-        manager->removeProvider(providerName);
+        auto id = skills::manager::dto::ProviderID{providerName};
+        manager->removeProvider(id);
     }
 
     void
@@ -62,82 +54,272 @@ namespace armarx::plugins
     }
 
     void
-    SkillProviderComponentPlugin::addSkill(const skills::LambdaSkill::FunT& f,
-                                           const skills::SkillDescription& desc)
+    SkillProviderComponentPlugin::addSkillFactory(const skills::LambdaSkill::FunT& f,
+                                                  const skills::SkillDescription& desc)
     {
-        auto lambda = std::make_unique<skills::LambdaSkill>(f, desc);
-        addSkill(std::move(lambda));
+        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::addSkill(std::unique_ptr<skills::Skill>&& skill)
+    SkillProviderComponentPlugin::addSkillFactory(std::unique_ptr<skills::SkillFactory>&& fac)
     {
-        if (!skill)
+        if (!fac)
         {
             return;
         }
 
-        std::string skillName = skill->description.skillName;
+        auto& p = parent<SkillProviderComponentPluginUser>();
+        const std::string providerName = p.getName();
 
         // lock skills map
-        const std::unique_lock l(skillImplementationsMapMutex);
-        if (skillImplementations.find(skillName) != skillImplementations.end())
+        const std::unique_lock l(skillFactoriesMutex);
+        auto skillId = fac->getSkillID(providerName);
+
+        if (skillFactories.find(skillId) != skillFactories.end())
         {
-            ARMARX_WARNING << "Try to add a skill '" + skillName +
+            ARMARX_WARNING << "Try to add a skill factory for skill '" + skillId.toString() +
                                   "' which already exists in list. Ignoring this skill.";
             return;
         }
 
-        ARMARX_INFO << "Adding skill and set owning provider name `" << skillName << "`.";
-        auto s = skillImplementations.emplace(skillName, std::move(skill));
+        ARMARX_INFO << "Adding skill `" << skillId << "` and set owning provider name to `"
+                    << providerName << "` .";
+        fac->setOwner(providerName);
 
-        if (connected)
-        {
-            // if skill is added after onConnect we have to set the proxies manually.
-            std::string providerName = parent().getName();
-            s.first->second.skill->manager = manager;
-            s.first->second.skill->providerName = providerName;
-        }
+        skillFactories.emplace(fac->getSkillID(), std::move(fac));
+
+        //        if (connected)
+        //        {
+        //            // if skill is added after onConnect we have to set the proxies manually.
+        //            std::string providerName = parent().getName();
+        //            s.first->second.skill->manager = manager;
+        //            s.first->second.skill->providerName = providerName;
+        //        }
+    }
+
+    skills::SkillFactory*
+    SkillProviderComponentPlugin::getSkillFactory(const armarx::skills::SkillID& skill)
+    {
+        ARMARX_CHECK_GREATER(skillFactories.count(skill), 0)
+            << "Skill '" + skill.toString() + "' not found.";
+
+        const std::unique_lock l(skillFactoriesMutex);
+        auto* facPtr = skillFactories.at(skill).get();
+        return static_cast<skills::SkillFactory*>(facPtr);
     }
 
-    skills::detail::SkillImplementationWrapper&
-    SkillProviderComponentPlugin::getSkill(const std::string& name)
+    std::optional<skills::SkillStatusUpdate>
+    SkillProviderComponentPlugin::getSkillExecutionStatus(
+        const skills::SkillExecutionId& execId) const
     {
-        ARMARX_CHECK_GREATER(skillImplementations.count(name), 0)
-            << "Skill '" + name + "' not found.";
-        const std::unique_lock l(skillImplementationsMapMutex);
-        return skillImplementations.at(name);
+        const std::unique_lock l(skillExecutionsMutex);
+        if (skillExecutions.find(execId) != skillExecutions.end())
+        {
+            ARMARX_WARNING << "Skill execution for skill '" + execId.skillId.toString() +
+                                  "' not found!";
+            return std::nullopt;
+        }
+
+        return skillExecutions.at(execId).statusUpdate;
     }
 
-    skills::provider::dto::SkillStatusUpdateList
+    std::map<skills::SkillExecutionId, skills::SkillStatusUpdate>
     SkillProviderComponentPlugin::getSkillExecutionStatuses() const
     {
-        skills::provider::dto::SkillStatusUpdateList skillUpdates;
-        const std::unique_lock l(skillImplementationsMapMutex);
-        for (const auto& [key, impl] : skillImplementations)
+        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate> skillUpdates;
+
+        const std::scoped_lock l(skillExecutionsMutex);
+        for (const auto& [key, impl] : skillExecutions)
         {
-            const std::shared_lock l2(impl.skillStatusesMutex);
-            for (const auto& [execId, up] : impl.statusUpdates)
-            {
-                (void)execId;
-                skillUpdates.push_back(up.toIceProviderView());
-            }
+            const std::scoped_lock l2(impl.skillStatusesMutex);
+            skillUpdates.insert({key, impl.statusUpdate});
         }
         return skillUpdates;
     }
 
-    skills::provider::dto::SkillDescriptionMap
+    std::optional<skills::SkillDescription>
+    SkillProviderComponentPlugin::getSkillDescription(const skills::SkillID& skillId) const
+    {
+        const std::unique_lock l(skillFactoriesMutex);
+        if (skillFactories.find(skillId) != skillFactories.end())
+        {
+            ARMARX_WARNING << "Skill description for skill '" + skillId.toString() + "' not found!";
+            return std::nullopt;
+        }
+
+        return skillFactories.at(skillId)->getSkillDescription();
+    }
+
+    std::map<skills::SkillID, skills::SkillDescription>
     SkillProviderComponentPlugin::getSkillDescriptions() const
     {
-        skills::provider::dto::SkillDescriptionMap skillDesciptions;
-        const std::unique_lock l(skillImplementationsMapMutex);
-        for (const auto& [key, impl] : skillImplementations)
+        std::map<skills::SkillID, skills::SkillDescription> skillDesciptions;
+        const std::unique_lock l(skillFactoriesMutex);
+        for (const auto& [key, fac] : skillFactories)
         {
-            skillDesciptions.insert({key, impl.skill->description.toIce()});
+            skillDesciptions.insert({key, fac->getSkillDescription()});
         }
         return skillDesciptions;
     }
 
+    skills::SkillStatusUpdate
+    SkillProviderComponentPlugin::executeSkill(const skills::SkillExecutionRequest& executionInfo)
+    {
+        // 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::SkillExecutionId execId(
+            executionInfo.skillId, executionInfo.executorName, armarx::core::time::DateTime::Now());
+
+        skills::SkillStatusUpdate ret{execId, usedParameterization};
+        {
+            auto l1 = std::unique_lock{skillFactoriesMutex};
+
+            const auto& id = executionInfo.skillId;
+            const auto& fac = getSkillFactory(id);
+
+            // async start execution. But we wait for the execution to finish at the end of this method
+            execution = std::thread(
+                [&]()
+                {
+                    skills::detail::SkillImplementationWrapper* wrapper;
+                    {
+                        const std::unique_lock l2{skillExecutionsMutex};
+                        auto it = skillExecutions.emplace(
+                            std::piecewise_construct,
+                            std::make_tuple(execId),
+                            std::make_tuple(fac, execId, usedParameterization));
+
+                        ARMARX_CHECK(it.second)
+                            << "For some reason a skill '" << execId.skillId.toString()
+                            << "' execution failed when instantiating the "
+                               "wrapper class and adding it to the internally used map. This "
+                               "should "
+                               "not happen!!";
+
+                        wrapper = &it.first->second;
+                    }
+
+
+                    // execute waits until the previous execution finishes.
+                    auto x = wrapper->executeSkill();
+                    ret.data = x.data;
+                    ret.status = armarx::skills::toSkillStatus(x.status);
+                });
+        } // release lock. We don't know how long the skill needs to finish and we have to release the lock for being able to abort the execution
+
+        if (execution.joinable())
+        {
+            execution.join();
+
+            // tidy up map of executions
+            const std::unique_lock l2{skillExecutionsMutex};
+            if (auto it = skillExecutions.find(execId); it != skillExecutions.end())
+            {
+                skillExecutions.erase(it);
+            }
+        }
+        return ret;
+    }
+
+    skills::SkillExecutionId
+    SkillProviderComponentPlugin::executeSkillAsync(
+        const skills::SkillExecutionRequest& executionInfo)
+    {
+        // 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::SkillExecutionId execId(
+            executionInfo.skillId, executionInfo.executorName, armarx::core::time::DateTime::Now());
+
+        {
+            auto l1 = std::unique_lock{skillFactoriesMutex};
+
+            const auto& id = executionInfo.skillId;
+            const auto& fac = getSkillFactory(id);
+
+            // async start execution. But we wait for the execution to finish at the end of this method
+            execution = std::thread(
+                [&]()
+                {
+                    skills::detail::SkillImplementationWrapper* wrapper;
+                    {
+                        const std::unique_lock l2{skillExecutionsMutex};
+                        auto it = skillExecutions.emplace(
+                            std::piecewise_construct,
+                            std::make_tuple(execId),
+                            std::make_tuple(fac, execId, usedParameterization));
+
+                        ARMARX_CHECK(it.second)
+                            << "For some reason a skill '" << execId.skillId.toString()
+                            << "' execution failed when instantiating the "
+                               "wrapper class and adding it to the internally used map. This "
+                               "should "
+                               "not happen!!";
+
+                        wrapper = &it.first->second;
+                    }
+
+
+                    // execute waits until the previous execution finishes.
+                    auto x = wrapper->executeSkill();
+                });
+        } // release lock. We don't know how long the skill needs to finish and we have to release the lock for being able to abort the execution
+
+        execution.detach();
+        return execId;
+    }
+
+    void
+    SkillProviderComponentPlugin::addSkillParameters(const skills::SkillExecutionId& id,
+                                                     const armarx::aron::data::DictPtr& input)
+    {
+        const std::scoped_lock l{skillExecutionsMutex};
+        auto it = skillExecutions.find(id);
+        if (it == skillExecutions.end())
+        {
+            ARMARX_INFO << "No acive execution for skill '" + id.skillId.toString() +
+                               "' found! Ignoring prepareSkill request.";
+            return;
+        }
+
+        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() +
+                               "' because its not in preparing phase.";
+            return;
+        }
+
+        it->second.addSkillParameters(input);
+    }
+
+    void
+    SkillProviderComponentPlugin::abortSkill(const skills::SkillExecutionId& execId)
+    {
+        const std::unique_lock l(skillExecutionsMutex);
+        auto it = skillExecutions.find(execId);
+        if (it == skillExecutions.end())
+        {
+            ARMARX_INFO << "No acive execution for skill '" + execId.skillId.toString() +
+                               "' found! Ignoring abortSkill request.";
+            return;
+        }
+
+        it->second.stopSkill();
+    }
+
 } // namespace armarx::plugins
 
 namespace armarx
@@ -148,31 +330,36 @@ namespace armarx
     }
 
     void
-    SkillProviderComponentPluginUser::addSkill(std::unique_ptr<skills::Skill>&& skill)
+    SkillProviderComponentPluginUser::addSkillFactory(std::unique_ptr<skills::SkillFactory>&& skill)
     {
-        plugin->addSkill(std::move(skill));
+        plugin->addSkillFactory(std::move(skill));
     }
 
     void
-    SkillProviderComponentPluginUser::addSkill(const skills::LambdaSkill::FunT& f,
-                                               const skills::SkillDescription& desc)
+    SkillProviderComponentPluginUser::addSkillFactory(const skills::SkillDescription& desc,
+                                                      const skills::LambdaSkill::FunT& f)
     {
-        plugin->addSkill(f, desc);
+        plugin->addSkillFactory(f, desc);
     }
 
     skills::provider::dto::SkillDescription
-    SkillProviderComponentPluginUser::getSkillDescription(const std::string& name,
-                                                          const Ice::Current& /*unused*/)
+    SkillProviderComponentPluginUser::getSkillDescription(
+        const skills::provider::dto::SkillID& skillId,
+        const Ice::Current& /*unused*/)
     {
-
-        const auto& skillWrapper = plugin->getSkill(name);
-        return skillWrapper.skill->description.toIce();
+        auto id = skills::SkillID::FromIce(skillId, getName());
+        return plugin->getSkillDescription(id)->toIce();
     }
 
     skills::provider::dto::SkillDescriptionMap
     SkillProviderComponentPluginUser::getSkillDescriptions(const Ice::Current& /*unused*/)
     {
-        return plugin->getSkillDescriptions();
+        skills::provider::dto::SkillDescriptionMap ret;
+        for (const auto& [k, v] : plugin->getSkillDescriptions())
+        {
+            ret.insert({k.toProviderIce(), v.toIce()});
+        }
+        return ret;
     }
 
     skills::provider::dto::SkillStatusUpdate
@@ -181,27 +368,23 @@ namespace armarx
         const Ice::Current& /*unused*/)
     {
         auto execId = skills::SkillExecutionId::FromIce(executionId, getName());
-
-        auto& skillWrapper = plugin->getSkill(executionId.skillName);
-
-        const std::shared_lock l(skillWrapper.skillStatusesMutex);
-        if (auto it = skillWrapper.statusUpdates.find(execId);
-            it != skillWrapper.statusUpdates.end())
-        {
-            return it->second.toIceProviderView();
-        }
-        else
+        auto o = plugin->getSkillExecutionStatus(execId);
+        if (o.has_value())
         {
-            skills::SkillStatusUpdate idle;
-            idle.executionId = execId;
-            return idle.toIceProviderView();
+            return o->toProviderIce();
         }
+        return {}; // TODO!!
     }
 
-    skills::provider::dto::SkillStatusUpdateList
+    skills::provider::dto::SkillStatusUpdateMap
     SkillProviderComponentPluginUser::getSkillExecutionStatuses(const Ice::Current& /*unused*/)
     {
-        return plugin->getSkillExecutionStatuses();
+        skills::provider::dto::SkillStatusUpdateMap ret;
+        for (const auto& [k, v] : plugin->getSkillExecutionStatuses())
+        {
+            ret.insert({k.toProviderIce(), v.toProviderIce()});
+        }
+        return ret;
     }
 
     // Please not that this method waits until the skill can be scheduled!
@@ -210,42 +393,38 @@ namespace armarx
         const skills::provider::dto::SkillExecutionRequest& info,
         const Ice::Current& /*unused*/)
     {
-        // The skill will be executed in a seperate thread
-        std::thread execution;
-
-        // setup input args for skill execution
-        skills::SkillParameterization usedParameterization;
-        usedParameterization.usedCallbackInterface = info.callbackInterface;
-        usedParameterization.usedInputParams = aron::data::Dict::FromAronDictDTO(info.params);
-
-        skills::provider::dto::SkillStatusUpdate ret;
-        {
-            const std::string skillName = info.skillName;
-            auto& wrapper = plugin->getSkill(skillName);
+        auto exec = skills::SkillExecutionRequest::FromIce(info);
+        auto up = this->plugin->executeSkill(exec);
+        return up.toProviderIce();
+    }
 
-            // async start execution. But we wait for the execution to finish at the end of this method
-            execution = std::thread(
-                [&ret, &wrapper, &info, &usedParameterization]()
-                {
-                    // execute waits until the previous execution finishes.
-                    auto x = wrapper.setupAndExecuteSkill(info.executorName, usedParameterization);
-                    ret = x.toIceProviderView();
-                });
-        } // 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
+    skills::provider::dto::SkillExecutionID
+    SkillProviderComponentPluginUser::executeSkillAsync(
+        const skills::provider::dto::SkillExecutionRequest& info,
+        const Ice::Current& current /*unused*/)
+    {
+        auto exec = skills::SkillExecutionRequest::FromIce(info);
+        auto id = this->plugin->executeSkillAsync(exec);
+        return id.toProviderIce();
+    }
 
-        if (execution.joinable())
-        {
-            execution.join();
-        }
-        return ret;
+    void
+    SkillProviderComponentPluginUser::addSkillParameters(
+        const skills::provider::dto::SkillExecutionID& id,
+        const aron::data::dto::DictPtr& input,
+        const Ice::Current& current /*unused*/)
+    {
+        auto exec = skills::SkillExecutionId::FromIce(id, getName());
+        auto prep = armarx::aron::data::Dict::FromAronDictDTO(input);
+        this->plugin->addSkillParameters(exec, prep);
     }
 
     void
-    SkillProviderComponentPluginUser::abortSkill(const std::string& skillName,
+    SkillProviderComponentPluginUser::abortSkill(const skills::provider::dto::SkillExecutionID& id,
                                                  const Ice::Current& /*unused*/)
     {
-        auto& wrapper = plugin->getSkill(skillName);
-        wrapper.skill->notifySkillToStopASAP();
+        auto exec = skills::SkillExecutionId::FromIce(id, getName());
+        this->plugin->abortSkill(exec);
     }
 
     const std::experimental::observer_ptr<plugins::SkillProviderComponentPlugin>&
diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
index f4d3489fe9c9f235e9ad94a4d73d028b57a4d6e6..881b813c2f161a5593ae0ba0b90a30fe8be5d136 100644
--- a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h
@@ -15,10 +15,14 @@
 #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
 
 // Include all types of skills
+#include <RobotAPI/libraries/skills/core/Skill.h>
+#include <RobotAPI/libraries/skills/core/SkillExecutionRequest.h>
+#include <RobotAPI/libraries/skills/core/SkillPreparationInput.h>
+
 #include "LambdaSkill.h"
 #include "PeriodicSkill.h"
 #include "PeriodicSpecializedSkill.h"
-#include "Skill.h"
+#include "SkillFactory.h"
 #include "SpecializedSkill.h"
 
 // Helper wrapper for execution
@@ -45,35 +49,51 @@ namespace armarx::plugins
 
         void preOnDisconnectComponent() override;
 
-        void addSkill(const skills::LambdaSkill::FunT&, const skills::SkillDescription&);
-        void addSkill(std::unique_ptr<skills::Skill>&&);
+        void addSkillFactory(const skills::LambdaSkill::FunT&, const skills::SkillDescription&);
+        void addSkillFactory(std::unique_ptr<skills::SkillFactory>&&);
 
         template <typename T, typename... Args>
-        T*
-        addSkill(Args&&... args)
-        {
-            static_assert(std::is_base_of<skills::Skill, T>::value,
-                          "T must be derived from skills::Skill!");
 
-            auto skill = std::make_unique<T>(std::forward<Args>(args)...);
-            auto* skillPtr = skill.get();
-            addSkill(std::move(skill));
-            return static_cast<T*>(skillPtr);
+        requires skills::isSkillFactory<T> T*
+        addSkillFactory(const skills::SkillID& id, Args&&... args)
+        {
+            auto fac = std::make_unique<T>(id, std::forward<Args>(args)...);
+            auto* facPtr = fac.get();
+            addSkillFactory(std::move(fac));
+            return static_cast<T*>(facPtr);
         }
 
-        skills::provider::dto::SkillStatusUpdateList getSkillExecutionStatuses() const;
-        skills::provider::dto::SkillDescriptionMap getSkillDescriptions() const;
+        // Ice forwards
+        std::optional<skills::SkillStatusUpdate>
+        getSkillExecutionStatus(const skills::SkillExecutionId&) const;
+        std::map<skills::SkillExecutionId, skills::SkillStatusUpdate>
+        getSkillExecutionStatuses() const;
+
+        std::optional<skills::SkillDescription> getSkillDescription(const skills::SkillID&) const;
+        std::map<skills::SkillID, skills::SkillDescription> getSkillDescriptions() const;
+
+        skills::SkillStatusUpdate executeSkill(const skills::SkillExecutionRequest& executionInfo);
+
+        skills::SkillExecutionId
+        executeSkillAsync(const skills::SkillExecutionRequest& executionInfo);
+
+        void addSkillParameters(const skills::SkillExecutionId& id,
+                                const armarx::aron::data::DictPtr& params);
+
+        void abortSkill(const skills::SkillExecutionId& execId);
 
     private:
-        skills::detail::SkillImplementationWrapper& getSkill(const std::string& name);
+        skills::SkillFactory* getSkillFactory(const armarx::skills::SkillID& name);
 
         skills::manager::dti::SkillManagerInterfacePrx manager;
         skills::provider::dti::SkillProviderInterfacePrx myPrx;
 
-        mutable std::mutex skillImplementationsMapMutex;
+        mutable std::mutex skillFactoriesMutex;
+        std::map<skills::SkillID, std::unique_ptr<skills::SkillFactory>> skillFactories;
 
-        bool connected = false;
-        std::map<std::string, skills::detail::SkillImplementationWrapper> skillImplementations;
+        mutable std::mutex skillExecutionsMutex;
+        std::map<skills::SkillExecutionId, skills::detail::SkillImplementationWrapper>
+            skillExecutions;
 
         friend class armarx::SkillProviderComponentPluginUser;
     };
@@ -88,35 +108,50 @@ namespace armarx
     public:
         SkillProviderComponentPluginUser();
 
+        // Ice Implementations
         skills::provider::dto::SkillDescription
-        getSkillDescription(const std::string&,
+        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
         getSkillExecutionStatus(const skills::provider::dto::SkillExecutionID& executionId,
                                 const Ice::Current& current = Ice::Current()) override;
-        skills::provider::dto::SkillStatusUpdateList
+
+        skills::provider::dto::SkillStatusUpdateMap
         getSkillExecutionStatuses(const Ice::Current& current = Ice::Current()) override;
 
         skills::provider::dto::SkillStatusUpdate
         executeSkill(const skills::provider::dto::SkillExecutionRequest& executionInfo,
                      const Ice::Current& current = Ice::Current()) override;
-        void abortSkill(const std::string& name,
+
+        skills::provider::dto::SkillExecutionID
+        executeSkillAsync(const skills::provider::dto::SkillExecutionRequest& executionInfo,
+                          const Ice::Current& current = Ice::Current()) override;
+
+        void addSkillParameters(const skills::provider::dto::SkillExecutionID& executionId,
+                                const armarx::aron::data::dto::DictPtr& input,
+                                const Ice::Current& current = Ice::Current()) override;
+
+        void abortSkill(const skills::provider::dto::SkillExecutionID& skill,
                         const Ice::Current& current = Ice::Current()) override;
 
+        // Plugin
         const std::experimental::observer_ptr<plugins::SkillProviderComponentPlugin>&
         getSkillProviderPlugin() const;
 
     protected:
-        void addSkill(const skills::LambdaSkill::FunT&, const skills::SkillDescription&);
-        void addSkill(std::unique_ptr<skills::Skill>&&);
+        // utility
+        void addSkillFactory(const skills::SkillDescription&, const skills::LambdaSkill::FunT&);
+        void addSkillFactory(std::unique_ptr<skills::SkillFactory>&&);
 
         template <typename T, typename... Args>
         T*
-        addSkill(Args&&... args)
+        addSkillFactory(Args&&... args)
         {
-            return plugin->addSkill<T>(std::forward<Args>(args)...);
+            return plugin->addSkillFactory<T>(std::forward<Args>(args)...);
         }
 
     private:
diff --git a/source/RobotAPI/libraries/skills/core/SkillProxy.cpp b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
similarity index 94%
rename from source/RobotAPI/libraries/skills/core/SkillProxy.cpp
rename to source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
index be2aa65cb30d2c385c4977bf1dea98c7d3a0a4ea..0c28fb5a62db877960cd9f3d3e3e8ebad478a12e 100644
--- a/source/RobotAPI/libraries/skills/core/SkillProxy.cpp
+++ b/source/RobotAPI/libraries/skills/provider/SkillProxy.cpp
@@ -20,7 +20,7 @@ namespace armarx
         SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
                                const std::string& skillProviderName,
                                const SkillDescription& skillDesc) :
-            manager(manager), skillId(skillProviderName, skillDesc.skillName)
+            manager(manager), skillId(skillProviderName, skillDesc.skillId.skillName)
         {
         }
 
@@ -31,7 +31,7 @@ namespace armarx
             skills::manager::dto::SkillExecutionRequest req;
             req.executorName = executorName;
             req.params = params->toAronDictDTO();
-            req.skillId = skillId.toIce();
+            req.skillId = skillId.toManagerIce();
 
             auto terminatingUpdate = manager->executeSkill(req);
             return TerminatedSkillStatusUpdate::FromIce(terminatingUpdate);
@@ -44,7 +44,7 @@ namespace armarx
             skills::manager::dto::SkillExecutionRequest req;
             req.executorName = executorName;
             req.params = params->toAronDictDTO();
-            req.skillId = skillId.toIce();
+            req.skillId = skillId.toManagerIce();
 
             auto future = manager->begin_executeSkill(req);
             return future;
@@ -55,7 +55,7 @@ namespace armarx
         {
             // TODO: This will be used in the future, do not remove it!
             (void)executorName;
-            manager->abortSkill(skillId.providerName, skillId.skillName);
+            //manager->abortSkill();
         }
 
         aron::data::DictPtr
diff --git a/source/RobotAPI/libraries/skills/core/SkillProxy.h b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
similarity index 97%
rename from source/RobotAPI/libraries/skills/core/SkillProxy.h
rename to source/RobotAPI/libraries/skills/provider/SkillProxy.h
index c9ea3f09f8eb8f9e57b23a09226d8d1903ab2644..a77c8603742c4ffc1957f6e9278f09211db6307c 100644
--- a/source/RobotAPI/libraries/skills/core/SkillProxy.h
+++ b/source/RobotAPI/libraries/skills/provider/SkillProxy.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Skill.h"
+#include <RobotAPI/libraries/skills/core/Skill.h>
 
 namespace armarx
 {
diff --git a/source/RobotAPI/libraries/skills/core/SpecializedSkill.cpp b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.cpp
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/SpecializedSkill.cpp
rename to source/RobotAPI/libraries/skills/provider/SpecializedSkill.cpp
diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
new file mode 100644
index 0000000000000000000000000000000000000000..c56953e46b0a28744a189d520c982d2ad8316775
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
+#include <RobotAPI/libraries/skills/core/Skill.h>
+
+// Debug
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
+
+namespace armarx
+{
+    namespace skills
+    {
+        template <class AronT>
+        class SpecializedSkill : public Skill
+        {
+        public:
+            using ParamType = AronT;
+
+            struct SpecializedMainInput
+            {
+                std::string executorName;
+                AronT params;
+                CallbackT callback;
+            };
+
+            using Skill::Skill;
+            virtual ~SpecializedSkill() = default;
+
+            /// returns the accepted type of the skill
+            static armarx::aron::type::ObjectPtr
+            GetAcceptedType()
+            {
+                return AronT::ToAronType();
+            }
+
+
+        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};
+            }
+        };
+    } // 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 32f8358c25f19a17aab365d7bc080ece79d90041..bbe71e6ae1e3e4c237ae1e553425b576ccafdc88 100644
--- a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
+++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp
@@ -5,57 +5,83 @@ namespace armarx
     namespace skills::detail
     {
         SkillImplementationWrapper::SkillImplementationWrapper(
-            std::unique_ptr<skills::Skill>&& skill) :
-            skill(std::move(skill))
+            const skills::SkillFactory* fac,
+            const skills::SkillExecutionId& execId,
+            const skills::SkillParameterization& param) :
+            factory(fac), statusUpdate(execId, param)
         {
-            ARMARX_CHECK_NOT_NULL(this->skill);
+            ARMARX_CHECK_NOT_NULL(this->factory);
         }
 
-        TerminatedSkillStatusUpdate
-        SkillImplementationWrapper::setupAndExecuteSkill(
-            const std::string& executorName,
-            const skills::SkillParameterization parameterization)
+        // ask a skill to stop
+        void
+        SkillImplementationWrapper::stopSkill()
         {
-            const std::string skillName = skill->description.skillName;
-            ARMARX_INFO_S << "Executing skill: " << skillName;
+            if (this->skill == nullptr)
+            {
+                // skill has not started yet.
+                return;
+            }
 
-            // we can safely assume that no two executions have the same timestamp
-            const skills::SkillExecutionId executionId = {
-                skill->getSkillId(), executorName, armarx::core::time::DateTime::Now()};
+            this->skill->notifySkillToStopASAP();
+        }
 
-            // set params and setup variables
+        void
+        SkillImplementationWrapper::addSkillParameters(const aron::data::DictPtr& i)
+        {
+            if (this->skill == nullptr)
             {
-                std::unique_lock l(skillStatusesMutex);
-                statusUpdates[executionId] =
-                    SkillStatusUpdate({{executionId, parameterization}, SkillStatus::Scheduled});
+                // skill has not started yet
+                return;
             }
 
-            // reset execution params. This func is also used to clean up once this method returns
-            auto tidyUpStatusUpdates = [&]()
-            {
-                std::unique_lock l2(skillStatusesMutex);
-                statusUpdates.erase(executionId);
-            };
+            this->skill->addParameters(i);
+        }
+
+        TerminatedSkillStatusUpdate
+        SkillImplementationWrapper::executeSkill()
+        {
+            // -------------------------------------------------------------------------------------
+            // sanity check
+            // -------------------------------------------------------------------------------------
+            ARMARX_CHECK(!has_been_called)
+                << "A SKILL HAS ALREADY BEEN CALLED. THIS SHOULD NOT HAPPEN!!";
+
+            has_been_called = true;
+
+            ARMARX_CHECK(this->skill == nullptr)
+                << "A SKILL HAS ALREADY BEEN CONSTRUCTED. THIS SHOULD NOT HAPPEN!!";
+
+
+            // -------------------------------------------------------------------------------------
+            // setup basic vars and lambdas
+            // -------------------------------------------------------------------------------------
+            // actually we should lock... however this is only read access and the members are const throughout the execution...
+            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 executorName = statusUpdate.executionId.executorName;
+
+            ARMARX_INFO_S << "Executing skill: " << skillName;
 
-            const auto& aron_params = parameterization.usedInputParams;
             auto updateStatus =
                 [&](const SkillStatus status, const aron::data::DictPtr& data = nullptr)
             {
                 std::unique_lock l(skillStatusesMutex);
-                auto& statusUpdate = statusUpdates[executionId];
                 statusUpdate.status = status;
                 statusUpdate.data = data;
+                statusUpdate.usedParameterization.parameterization = skill->parameters;
 
-                auto& callbackInterface = statusUpdate.usedParameterization.usedCallbackInterface;
-
-                if (callbackInterface)
+                if (callback_interface)
                 {
-                    callbackInterface->updateStatusForSkill(statusUpdate.toIceProviderView(),
-                                                            skill->getSkillId().providerName);
+                    skills::provider::dto::ProviderID pid({providerName});
+                    callback_interface->updateStatusForSkill(statusUpdate.toProviderIce(), pid);
                 }
             };
 
-            auto createErrorMessage = [](const std::string& message)
+            auto createErrorMessageData = [](const std::string& message)
             {
                 auto obj = aron::make_dict();
                 auto m = aron::make_string(message, aron::Path({"errormessage"}));
@@ -63,165 +89,131 @@ namespace armarx
                 return obj;
             };
 
-            // Check params
-            if (skill->description.acceptedType && not(aron_params))
             {
-                std::string message = "SkillError 001: The Skill '" + skillName +
-                                      "' requires a type but params are NULL.";
-                ARMARX_ERROR_S << message;
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
+                std::unique_lock l(skillStatusesMutex);
+
+                // ---------------------------------------------------------------------------------
+                // check times
+                // ---------------------------------------------------------------------------------
+                if ((armarx::core::time::DateTime::Now() -
+                     statusUpdate.executionId.executionStartedTime) >
+                    armarx::core::time::Duration::Seconds(1))
+                {
+                    ARMARX_WARNING_S << "SkillError 001: For some reason the skill '"
+                                     << skillId.toString()
+                                     << "' has been scheduled > 1s ago. The execution should start "
+                                        "much faster! Continue, but this is bad behavior..";
+                }
             }
 
-            if (skill->description.acceptedType && aron_params &&
-                not(aron_params->fullfillsType(skill->description.acceptedType)))
+            // -------------------------------------------------------------------------------------
+            // construct skill
+            // -------------------------------------------------------------------------------------
+            updateStatus(SkillStatus::Constructing);
+            this->skill = this->factory->createSkill();
+            this->skill->executorName = (executorName);
+            this->skill->callback = [&](const SkillStatus s, const armarx::aron::data::DictPtr& d)
+            { updateStatus(s, d); };
+
+
+            auto makeTerminationResult = [&](const std::string& message)
+            {
+                updateStatus(SkillStatus::Failed, createErrorMessageData(message));
+
+                std::unique_lock l(skillStatusesMutex);
+                auto terminated = TerminatedSkillStatusUpdate(statusUpdate.executionId,
+                                                              statusUpdate.usedParameterization);
+                terminated.data = statusUpdate.data;
+                terminated.status = TerminatedSkillStatus::Failed;
+                return terminated;
+            };
+
+            // -------------------------------------------------------------------------------------
+            // 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;
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
+                return makeTerminationResult(message);
             }
 
-            // Check if skill is available with the given parameterization
-            try
-            {
-                if (not skill->isSkillAvailable(
-                        Skill::InitInput{.executorName = executorName, .params = aron_params}))
-                {
-                    std::string message =
-                        "SkillError 101: The Skill '" + skillName + "' is not available.";
-                    ARMARX_WARNING << message;
-                    tidyUpStatusUpdates();
-                    return TerminatedSkillStatusUpdate(
-                        {{executionId, parameterization, createErrorMessage(message)},
-                         TerminatedSkillStatus::Failed});
-                }
-            }
 
-            catch (const std::exception& ex)
+            auto exitAndMakeTerminationResult = [&](const std::string& message)
             {
-                std::string message =
-                    "SkillError 101e: An error occured during the check whether skill '" +
-                    skillName + "' is available. The error was: " + GetHandledExceptionString();
-                ARMARX_ERROR_S << message;
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
-            }
-
-            // set scheduled
-            updateStatus(SkillStatus::Scheduled);
+                skill->exitSkill(); // try to exit skill. Ignore return value
+                return makeTerminationResult(message);
+            };
 
-            // reset skill and perhaps wait for dependencies
+            // -------------------------------------------------------------------------------------
+            // Init skill
+            // -------------------------------------------------------------------------------------
             try
             {
-                skill->resetSkill();
+                updateStatus(SkillStatus::Initializing);
+                Skill::InitResult initRet = skill->initSkill();
+                if (initRet.status != TerminatedSkillStatus::Succeeded)
+                {
+                    std::string message = "SkillError 101: The initialization of skill '" +
+                                          skillName + "' did not succeed.";
+                    return exitAndMakeTerminationResult(message);
+                }
             }
 
             catch (const std::exception& ex)
             {
                 std::string message =
-                    "SkillError 201e: An error occured during the reset of skill '" + skillName +
-                    "'. The error was: " + GetHandledExceptionString();
+                    "SkillError 101e: An error occured during the initialization of skill '" +
+                    skillName + "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-
-                updateStatus(SkillStatus::Failed);
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
+                return exitAndMakeTerminationResult(message);
             }
 
+            // -------------------------------------------------------------------------------------
+            // Prepare skill
+            // -------------------------------------------------------------------------------------
             try
             {
-                skill->waitForDependenciesOfSkill();
+                updateStatus(SkillStatus::Preparing);
+
+                // set initial parameters that were attached to the execution request
+                skill->addParameters(initial_aron_params);
+                while (not skill->skillPreparationFinished())
+                {
+                    // wait...
+                    skill->prepareSkill();
+                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
+                }
             }
 
             catch (const std::exception& ex)
             {
-                std::string message = "SkillError 301e: An error occured during waiting for skill "
+                std::string message = "SkillError 201e: An error occured during waiting for skill "
                                       "dependencies of skill '" +
                                       skillName +
                                       "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-
-                updateStatus(SkillStatus::Failed);
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
+                return exitAndMakeTerminationResult(message);
             }
 
             // execute. If the skill fails for some reason, from this point it will always execute its exit function.
             updateStatus(SkillStatus::Running);
 
-
-            try
-            {
-                Skill::InitResult initRet = skill->initSkill({executorName, aron_params});
-                if (initRet.status != TerminatedSkillStatus::Succeeded)
-                {
-                    std::string message = "SkillError 401: The initialization of skill '" +
-                                          skillName + "' did not succeed.";
-                    skill->exitSkill(
-                        {executorName, aron_params}); // try to exit skill. Ignore return value
-
-                    updateStatus(skills::toSkillStatus(initRet.status));
-                    tidyUpStatusUpdates();
-                    return TerminatedSkillStatusUpdate(
-                        {{executionId, parameterization, createErrorMessage(message)},
-                         initRet.status});
-                }
-            }
-
-            catch (const std::exception& ex)
-            {
-                std::string message =
-                    "SkillError 401e: An error occured during the initialization of skill '" +
-                    skillName + "'. The error was: " + GetHandledExceptionString();
-                ARMARX_ERROR_S << message;
-                skill->exitSkill(
-                    {executorName, aron_params}); // try to exit skill. Ignore return value
-
-                updateStatus(SkillStatus::Failed);
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
-            }
-
             // Init succeeded!
 
 
             Skill::MainResult mainRet;
             try
             {
-                mainRet = skill->mainOfSkill({executorName,
-                                              aron_params,
-                                              [&updateStatus](const aron::data::DictPtr& update)
-                                              {
-                                                  // during execution the statusUpdate.status is always RUNNING
-                                                  updateStatus(SkillStatus::Running, update);
-                                              }});
+                mainRet = skill->mainOfSkill();
                 if (mainRet.status != TerminatedSkillStatus::Succeeded)
                 {
                     std::string message = "SkillError 501: The main method of skill '" + skillName +
                                           "' did not succeed.";
-                    skill->exitSkill(
-                        {executorName, aron_params}); // try to exit skill. Ignore return value
-
-                    updateStatus(skills::toSkillStatus(mainRet.status));
-                    tidyUpStatusUpdates();
-                    return TerminatedSkillStatusUpdate(
-                        {{executionId, parameterization, createErrorMessage(message)},
-                         mainRet.status});
+                    return exitAndMakeTerminationResult(message);
                 }
             }
 
@@ -231,33 +223,19 @@ namespace armarx
                     "SkillError 501e: An error occured during the main method of skill '" +
                     skillName + "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-                skill->exitSkill(
-                    {executorName, aron_params}); // try to exit skill. Ignore return value
-
-                updateStatus(SkillStatus::Failed);
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
+                return exitAndMakeTerminationResult(message);
             }
 
             // Main succeeded!
 
             try
             {
-                Skill::ExitResult exitRet = skill->exitSkill({executorName, aron_params});
+                Skill::ExitResult exitRet = skill->exitSkill();
                 if (exitRet.status != TerminatedSkillStatus::Succeeded)
                 {
                     std::string message = "SkillError 601: The exit method of skill '" + skillName +
                                           "' did not succeed.";
-                    skill->exitSkill(
-                        {executorName, aron_params}); // try to exit skill. Ignore return value
-
-                    updateStatus(skills::toSkillStatus(exitRet.status));
-                    tidyUpStatusUpdates();
-                    return TerminatedSkillStatusUpdate(
-                        {{executionId, parameterization, createErrorMessage(message)},
-                         exitRet.status});
+                    return makeTerminationResult(message);
                 }
             }
 
@@ -267,12 +245,7 @@ namespace armarx
                     "SkillError 601e: An error occured during the exit method of skill '" +
                     skillName + "'. The error was: " + GetHandledExceptionString();
                 ARMARX_ERROR_S << message;
-
-                updateStatus(SkillStatus::Failed);
-                tidyUpStatusUpdates();
-                return TerminatedSkillStatusUpdate(
-                    {{executionId, parameterization, createErrorMessage(message)},
-                     TerminatedSkillStatus::Failed});
+                return makeTerminationResult(message);
             }
 
             // Exit succeeded!
@@ -281,12 +254,14 @@ namespace armarx
             // All succeeded!
             updateStatus(SkillStatus::Succeeded);
 
-            // Tidy up
-            tidyUpStatusUpdates();
-
             // return result of main method
-            return {{executionId, parameterization, mainRet.data},
-                    TerminatedSkillStatus::Succeeded};
+            std::unique_lock l(skillStatusesMutex);
+            TerminatedSkillStatusUpdate ret(statusUpdate.executionId,
+                                            statusUpdate.usedParameterization);
+            ret.data = mainRet.data;
+            ret.status = TerminatedSkillStatus::Succeeded;
+
+            return ret;
         }
     } // namespace skills::detail
 } // namespace armarx
diff --git a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
index 32fafd3537724d96fde728e1ce3ddba5d2b06ad2..8ae7dcf7709f2f7293346eb6b928e7e00709b619 100644
--- a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
+++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h
@@ -3,10 +3,11 @@
 #include <shared_mutex>
 
 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
-
-#include "../Skill.h"
-#include "../SkillDescription.h"
-#include "../SkillStatusUpdate.h"
+#include <RobotAPI/libraries/skills/core/Skill.h>
+#include <RobotAPI/libraries/skills/core/SkillDescription.h>
+#include <RobotAPI/libraries/skills/core/SkillPreparationInput.h>
+#include <RobotAPI/libraries/skills/core/SkillStatusUpdate.h>
+#include <RobotAPI/libraries/skills/provider/SkillFactory.h>
 
 namespace armarx
 {
@@ -16,23 +17,32 @@ namespace armarx
         {
             class SkillImplementationWrapper
             {
-            public:
-                // fixed values. Do not change after skill instantiation
-                const std::unique_ptr<Skill> skill;
+            private:
+                const skills::SkillFactory* factory;
+
+                std::unique_ptr<Skill> skill;
+
+                std::atomic_bool has_been_called = false; // sanitize
 
+            public:
                 // Current execution statuses. Changes during execution
                 // The status also holds the used parameterization
-                mutable std::shared_mutex skillStatusesMutex;
-                std::map<skills::SkillExecutionId, SkillStatusUpdate> statusUpdates;
+                mutable std::mutex skillStatusesMutex;
+                SkillStatusUpdate statusUpdate;
 
                 // ctor
-                SkillImplementationWrapper(std::unique_ptr<skills::Skill>&& skill);
+                SkillImplementationWrapper(const skills::SkillFactory* fac,
+                                           const skills::SkillExecutionId&,
+                                           const skills::SkillParameterization&);
 
                 // execute a skill. The parameterization is copied. T
                 // the return type additionally contains the input configuration (similar to the status updates used in callbacks)
-                TerminatedSkillStatusUpdate
-                setupAndExecuteSkill(const std::string& executorName,
-                                     const skills::SkillParameterization);
+                TerminatedSkillStatusUpdate executeSkill();
+
+                // ask a skill to stop
+                void stopSkill();
+
+                void addSkillParameters(const aron::data::DictPtr& i);
             };
         } // namespace detail
     } // namespace skills
diff --git a/source/RobotAPI/libraries/skills/core/mixins/All.h b/source/RobotAPI/libraries/skills/provider/mixins/All.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/All.h
rename to source/RobotAPI/libraries/skills/provider/mixins/All.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/ArvizSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/ArvizSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/ArvizSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/ArvizSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/GraspReadingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/GraspReadingSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/GraspReadingSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/GraspReadingSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/MNSSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/MNSSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/MNSSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/MNSSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/MemoryReadingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/MemoryReadingSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/MemoryReadingSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/MemoryReadingSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/ObjectReadingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/ObjectReadingSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/ObjectReadingSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/ObjectReadingSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/ObjectWritingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/ObjectWritingSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/ObjectWritingSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/ObjectWritingSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/RobotReadingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/RobotReadingSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/RobotReadingSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/RobotReadingSkillMixin.h
diff --git a/source/RobotAPI/libraries/skills/core/mixins/RobotWritingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/RobotWritingSkillMixin.h
similarity index 100%
rename from source/RobotAPI/libraries/skills/core/mixins/RobotWritingSkillMixin.h
rename to source/RobotAPI/libraries/skills/provider/mixins/RobotWritingSkillMixin.h