diff --git a/scenarios/ArMemExample/config/ExampleMemory.cfg b/scenarios/ArMemExample/config/ExampleMemory.cfg
index 7989108bc28741f5c638fe53de5608ecaf8c7612..251382f2af086afccf73924421ea31a2aad01017 100644
--- a/scenarios/ArMemExample/config/ExampleMemory.cfg
+++ b/scenarios/ArMemExample/config/ExampleMemory.cfg
@@ -143,21 +143,12 @@ ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener = MemoryUpdates
 # ArmarX.ExampleMemory.mem.MemoryName = Example
 
 
-# ArmarX.ExampleMemory.mem.ltm..buffer.storeFreq:  Frequency to store the buffer to the LTM in Hz.
+# ArmarX.ExampleMemory.mem.ltm.configuration:  
 #  Attributes:
-#  - Default:            10
+#  - Default:            {}
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ExampleMemory.mem.ltm..buffer.storeFreq = 10
-
-
-# ArmarX.ExampleMemory.mem.ltm.depthImageExtractor.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.depthImageExtractor.Enabled = true
+# ArmarX.ExampleMemory.mem.ltm.configuration = {}
 
 
 # ArmarX.ExampleMemory.mem.ltm.enabled:  
@@ -169,100 +160,6 @@ ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener = MemoryUpdates
 # ArmarX.ExampleMemory.mem.ltm.enabled = false
 
 
-# ArmarX.ExampleMemory.mem.ltm.exrConverter.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.exrConverter.Enabled = true
-
-
-# ArmarX.ExampleMemory.mem.ltm.imageExtractor.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.imageExtractor.Enabled = true
-
-
-# ArmarX.ExampleMemory.mem.ltm.memFreqFilter.Enabled:  
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.memFreqFilter.Enabled = false
-
-
-# ArmarX.ExampleMemory.mem.ltm.memFreqFilter.WaitingTime:  Waiting time in MS after each LTM update.
-#  Attributes:
-#  - Default:            -1
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ExampleMemory.mem.ltm.memFreqFilter.WaitingTime = -1
-
-
-# ArmarX.ExampleMemory.mem.ltm.pngConverter.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.pngConverter.Enabled = true
-
-
-# ArmarX.ExampleMemory.mem.ltm.sizeToCompressDataInMegaBytes:  The size in MB to compress away the current export. Exports are numbered (lower number means newer).
-#  Attributes:
-#  - Default:            1024
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ExampleMemory.mem.ltm.sizeToCompressDataInMegaBytes = 1024
-
-
-# ArmarX.ExampleMemory.mem.ltm.snapEqFilter.Enabled:  
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.snapEqFilter.Enabled = false
-
-
-# ArmarX.ExampleMemory.mem.ltm.snapEqFilter.MaxWaitingTime:  Max Waiting time in MS after each Entity update.
-#  Attributes:
-#  - Default:            -1
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ExampleMemory.mem.ltm.snapEqFilter.MaxWaitingTime = -1
-
-
-# ArmarX.ExampleMemory.mem.ltm.snapFreqFilter.Enabled:  
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ExampleMemory.mem.ltm.snapFreqFilter.Enabled = false
-
-
-# ArmarX.ExampleMemory.mem.ltm.snapFreqFilter.WaitingTime:  Waiting time in MS after each Entity update.
-#  Attributes:
-#  - Default:            -1
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ExampleMemory.mem.ltm.snapFreqFilter.WaitingTime = -1
-
-
-# ArmarX.ExampleMemory.mem.ltm.storagepath:  The path to the memory storage (the memory will be stored in a seperate subfolder).
-#  Attributes:
-#  - Default:            Default value not mapped.
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ExampleMemory.mem.ltm.storagepath = Default value not mapped.
-
-
 # ArmarX.ExampleMemory.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
 # Set to false to use this memory as a stand-alone.
 #  Attributes:
diff --git a/scenarios/SkillProviderTest/config/SkillsMemory.cfg b/scenarios/SkillProviderTest/config/SkillsMemory.cfg
index 711047a4029175550111268cf857a613c2dd48b2..8b2bf04855a21e5a8ca955da89ba3a309460241e 100644
--- a/scenarios/SkillProviderTest/config/SkillsMemory.cfg
+++ b/scenarios/SkillProviderTest/config/SkillsMemory.cfg
@@ -167,21 +167,12 @@
 # ArmarX.SkillMemory.mem.MemoryName = Skill
 
 
-# ArmarX.SkillMemory.mem.ltm..buffer.storeFreq:  Frequency to store the buffer to the LTM in Hz.
+# ArmarX.SkillMemory.mem.ltm.configuration:  
 #  Attributes:
-#  - Default:            10
+#  - Default:            {}
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.SkillMemory.mem.ltm..buffer.storeFreq = 10
-
-
-# ArmarX.SkillMemory.mem.ltm.depthImageExtractor.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.depthImageExtractor.Enabled = true
+# ArmarX.SkillMemory.mem.ltm.configuration = {}
 
 
 # ArmarX.SkillMemory.mem.ltm.enabled:  
@@ -193,100 +184,6 @@
 # ArmarX.SkillMemory.mem.ltm.enabled = false
 
 
-# ArmarX.SkillMemory.mem.ltm.exrConverter.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.exrConverter.Enabled = true
-
-
-# ArmarX.SkillMemory.mem.ltm.imageExtractor.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.imageExtractor.Enabled = true
-
-
-# ArmarX.SkillMemory.mem.ltm.memFreqFilter.Enabled:  
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.memFreqFilter.Enabled = false
-
-
-# ArmarX.SkillMemory.mem.ltm.memFreqFilter.WaitingTime:  Waiting time in MS after each LTM update.
-#  Attributes:
-#  - Default:            -1
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.SkillMemory.mem.ltm.memFreqFilter.WaitingTime = -1
-
-
-# ArmarX.SkillMemory.mem.ltm.pngConverter.Enabled:  
-#  Attributes:
-#  - Default:            true
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.pngConverter.Enabled = true
-
-
-# ArmarX.SkillMemory.mem.ltm.sizeToCompressDataInMegaBytes:  The size in MB to compress away the current export. Exports are numbered (lower number means newer).
-#  Attributes:
-#  - Default:            1024
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.SkillMemory.mem.ltm.sizeToCompressDataInMegaBytes = 1024
-
-
-# ArmarX.SkillMemory.mem.ltm.snapEqFilter.Enabled:  
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.snapEqFilter.Enabled = false
-
-
-# ArmarX.SkillMemory.mem.ltm.snapEqFilter.MaxWaitingTime:  Max Waiting time in MS after each Entity update.
-#  Attributes:
-#  - Default:            -1
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.SkillMemory.mem.ltm.snapEqFilter.MaxWaitingTime = -1
-
-
-# ArmarX.SkillMemory.mem.ltm.snapFreqFilter.Enabled:  
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.SkillMemory.mem.ltm.snapFreqFilter.Enabled = false
-
-
-# ArmarX.SkillMemory.mem.ltm.snapFreqFilter.WaitingTime:  Waiting time in MS after each Entity update.
-#  Attributes:
-#  - Default:            -1
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.SkillMemory.mem.ltm.snapFreqFilter.WaitingTime = -1
-
-
-# ArmarX.SkillMemory.mem.ltm.storagepath:  The path to the memory storage (the memory will be stored in a seperate subfolder).
-#  Attributes:
-#  - Default:            Default value not mapped.
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.SkillMemory.mem.ltm.storagepath = Default value not mapped.
-
-
 # ArmarX.SkillMemory.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
 # Set to false to use this memory as a stand-alone.
 #  Attributes:
diff --git a/source/RobotAPI/components/ArViz/Client/Elements.cpp b/source/RobotAPI/components/ArViz/Client/Elements.cpp
index f479f4ef5456fc7a88d0f3a0fa87d2e77e9aab66..d97fea3b03d55ddb82a379628197a5f04ffc3d74 100644
--- a/source/RobotAPI/components/ArViz/Client/Elements.cpp
+++ b/source/RobotAPI/components/ArViz/Client/Elements.cpp
@@ -107,9 +107,9 @@ namespace armarx::viz
         float angle = std::acos(naturalDir.dot(dir));
         if (cross.squaredNorm() < 1.0e-12f)
         {
-            // Directions are almost colinear ==> Do no rotation
+            // Directions are almost colinear ==> Angle is either 0 or 180 deg
             cross = Eigen::Vector3f::UnitX();
-            angle = 0.0f;
+            // Keep angle
         }
         Eigen::Vector3f axis = cross.normalized();
         Eigen::Quaternionf ori(Eigen::AngleAxisf(angle, axis));
diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
index 2c93faf7fa4a464909bd6dea214c74022571474f..e52609fa085feac2dc4ef8fc93f68127aef8b040 100644
--- a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
+++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
@@ -275,13 +275,18 @@ namespace armarx
 
     void fillExampleLayer(viz::Layer& layer, double timeInSeconds)
     {
+        for (int i = 0; i < 6; ++i)
         {
-            Eigen::Vector3f pos = Eigen::Vector3f::Zero();
-            pos.z() = +300.0f;
+            Eigen::Vector3f pos = Eigen::Vector3f(-200.0, 200.0, 300);
+            pos.x() +=  -300 * i;
+
+            Eigen::Vector3f normal = Eigen::Vector3f::Zero();
+            normal(i / 2) = (i % 2 == 0 ? 1.0 : -1.0);
 
-            viz::ArrowCircle circle = viz::ArrowCircle("circle")
+            viz::ArrowCircle circle = viz::ArrowCircle("circle " + std::to_string(i))
                                       .position(pos)
                                       .radius(100.0f)
+                                      .normal(normal)
                                       .width(10.0f)
                                       .color(viz::Color::fromRGBA(255, 0, 255));
 
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
index bc50155edc0d42a775c63ade67e35f38e34fd8c5..985ef8171792570e6dad35d7a0abb09d78492006 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
+++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp
@@ -20,6 +20,8 @@ namespace armarx::skills::provider
         default_params.some_float = 5;
         default_params.some_int = 42;
         default_params.some_text = "YOLO";
+        default_params.some_list_of_matrices.push_back(Eigen::Matrix3f::Zero());
+        //default_params.some_matrix = Eigen::Matrix3f::Zero();
 
         return SkillDescription{
             "HelloWorld",
diff --git a/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml b/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml
index 553a93ad0898ddc40d112e097af9c95ca801da55..a2423c560b8548c265af0ae14602b8771fe46218 100644
--- a/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml
+++ b/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <AronTypeDefinition>
     <GenerateTypes>
+        <IntEnum name="HelloWorldInteEnum">
+            <EnumValue key="INT_ENUM_VALUE_0" value="0" />
+            <EnumValue key="INT_ENUM_VALUE_1" value="1" />
+            <EnumValue key="INT_ENUM_VALUE_2" value="2" />
+            <EnumValue key="INT_ENUM_VALUE_3" value="3" />
+            <EnumValue key="INT_ENUM_VALUE_4" value="4" />
+            <EnumValue key="INT_ENUM_VALUE_5" value="5" />
+            <EnumValue key="INT_ENUM_VALUE_6" value="6" />
+            <EnumValue key="INT_ENUM_VALUE_7" value="7" />
+            <EnumValue key="INT_ENUM_VALUE_8" value="8" />
+        </IntEnum>
         <Object name='armarx::skills::Example::HelloWorldAcceptedType'>
             <ObjectChild key='some_int'>
                 <Int />
@@ -11,6 +22,23 @@
             <ObjectChild key='some_text'>
                 <String />
             </ObjectChild>
+
+            <ObjectChild key='some_list_of_matrices'>
+                <List>
+                    <Matrix rows="3" cols="3" type="float32" />
+                </List>
+            </ObjectChild>
+
+            <ObjectChild key='some_dict_of_matrices'>
+                <Dict>
+                    <Matrix rows="3" cols="3" type="float32" />
+                </Dict>
+            </ObjectChild>
+
+            <ObjectChild key='some_matrix'>
+                <Matrix rows="3" cols="3" type="float32" />
+            </ObjectChild>
+
         </Object>
     </GenerateTypes>
 
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt
index 89a90ab482f9916ff11ad149faa1a3fc1b7d483c..b40d5a2fcf9c480a71f0576d049ad0a311813815 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt
@@ -9,15 +9,22 @@ set(SOURCES
     aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
     aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
     aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp
+    aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp
     aronTreeWidget/Data.cpp
+    aronTreeWidget/widgets/CustomWidget.cpp
+    aronTreeWidget/widgets/EditMatrixWidget.cpp
+    aronTreeWidget/widgets/IntEnumWidget.cpp
+    aronTreeWidget/ListDictHelper.cpp
+    aronTreeWidget/widgets/QuaternionWidget.cpp
     aronTreeWidget/AronTreeWidgetItem.cpp
     aronTreeWidget/AronTreeWidgetController.cpp
-    aronTreeWidget/modal/AronTreeWidgetModal.cpp
-    aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModalController.cpp
-    aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModalController.cpp
-    aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModalController.cpp
     aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.cpp
     aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp
+    aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModalController.cpp
+    aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModalController.cpp
+    aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModalController.cpp
+    aronTreeWidget/modal/AronTreeWidgetModal.cpp
+    ColorPalettes.cpp
     SkillManagerMonitorWidgetController.cpp
 )
 
@@ -26,25 +33,29 @@ set(HEADERS
     aronTreeWidget/visitors/AronTreeWidgetConverter.h
     aronTreeWidget/visitors/AronTreeWidgetSetter.h
     aronTreeWidget/visitors/AronTreeWidgetModalCreator.h
+    aronTreeWidget/visitors/AronTreeWidgetContextMenu.h
     aronTreeWidget/Data.h
+    aronTreeWidget/widgets/NDArrayHelper.h
+    aronTreeWidget/widgets/EditMatrixWidget.h
+    aronTreeWidget/widgets/CustomWidget.h
+    aronTreeWidget/widgets/IntEnumWidget.h
+    aronTreeWidget/ListDictHelper.h
+    aronTreeWidget/widgets/QuaternionWidget.h
     aronTreeWidget/AronTreeWidgetItem.h
     aronTreeWidget/AronTreeWidgetController.h
     aronTreeWidget/modal/AronTreeWidgetModal.h
-    aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModalController.h
-    aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModalController.h
-    aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModalController.h
     aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.h
     aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.h
+    aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModalController.h
+    aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModalController.h
+    aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModalController.h
+    ColorPalettes.h
     SkillManagerMonitorWidgetController.h
 )
 
 set(GUI_UIS
     SkillManagerMonitorWidget.ui
-    aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModal.ui
-    aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModal.ui
-    aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModal.ui
     aronTreeWidget/modal/text/AronTreeWidgetTextInputModal.ui
-    aronTreeWidget/modal/dict/AronTreeWidgetDictInputModal.ui
 )
 
 # Add more libraries you depend on here, e.g. ${QT_LIBRARIES}.
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/ColorPalettes.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/ColorPalettes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05cd7a5cc08224561af8df64cf6be2347adb3e37
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/ColorPalettes.cpp
@@ -0,0 +1,32 @@
+#include "ColorPalettes.h"
+
+namespace armarx::gui_color_palette
+{
+    QPalette
+    getErrorPalette()
+    {
+        QPalette errorPalette;
+        errorPalette.setColor(QPalette::Base, Qt::red);
+        return errorPalette;
+    }
+    QPalette
+    getNormalPalette()
+    {
+
+        QPalette normalPalette;
+
+        normalPalette.setColor(QPalette::Base, Qt::white);
+        return normalPalette;
+    }
+
+    QPalette
+    getIndirectErrorPalette()
+    {
+        QPalette indirectErr;
+        static QColor orange = QColor::fromRgb(255, 165, 0);
+        // orange color
+        indirectErr.setColor(QPalette::Base, orange);
+        return indirectErr;
+    }
+
+} // namespace armarx::gui_color_palette
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/ColorPalettes.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/ColorPalettes.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea2c247a9428559de4be7bdb8fc1497c14b1ea00
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/ColorPalettes.h
@@ -0,0 +1,11 @@
+#pragma once
+#include <QPalette>
+
+namespace armarx::gui_color_palette
+{
+    QPalette getNormalPalette();
+
+    QPalette getErrorPalette();
+
+    QPalette getIndirectErrorPalette();
+} // namespace armarx::gui_color_palette
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
index 3aa3984c65aad167af2b49e94ab34130c880c998..1e80202efb18b2aca77e8ba45b87827e362ae233 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui
@@ -6,145 +6,187 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1015</width>
-    <height>498</height>
+    <width>1060</width>
+    <height>657</height>
    </rect>
   </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
   <property name="windowTitle">
    <string>SkillManagerMonitorWidget</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QGroupBox" name="groupBoxActiveSkills">
+  <layout class="QGridLayout" name="gridLayout_3">
+   <item row="0" column="0">
+    <widget class="QSplitter" name="splitter_2">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="title">
-      <string>Active Skills</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_3">
-      <item row="0" column="0">
-       <widget class="QListWidget" name="listWidgetActiveSkills">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QSplitter" name="splitter">
      <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="childrenCollapsible">
+      <bool>false</bool>
      </property>
-     <widget class="QGroupBox" name="groupBoxSkills">
+     <widget class="QGroupBox" name="groupBoxActiveSkills">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
       <property name="title">
-       <string>Manager</string>
+       <string>Active Skills</string>
       </property>
-      <layout class="QGridLayout" name="gridLayout">
-       <item row="2" column="0">
-        <widget class="QLabel" name="label">
-         <property name="text">
-          <string>Update Frequency:</string>
+      <layout class="QGridLayout" name="gridLayout_4">
+       <item row="0" column="0">
+        <widget class="QListWidget" name="listWidgetActiveSkills">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
          </property>
         </widget>
        </item>
-       <item row="3" column="0" colspan="3">
-        <widget class="QTreeWidget" name="treeWidgetSkills">
-         <column>
+      </layout>
+     </widget>
+     <widget class="QSplitter" name="splitter">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <widget class="QGroupBox" name="groupBoxSkills">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="title">
+        <string>Manager</string>
+       </property>
+       <layout class="QGridLayout" name="gridLayout">
+        <item row="2" column="0">
+         <widget class="QLabel" name="label">
           <property name="text">
-           <string>Skill</string>
+           <string>Update Frequency:</string>
           </property>
-         </column>
-         <column>
-          <property name="text">
-           <string>HasType</string>
+         </widget>
+        </item>
+        <item row="3" column="0" colspan="3">
+         <widget class="QTreeWidget" name="treeWidgetSkills">
+          <column>
+           <property name="text">
+            <string>Skill</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>HasType</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>State</string>
+           </property>
+          </column>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QDoubleSpinBox" name="doubleSpinBoxUpdateFreq"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QGroupBox" name="groupBoxSkillDetails">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="title">
+        <string>Skill Details</string>
+       </property>
+       <layout class="QGridLayout" name="gridLayout_2">
+        <item row="1" column="0" colspan="4">
+         <widget class="QTreeWidget" name="treeWidgetSkillDetails">
+          <property name="contextMenuPolicy">
+           <enum>Qt::CustomContextMenu</enum>
+          </property>
+          <property name="editTriggers">
+           <set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
           </property>
-         </column>
-         <column>
+          <column>
+           <property name="text">
+            <string>Key</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>Value</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>Type</string>
+           </property>
+          </column>
+          <column>
+           <property name="text">
+            <string>defaultValue</string>
+           </property>
+          </column>
+         </widget>
+        </item>
+        <item row="6" column="3">
+         <widget class="QPushButton" name="pushButtonExecuteSkill">
           <property name="text">
-           <string>State</string>
+           <string>Request Execution</string>
           </property>
-         </column>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QDoubleSpinBox" name="doubleSpinBoxUpdateFreq"/>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QGroupBox" name="groupBoxSkillDetails">
-      <property name="title">
-       <string>Skill Details</string>
-      </property>
-      <layout class="QGridLayout" name="gridLayout_2">
-       <item row="1" column="0" colspan="4">
-        <widget class="QTreeWidget" name="treeWidgetSkillDetails">
-         <column>
+         </widget>
+        </item>
+        <item row="0" column="0">
+         <widget class="QPushButton" name="pushButtonPaste">
           <property name="text">
-           <string>Key</string>
+           <string>Set from clipboard</string>
           </property>
-         </column>
-         <column>
+         </widget>
+        </item>
+        <item row="6" column="0">
+         <widget class="QPushButton" name="pushButtonStopSkill">
           <property name="text">
-           <string>Value</string>
+           <string>Stop current skill</string>
           </property>
-         </column>
-         <column>
+         </widget>
+        </item>
+        <item row="0" column="3">
+         <widget class="QPushButton" name="pushButtonReset">
           <property name="text">
-           <string>Type</string>
+           <string>Reset args</string>
           </property>
-         </column>
-         <column>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QPushButton" name="pushButtonCopy">
           <property name="text">
-           <string>defaultValue</string>
+           <string>Copy args to clipboard</string>
           </property>
-         </column>
-        </widget>
-       </item>
-       <item row="6" column="3">
-        <widget class="QPushButton" name="pushButtonExecuteSkill">
-         <property name="text">
-          <string>Request Execution</string>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="0">
-        <widget class="QPushButton" name="pushButtonPaste">
-         <property name="text">
-          <string>Set from clipboard</string>
-         </property>
-        </widget>
-       </item>
-       <item row="6" column="0">
-        <widget class="QPushButton" name="pushButtonStopSkill">
-         <property name="text">
-          <string>Stop current skill</string>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="3">
-        <widget class="QPushButton" name="pushButtonReset">
-         <property name="text">
-          <string>Reset args</string>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="1">
-        <widget class="QPushButton" name="pushButtonCopy">
-         <property name="text">
-          <string>Copy args to clipboard</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
+         </widget>
+        </item>
+       </layout>
+      </widget>
      </widget>
     </widget>
    </item>
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
index 27a954593ad99d252410ffec11d086689c1d9e07..edc9eebb6d619dd09de033ac2959b4858d263246 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp
@@ -20,52 +20,57 @@
  *             GNU General Public License
  */
 
+#include "SkillManagerMonitorWidgetController.h"
+
 #include <string>
 
-#include "SkillManagerMonitorWidgetController.h"
+#include <RobotAPI/libraries/skills/provider/Skill.h>
 
-#include "aronTreeWidget/visitors/AronTreeWidgetCreator.h"
 #include "aronTreeWidget/visitors/AronTreeWidgetConverter.h"
+#include "aronTreeWidget/visitors/AronTreeWidgetCreator.h"
 #include "aronTreeWidget/visitors/AronTreeWidgetModalCreator.h"
 
-#include <RobotAPI/libraries/skills/provider/Skill.h>
-
 // modals
 #include "aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.h"
 
 // debug
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
-
-#include <QDoubleSpinBox>
 #include <QClipboard>
+#include <QDoubleSpinBox>
+
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 
 #include "aronTreeWidget/Data.h"
 
 //config
 namespace armarx
 {
-    QPointer<QDialog> SkillManagerMonitorWidgetController::getConfigDialog(QWidget* parent)
+    QPointer<QDialog>
+    SkillManagerMonitorWidgetController::getConfigDialog(QWidget* parent)
     {
         if (!dialog)
         {
             dialog = new SimpleConfigDialog(parent);
-            dialog->addProxyFinder<skills::manager::dti::SkillManagerInterfacePrx>("SkillManager", "", "Skill*");
+            dialog->addProxyFinder<skills::manager::dti::SkillManagerInterfacePrx>(
+                "SkillManager", "", "Skill*");
         }
         return qobject_cast<SimpleConfigDialog*>(dialog);
     }
-    void SkillManagerMonitorWidgetController::configured()
+    void
+    SkillManagerMonitorWidgetController::configured()
     {
         observerName = dialog->getProxyName("SkillManager");
     }
-    void SkillManagerMonitorWidgetController::loadSettings(QSettings* settings)
+    void
+    SkillManagerMonitorWidgetController::loadSettings(QSettings* settings)
     {
         observerName = settings->value("SkillManager", "SkillManager").toString().toStdString();
     }
-    void SkillManagerMonitorWidgetController::saveSettings(QSettings* settings)
+    void
+    SkillManagerMonitorWidgetController::saveSettings(QSettings* settings)
     {
         settings->setValue("SkillManager", QString::fromStdString(observerName));
     }
-}
+} // namespace armarx
 
 // Others
 namespace armarx
@@ -81,29 +86,40 @@ namespace armarx
         widget.doubleSpinBoxUpdateFreq->setSuffix(" Hz");
 
         refreshSkillsResultTimer = new QTimer(this);
-        refreshSkillsResultTimer->setInterval(1000 / 5);  // Keep this stable.
+        refreshSkillsResultTimer->setInterval(1000 / 5); // Keep this stable.
         refreshSkillsResultTimer->start();
 
-        connect(widget.doubleSpinBoxUpdateFreq, &QDoubleSpinBox::editingFinished,
-                this, &SkillManagerMonitorWidgetController::updateTimerFrequency);
-        connect(refreshSkillsResultTimer, &QTimer::timeout,
-                this, &SkillManagerMonitorWidgetController::refreshSkills);
-
-        connect(widget.pushButtonCopy, &QPushButton::clicked,
-                this, &SkillManagerMonitorWidgetController::copyCurrentConfig);
-        connect(widget.pushButtonPaste, &QPushButton::clicked,
-                this, &SkillManagerMonitorWidgetController::pasteCurrentConfig);
-
-        connect(widget.pushButtonExecuteSkill, &QPushButton::clicked,
-                this, &SkillManagerMonitorWidgetController::executeSkill);
-        connect(widget.pushButtonStopSkill, &QPushButton::clicked,
-                this, &SkillManagerMonitorWidgetController::stopSkill);
-
-        connect(widget.treeWidgetSkills, &QTreeWidget::currentItemChanged,
-                this, &SkillManagerMonitorWidgetController::skillSelectionChanged);
-
-        connect(widget.treeWidgetSkillDetails, &QTreeWidget::itemDoubleClicked,
-                this, &SkillManagerMonitorWidgetController::onTreeWidgetItemDoubleClicked);
+        connect(widget.doubleSpinBoxUpdateFreq,
+                &QDoubleSpinBox::editingFinished,
+                this,
+                &SkillManagerMonitorWidgetController::updateTimerFrequency);
+        connect(refreshSkillsResultTimer,
+                &QTimer::timeout,
+                this,
+                &SkillManagerMonitorWidgetController::refreshSkills);
+
+        connect(widget.pushButtonCopy,
+                &QPushButton::clicked,
+                this,
+                &SkillManagerMonitorWidgetController::copyCurrentConfig);
+        connect(widget.pushButtonPaste,
+                &QPushButton::clicked,
+                this,
+                &SkillManagerMonitorWidgetController::pasteCurrentConfig);
+
+        connect(widget.pushButtonExecuteSkill,
+                &QPushButton::clicked,
+                this,
+                &SkillManagerMonitorWidgetController::executeSkill);
+        connect(widget.pushButtonStopSkill,
+                &QPushButton::clicked,
+                this,
+                &SkillManagerMonitorWidgetController::stopSkill);
+
+        connect(widget.treeWidgetSkills,
+                &QTreeWidget::currentItemChanged,
+                this,
+                &SkillManagerMonitorWidgetController::skillSelectionChanged);
     }
 
     SkillManagerMonitorWidgetController::~SkillManagerMonitorWidgetController()
@@ -111,25 +127,38 @@ namespace armarx
 
     }
 
-    void SkillManagerMonitorWidgetController::onInitComponent()
+    void 
+    SkillManagerMonitorWidgetController::reconnectToSkillManager()
+    {
+        if (connected)
+        {
+            getProxy(manager, observerName, 1000);
+        }
+    }
+
+    void 
+    SkillManagerMonitorWidgetController::onInitComponent()
     {
         usingProxy(observerName);
     }
 
 
-    void SkillManagerMonitorWidgetController::onConnectComponent()
+    void
+    SkillManagerMonitorWidgetController::onConnectComponent()
     {
-        getProxy(manager, observerName);
         widget.groupBoxSkills->setTitle(QString::fromStdString(observerName));
-        widget.treeWidgetSkillDetails->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
+        widget.treeWidgetSkillDetails->setEditTriggers(
+            QAbstractItemView::EditTrigger::NoEditTriggers);
         widget.treeWidgetSkillDetails->setColumnHidden(3, true);
 
         connected = true;
     }
 
-    void SkillManagerMonitorWidgetController::onDisconnectComponent()
+    void
+    SkillManagerMonitorWidgetController::onDisconnectComponent()
     {
         connected = false;
+        manager = nullptr;
 
         // reset all
         skills.clear();
@@ -140,25 +169,30 @@ namespace armarx
         selectedSkill.skillName = "";
     }
 
-    void SkillManagerMonitorWidgetController::updateTimerFrequency()
+    void
+    SkillManagerMonitorWidgetController::updateTimerFrequency()
     {
         int f = static_cast<int>(std::round(1000 / widget.doubleSpinBoxUpdateFreq->value()));
         refreshSkillsResultTimer->setInterval(f);
     }
 
-    void SkillManagerMonitorWidgetController::refreshSkills()
+    void
+    SkillManagerMonitorWidgetController::refreshSkills()
     {
-        static std::map<skills::provider::dto::Execution::Status, std::string> ExecutionStatus2String = {
-            {skills::provider::dto::Execution::Status::Aborted, "Aborted"},
-            {skills::provider::dto::Execution::Status::Failed, "Failed"},
-            {skills::provider::dto::Execution::Status::Idle, "Not yet started"},
-            {skills::provider::dto::Execution::Status::Running, "Running"},
-            {skills::provider::dto::Execution::Status::Scheduled, "Scheduled"},
-            {skills::provider::dto::Execution::Status::Succeeded, "Succeeded"}
-        };
-
-        if (!connected)
+        static std::map<skills::provider::dto::Execution::Status, std::string>
+            ExecutionStatus2String = {
+                {skills::provider::dto::Execution::Status::Aborted, "Aborted"},
+                {skills::provider::dto::Execution::Status::Failed, "Failed"},
+                {skills::provider::dto::Execution::Status::Idle, "Not yet started"},
+                {skills::provider::dto::Execution::Status::Running, "Running"},
+                {skills::provider::dto::Execution::Status::Scheduled, "Scheduled"},
+                {skills::provider::dto::Execution::Status::Succeeded, "Succeeded"}};
+
+        if (!manager)
+        {
+            reconnectToSkillManager();
             return;
+        }
 
         /* CHECK OWN SKILLS LIST */
         // remove non-existing ones
@@ -196,7 +230,9 @@ namespace armarx
         while (i < widget.treeWidgetSkills->topLevelItemCount())
         {
             QTreeWidgetItem* item = widget.treeWidgetSkills->topLevelItem(i);
-            if (std::find(removedProviders.begin(), removedProviders.end(), item->text(0).toStdString()) != removedProviders.end())
+            if (std::find(removedProviders.begin(),
+                          removedProviders.end(),
+                          item->text(0).toStdString()) != removedProviders.end())
             {
                 delete widget.treeWidgetSkills->takeTopLevelItem(i);
             }
@@ -209,7 +245,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(newProviders.begin(), newProviders.end(), providerName);
+                it != newProviders.end())
             {
                 auto item = new QTreeWidgetItem(widget.treeWidgetSkills);
                 item->setText(0, QString::fromStdString(providerName));
@@ -225,7 +262,7 @@ namespace armarx
         // update status and active skills window
         std::map<skills::SkillID, std::string> activeSkillsAndPrefixes;
         auto managerStatuses = manager->getSkillExecutionStatuses();
-        for (int i = 0;  i < widget.treeWidgetSkills->topLevelItemCount(); ++i)
+        for (int i = 0; i < widget.treeWidgetSkills->topLevelItemCount(); ++i)
         {
             try
             {
@@ -240,11 +277,15 @@ namespace armarx
                     skills::SkillID currentSkillId(providerName, skillItem->text(0).toStdString());
 
                     auto statusForSkill = allStatusesForProvider.at(currentSkillId.skillName);
-                    skillItem->setText(2, QString::fromStdString(ExecutionStatus2String.at(statusForSkill.header.status)));
+                    skillItem->setText(2,
+                                       QString::fromStdString(ExecutionStatus2String.at(
+                                           statusForSkill.header.status)));
 
-                    if (not statusForSkill.header.executorName.empty()) // it means that the skill was called by someone
+                    if (not statusForSkill.header.executorName
+                                .empty()) // it means that the skill was called by someone
                     {
-                        activeSkillsAndPrefixes.insert({currentSkillId, statusForSkill.header.executorName});
+                        activeSkillsAndPrefixes.insert(
+                            {currentSkillId, statusForSkill.header.executorName});
                     }
                 }
             }
@@ -261,7 +302,8 @@ namespace armarx
         {
             auto prefixedStr = id.toString(prefix);
             bool longest = true;
-            for (const auto& [id2, prefix2] : activeSkillsAndPrefixes) // check if there is a deeper skill currently executing
+            for (const auto& [id2, prefix2] :
+                 activeSkillsAndPrefixes) // check if there is a deeper skill currently executing
             {
                 auto prefixedStr2 = id.toString(prefix2);
                 if (prefixedStr == prefixedStr2)
@@ -278,12 +320,14 @@ namespace armarx
 
             if (longest)
             {
-                widget.listWidgetActiveSkills->addItem(QString::fromStdString(id.toString() + ": " + id.toString(prefix)));
+                widget.listWidgetActiveSkills->addItem(
+                    QString::fromStdString(id.toString() + ": " + id.toString(prefix)));
             }
         }
     }
 
-    void SkillManagerMonitorWidgetController::executeSkill()
+    void
+    SkillManagerMonitorWidgetController::executeSkill()
     {
         if (selectedSkill.providerName.empty() or selectedSkill.skillName.empty())
         {
@@ -307,12 +351,14 @@ namespace armarx
         exInfo.skillId = {selectedSkill.providerName, selectedSkill.skillName};
         exInfo.params = aron::data::Dict::ToAronDictDTO(data);
 
-        ARMARX_IMPORTANT << "Executing skill from GUI: " << selectedSkill.providerName << "/" << selectedSkill.skillName << ". The data was: " << data;
+        ARMARX_IMPORTANT << "Executing skill from GUI: " << selectedSkill.providerName << "/"
+                         << selectedSkill.skillName << ". The data was: " << data;
         // Note that we execute the skill in a seperate thread so that the GUI thread does not freeze.
         manager->begin_executeSkill(exInfo);
     }
 
-    void SkillManagerMonitorWidgetController::stopSkill()
+    void
+    SkillManagerMonitorWidgetController::stopSkill()
     {
         if (selectedSkill.providerName.empty() or selectedSkill.skillName.empty())
         {
@@ -325,11 +371,14 @@ namespace armarx
             return;
         }
 
-        ARMARX_INFO << "Stopping skill from GUI: " << selectedSkill.providerName << "/" << selectedSkill.skillName;
+        ARMARX_INFO << "Stopping skill from GUI: " << selectedSkill.providerName << "/"
+                    << selectedSkill.skillName;
         manager->abortSkill(selectedSkill.providerName, selectedSkill.skillName);
     }
 
-    void SkillManagerMonitorWidgetController::skillSelectionChanged(QTreeWidgetItem* current, QTreeWidgetItem*)
+    void
+    SkillManagerMonitorWidgetController::skillSelectionChanged(QTreeWidgetItem* current,
+                                                               QTreeWidgetItem*)
     {
         widget.groupBoxSkillDetails->setEnabled(false);
 
@@ -352,10 +401,12 @@ namespace armarx
         newSelectedSkill.skillName = current->text(0).toStdString();
 
         // setup groupBox
-        widget.groupBoxSkillDetails->setTitle(QString::fromStdString(newSelectedSkill.providerName + "/" + newSelectedSkill.skillName));
+        widget.groupBoxSkillDetails->setTitle(QString::fromStdString(
+            newSelectedSkill.providerName + "/" + newSelectedSkill.skillName));
         widget.groupBoxSkillDetails->setEnabled(true);
 
-        if (newSelectedSkill.providerName == selectedSkill.providerName and newSelectedSkill.skillName == selectedSkill.skillName)
+        if (newSelectedSkill.providerName == selectedSkill.providerName and
+            newSelectedSkill.skillName == selectedSkill.skillName)
         {
             return;
         }
@@ -370,37 +421,46 @@ 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.skillName)});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
         {
-            auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
-                                          {QString::fromStdString("Robot"), QString::fromStdString(simox::alg::join(skillDesc.robots, ", "))});
+            auto it = new QTreeWidgetItem(
+                widget.treeWidgetSkillDetails,
+                {QString::fromStdString("Robot"),
+                 QString::fromStdString(simox::alg::join(skillDesc.robots, ", "))});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
         {
             auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
-                                          {QString::fromStdString("Description"), QString::fromStdString(skillDesc.description)});
+                                          {QString::fromStdString("Description"),
+                                           QString::fromStdString(skillDesc.description)});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
         {
-            auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
-                                          {QString::fromStdString("Timeout"), QString::fromStdString(std::to_string(skillDesc.timeoutMs)) + " ms"});
+            auto it = new QTreeWidgetItem(
+                widget.treeWidgetSkillDetails,
+                {QString::fromStdString("Timeout"),
+                 QString::fromStdString(std::to_string(skillDesc.timeoutMs)) + " ms"});
             widget.treeWidgetSkillDetails->addTopLevelItem(it);
         }
 
-        skillsArgumentsTreeWidgetItem = new QTreeWidgetItem(widget.treeWidgetSkillDetails, {QString::fromStdString("Arguments")});
+        skillsArgumentsTreeWidgetItem = new QTreeWidgetItem(widget.treeWidgetSkillDetails,
+                                                            {QString::fromStdString("Arguments")});
         auto aron_args = aron::type::Object::FromAronObjectDTO(skillDesc.acceptedType);
         auto default_args = aron::data::Dict::FromAronDictDTO(skillDesc.defaultParams);
 
-        aronTreeWidgetController = std::make_shared<AronTreeWidgetController>(widget.treeWidgetSkillDetails, skillsArgumentsTreeWidgetItem, aron_args, default_args);
+        aronTreeWidgetController = std::make_shared<AronTreeWidgetController>(
+            widget.treeWidgetSkillDetails, skillsArgumentsTreeWidgetItem, aron_args, default_args);
     }
 
-    aron::data::DictPtr SkillManagerMonitorWidgetController::getConfigAsAron() const
+    aron::data::DictPtr
+    SkillManagerMonitorWidgetController::getConfigAsAron() const
     {
         // create argument aron (if there is an accepted type set)
         if (aronTreeWidgetController)
@@ -410,7 +470,8 @@ namespace armarx
         return nullptr;
     }
 
-    void SkillManagerMonitorWidgetController::copyCurrentConfig()
+    void
+    SkillManagerMonitorWidgetController::copyCurrentConfig()
     {
         auto data = getConfigAsAron();
         if (!data)
@@ -423,7 +484,8 @@ namespace armarx
         clipboard->setText(QString::fromStdString(json.dump(2)));
     }
 
-    void SkillManagerMonitorWidgetController::pasteCurrentConfig()
+    void
+    SkillManagerMonitorWidgetController::pasteCurrentConfig()
     {
         QClipboard* clipboard = QApplication::clipboard();
         std::string s = clipboard->text().toStdString();
@@ -438,34 +500,10 @@ namespace armarx
         aronTreeWidgetController->setFromAron(data);
     }
 
-    void SkillManagerMonitorWidgetController::resetCurrentConfig()
+    void
+    SkillManagerMonitorWidgetController::resetCurrentConfig()
     {
         // TODO
     }
 
-    void SkillManagerMonitorWidgetController::onTreeWidgetItemDoubleClicked(QTreeWidgetItem* item, int column)
-    {
-        if (!item)
-        {
-            return;
-        }
-
-        if (column == 1)
-        {
-            if (item->flags() & Qt::ItemIsEditable) // we use the flag to indicate whether the item is editable or not
-            {
-                // we assume its aron item
-                AronTreeWidgetItem* aItem = AronTreeWidgetItem::DynamicCastAndCheck(item);
-                std::string name = aItem->text(aron_tree_widget::constantes::TREE_WIDGET_ITEM_NAME).toStdString();
-                std::string type = aItem->text(aron_tree_widget::constantes::TREE_WIDGET_ITEM_TYPE).toStdString();
-
-                // why visitor?!?!?
-                AronTreeWidgetModalCreatorVisitor v(name, aItem, widget.treeWidgetSkillDetails);
-                aron::type::visit(v, aItem->aronType);
-                auto modal = v.createdModal;
-                modal->exec();
-            }
-        }
-    }
-}
-
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
index 64256f2d6530d766726df37ec5fc60c9429d3e70..d9a9379bdfdea0ee56c9c5f3e601ef68a5ce75b5 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h
@@ -22,25 +22,24 @@
 #pragma once
 
 #include <stack>
-#include <vector>
 #include <thread>
+#include <vector>
+
+#include <QTimer>
+
 #include <ArmarXCore/core/system/ImportExportComponent.h>
 
-#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 #include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h>
+#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h>
 
-#include <RobotAPI/interface/skills/SkillMemoryInterface.h>
-
 #include <RobotAPI/gui-plugins/SkillManagerPlugin/ui_SkillManagerMonitorWidget.h>
-
-#include "aronTreeWidget/AronTreeWidgetController.h"
-
-#include <RobotAPI/libraries/aron/core/type/variant/All.h>
+#include <RobotAPI/interface/skills/SkillMemoryInterface.h>
 #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 <QTimer>
+#include "aronTreeWidget/AronTreeWidgetController.h"
 
 namespace armarx
 {
@@ -71,6 +70,8 @@ namespace armarx
             return "Skills.Manager";
         }
 
+        void reconnectToSkillManager();
+
         void onInitComponent() override;
         void onConnectComponent() override;
         void onDisconnectComponent() override;
@@ -88,7 +89,6 @@ namespace armarx
         void pasteCurrentConfig();
         void resetCurrentConfig();
 
-        void onTreeWidgetItemDoubleClicked(QTreeWidgetItem * item, int column);
 
     private:
         aron::data::DictPtr getConfigAsAron() const;
@@ -120,11 +120,13 @@ namespace armarx
         AronTreeWidgetControllerPtr aronTreeWidgetController = nullptr;
 
         // others
-        std::atomic_bool connected = false;
         QTimer* refreshSkillsResultTimer;
 
         // skillExecutions
         std::vector<std::thread> executions;
+
+        // connected flag
+        std::atomic_bool connected = false;
     };
 }
 
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/TODO b/source/RobotAPI/gui-plugins/SkillManagerPlugin/TODO
new file mode 100644
index 0000000000000000000000000000000000000000..d25aead078c039b5724f9a6f05abe669ed1caf50
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/TODO
@@ -0,0 +1,3 @@
+- keep set values around to not loose precision of values that have not been manipulated (in AronTreeWidgetItem, as well as Matrix and Quaternion) 
+- get rid of any todos present
+
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp
index 0ef63ff506ebb1f624f7380e61309f02c522b915..52110b494a2bfc38a361d8354eb18efccc760617 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.cpp
@@ -1,43 +1,62 @@
 #include "AronTreeWidgetController.h"
 
+#include <RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.h>
+
+#include "visitors/AronTreeWidgetContextMenu.h"
 #include "visitors/AronTreeWidgetConverter.h"
 #include "visitors/AronTreeWidgetSetter.h"
 
+
 namespace armarx
 {
-    AronTreeWidgetController::AronTreeWidgetController(QTreeWidget* tree, QTreeWidgetItem* parent, const aron::type::ObjectPtr& type, const aron::data::DictPtr& data):
-        parent(parent),
-        tree(tree),
-        type(type)
+    AronTreeWidgetController::AronTreeWidgetController(QTreeWidget* tree,
+                                                       QTreeWidgetItem* parent,
+                                                       const aron::type::ObjectPtr& type,
+                                                       const aron::data::DictPtr& data) :
+        parent(parent), tree(tree), type(type)
     {
-        if (type) // if there is a type set, we create a tree widget from the typp
+        connect(tree,
+                SIGNAL(customContextMenuRequested(const QPoint&)),
+                this,
+                SLOT(ShowContextMenu(const QPoint&)));
+        connect(tree,
+                &QTreeWidget::itemDoubleClicked,
+                this,
+                &AronTreeWidgetController::onTreeWidgetItemDoubleClicked);
+
+        if (type) // if there is a type set, we create a tree widget from the type
         {
-            AronTreeWidgetCreatorVisitor v;
+            AronTreeWidgetCreatorVisitor v(parent);
+            v.setTopLevelWidget(tree);
             aron::type::visit(v, type);
 
-            if (v.createdQWidgetItem)
-            {
-                parent->addChild(v.createdQWidgetItem);
-            }
-
             if (data) // check if there is a default argument set. Prefill the GUI with it
             {
                 setFromAron(data);
             }
         }
-        else if(data) // there is no type but a default configuration. Prefill the GUI with the default arguments
+        // there is no type but a default configuration. Prefill the GUI with the default arguments
+        else if (data)
         {
+            // TODO: There is no visitor for that (yet)...
             // create type from data, ...
         }
         else
         {
             new QTreeWidgetItem(parent, {QString::fromStdString("No args")});
         }
+
+        // connect change handling after args init
+        connect(tree,
+                &QTreeWidget::itemChanged,
+                this,
+                &AronTreeWidgetController::onTreeWidgetItemChanged);
     }
 
-    aron::data::DictPtr AronTreeWidgetController::convertToAron() const
+    aron::data::DictPtr
+    AronTreeWidgetController::convertToAron() const
     {
-        if (parent)
+        if (parent && type)
         {
             AronTreeWidgetConverterVisitor v(parent, 0);
             aron::type::visit(v, type);
@@ -48,7 +67,8 @@ namespace armarx
         return nullptr;
     }
 
-    void AronTreeWidgetController::setFromAron(const aron::data::DictPtr& data)
+    void
+    AronTreeWidgetController::setFromAron(const aron::data::DictPtr& data)
     {
         if (parent)
         {
@@ -56,4 +76,87 @@ namespace armarx
             aron::data::visit(v, data);
         }
     }
-}
+    void
+    AronTreeWidgetController::ShowContextMenu(const QPoint& pos)
+    {
+        tree->blockSignals(true);
+
+        auto idx = tree->indexAt(pos);
+        AronTreeWidgetItem* clickedItem = AronTreeWidgetItem::DynamicCast(tree->itemAt(pos));
+        if (clickedItem)
+        {
+            AronTreeWidgetContextMenuVisitor visitor(clickedItem, pos, tree, idx.row());
+
+            aron::type::visit(visitor, clickedItem->aronType);
+            visitor.showMenuAndExecute();
+        }
+
+        tree->blockSignals(false);
+    }
+    void
+    AronTreeWidgetController::onTreeWidgetItemDoubleClicked(QTreeWidgetItem* item, int column)
+    {
+        if (!item)
+        {
+            return;
+        }
+        tree->blockSignals(true);
+
+        auto* aronItem = AronTreeWidgetItem::DynamicCast(item);
+        if (column == 1 && aronItem)
+        {
+
+
+            std::string name =
+                aronItem->text(aron_tree_widget::constantes::TREE_WIDGET_ITEM_NAME).toStdString();
+            // depending on aron type, create extra gui element.
+            AronTreeWidgetModalCreatorVisitor v(name, aronItem, tree);
+            aron::type::visit(v, aronItem->aronType);
+            auto modal = v.createdModal;
+
+            // if no modal is created, we instead use the edit field directly
+            if (modal)
+            {
+                modal->exec();
+            }
+            else if (aronItem->col1Editable)
+            {
+                item->treeWidget()->editItem(item, column);
+            }
+        }
+        else if (column == 0 && aronItem && aronItem->col0Editable)
+        {
+            item->treeWidget()->editItem(item, column);
+        }
+
+        tree->blockSignals(false);
+    }
+
+    void
+    AronTreeWidgetController::onTreeWidgetItemChanged(QTreeWidgetItem* item, int column)
+    {
+        tree->blockSignals(true);
+
+        auto* aronElem = AronTreeWidgetItem::DynamicCast(item);
+        if (aronElem)
+        {
+            aronElem->onUserChange(column);
+        }
+        // start conversion for entire tree -- this also sets the highlighting
+        if (parent->childCount() == 1)
+        {
+            auto* aronTreeRoot = AronTreeWidgetItem::DynamicCast(parent->child(0));
+            aronTreeRoot->resetError();
+            if (aronTreeRoot)
+            {
+                AronTreeWidgetConverterVisitor v(parent, 0);
+                aron::type::visit(v, type);
+                aronTreeRoot->setValueErrorState(v.hasDirectError(), v.onlyChildFailedConversion());
+            }
+        }
+        // else perhaps the GUI was stopped or died.
+
+        tree->blockSignals(false);
+    }
+
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.h
index c70b0277b41684a7144319a3c9d07fcf7dd31668..c3c2c9c2c913fba11fdd4dfc362e98297c4338f4 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetController.h
@@ -1,24 +1,30 @@
 #pragma once
 
 #include <stack>
-#include <ArmarXCore/core/system/ImportExportComponent.h>
 
-#include "Data.h"
+#include <QTreeWidget>
+
+#include <ArmarXCore/core/system/ImportExportComponent.h>
 
-#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 #include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h>
+#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 
-#include <QTreeWidget>
-#include "visitors/AronTreeWidgetCreator.h"
 #include "AronTreeWidgetItem.h"
+#include "Data.h"
+#include "visitors/AronTreeWidgetCreator.h"
 
 namespace armarx
 {
-    class AronTreeWidgetController
+    // Main controller for any AronTreeWidget GUI. It attaches itself to the parent and needs the active widget.
+    // It's responsible to handle all signals for non-widget fields and click events.
+    class AronTreeWidgetController : public QObject
     {
-
+        Q_OBJECT
     public:
-        AronTreeWidgetController(QTreeWidget* tree, QTreeWidgetItem* parent, const aron::type::ObjectPtr& type, const aron::data::DictPtr& data = nullptr);
+        AronTreeWidgetController(QTreeWidget* tree,
+                                 QTreeWidgetItem* parent,
+                                 const aron::type::ObjectPtr& type,
+                                 const aron::data::DictPtr& data = nullptr);
 
         aron::data::DictPtr convertToAron() const;
         void setFromAron(const aron::data::DictPtr&);
@@ -28,7 +34,19 @@ namespace armarx
         QTreeWidget* tree;
 
         aron::type::ObjectPtr type;
+
+    private slots:
+        // allows most primitive fields to be directly editable in the tree
+        // only String will open up a new widget
+        void onTreeWidgetItemDoubleClicked(QTreeWidgetItem* item, int column);
+        // check the new user input. Maybe undo if the field must not be edited.
+        // Also highlight if the input cannot be parsed. (Or the errors are now fixed)
+        void onTreeWidgetItemChanged(QTreeWidgetItem* item, int column);
+
+    public slots:
+        // hook for items to show a context menu (add  / delete element)
+        void ShowContextMenu(const QPoint&);
     };
 
     using AronTreeWidgetControllerPtr = std::shared_ptr<AronTreeWidgetController>;
-}
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.cpp
index e53161bb8b2ee4aee0c34ac2fc82c3214894f0cd..29d895f7b0f9666ebf42acd2bf3046ac90d7f1db 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.cpp
@@ -1,21 +1,24 @@
 #include "AronTreeWidgetItem.h"
 
+#include <QAction>
+#include <QMenu>
+
 #include <RobotAPI/libraries/aron/core/type/variant/All.h>
 
+#include "../ColorPalettes.h"
+#include "visitors/AronTreeWidgetConverter.h"
+#include "widgets/CustomWidget.h"
+
 namespace armarx
 {
-    AronTreeWidgetItem* AronTreeWidgetItem::DynamicCast(QTreeWidgetItem* i)
+    AronTreeWidgetItem*
+    AronTreeWidgetItem::DynamicCast(QTreeWidgetItem* i)
     {
         return dynamic_cast<AronTreeWidgetItem*>(i);
     }
 
-    AronTreeWidgetItem* AronTreeWidgetItem::copy()
-    {
-        AronTreeWidgetItem* ret = new AronTreeWidgetItem(*this);
-        return ret;
-    }
-
-    AronTreeWidgetItem* AronTreeWidgetItem::DynamicCastAndCheck(QTreeWidgetItem* i)
+    AronTreeWidgetItem*
+    AronTreeWidgetItem::DynamicCastAndCheck(QTreeWidgetItem* i)
     {
         if (!i)
         {
@@ -25,4 +28,174 @@ namespace armarx
         ARMARX_CHECK_NOT_NULL(c);
         return c;
     }
-}
+
+    bool
+    AronTreeWidgetItem::isValueErrorneous()
+    {
+        return itemValueError;
+    }
+
+    void
+    AronTreeWidgetItem::setValueErrorState(bool isErrorSource, bool isTransitiveError)
+    {
+        itemValueError |= isErrorSource;
+        transitiveValueError |= isTransitiveError;
+
+
+        if (CustomWidget::DynamicCast(treeWidget()->itemWidget(this, 1)))
+        {
+            // The widgets handle errors themselves
+            return;
+        }
+        auto palette = gui_color_palette::getNormalPalette();
+        if (itemValueError)
+        {
+            palette = gui_color_palette::getErrorPalette();
+        }
+        else if (transitiveValueError)
+        {
+            palette = gui_color_palette::getIndirectErrorPalette();
+        }
+
+        QTreeWidgetItem::setBackground(1, QBrush(palette.color(QPalette::Base)));
+    }
+
+    void
+    AronTreeWidgetItem::setKeyErrorState(bool hasError)
+    {
+        ARMARX_CHECK(col0Editable); //only editable keys should call this function!
+        auto palette =
+            hasError ? gui_color_palette::getErrorPalette() : gui_color_palette::getNormalPalette();
+
+        keyValueError = hasError;
+
+        QTreeWidgetItem::setBackground(1, QBrush(palette.color(QPalette::Base)));
+    }
+
+    void
+    AronTreeWidgetItem::resetError()
+    {
+        keyValueError = false;
+        itemValueError = false;
+        transitiveValueError = false;
+        // also reset children
+        for (int i = 0; i < childCount(); ++i)
+        {
+            auto* arChild = AronTreeWidgetItem::DynamicCastAndCheck(QTreeWidgetItem::child(i));
+            arChild->resetError();
+        }
+    }
+
+
+    void
+    AronTreeWidgetItem::checkKeyValidityOfChildren()
+    {
+        ARMARX_CHECK(aronType->getDescriptor() == aron::type::Descriptor::DICT);
+        // return if check failed
+        if (aronType->getDescriptor() != aron::type::Descriptor::DICT)
+        {
+            return;
+        }
+        // iterate through children; memorize keys
+        std::map<QString, std::vector<int>> found_keys;
+        auto numChildren = childCount();
+        for (int i = 0; i < numChildren; ++i)
+        {
+            auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
+            if (!casted)
+            {
+                // soft error here, we already report it above. - Definetly programming error
+                continue;
+            }
+            auto& vec = found_keys[casted->text(0)];
+            vec.push_back(i);
+        }
+        // highlight keys that conflict
+        // memorize children that are not ok
+        std::set<int> errorneous_indices;
+        for (auto [key, vals] : found_keys)
+        {
+            if (vals.size() > 1)
+            {
+                for (int i : vals)
+                {
+                    auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
+                    if (!casted)
+                    {
+                        // soft error here, we already report it above. - Definetly programming error
+                        continue;
+                    }
+                    casted->setKeyErrorState(true);
+                    errorneous_indices.emplace(i);
+                }
+            }
+        }
+        // clear potential error state of other elements
+        for (int i = 0; i < numChildren; ++i)
+        {
+            if (errorneous_indices.find(i) != errorneous_indices.end())
+            {
+                continue;
+            }
+            auto* casted = AronTreeWidgetItem::DynamicCastAndCheck(child(i));
+            if (!casted)
+            {
+                // soft error here, we already report it above. - Definetly programming error
+                continue;
+            }
+            casted->setKeyErrorState(false);
+        }
+    }
+
+    void
+    AronTreeWidgetItem::onUserChange(int changedColumn)
+    {
+        QTreeWidgetItem* qParent = QTreeWidgetItem::parent();
+        ARMARX_CHECK(qParent);
+        AronTreeWidgetItem* aronParent = DynamicCast(qParent);
+        if (changedColumn == 0)
+        {
+            if (col0Editable)
+            {
+                // Topmost should always be an Object and col0 is not editable in the child then...
+                // -> aronParent should never be nullptr
+                ARMARX_CHECK(aronParent);
+                // check if the element is child of a dict. If so, validate uniqueness of keys
+                if (aronParent->aronType->getDescriptor() == aron::type::Descriptor::DICT)
+                {
+                    aronParent->checkKeyValidityOfChildren();
+                }
+            }
+            else
+            {
+                // maybe while editing keys, we try to edit a key that should not change by tabbing.
+                // Catch that here and undo the edit
+                preventIllegalKeyChange();
+            }
+        }
+    }
+
+    void
+    AronTreeWidgetItem::preventIllegalKeyChange()
+    {
+        if (!col0Editable)
+        {
+            setText(0, unchangeableKey);
+        }
+    }
+
+    AronTreeWidgetItem::AronTreeWidgetItem(bool editKey,
+                                           bool editVal,
+                                           QString key,
+                                           aron::type::VariantPtr type) :
+        aronType(type), col0Editable(editKey), col1Editable(editVal)
+    {
+        this->setText(0, key);
+        // add hook to check for edited keys for children of dictionaries
+        if (!editKey)
+        {
+            unchangeableKey = std::move(key);
+        }
+    }
+
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.h
index 3d6d0c2a329c5a4376fb24a406dadf706d6b898b..9106cb3192526f15355445deb0c6f1654921c17a 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/AronTreeWidgetItem.h
@@ -1,39 +1,65 @@
 #pragma once
 
-#include <stack>
-#include <ArmarXCore/core/system/ImportExportComponent.h>
+#include <QTreeWidget>
 
-#include "Data.h"
+#include <ArmarXCore/core/system/ImportExportComponent.h>
 
-#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 #include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h>
+#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
 
 #include <RobotAPI/libraries/aron/core/type/variant/Variant.h>
 
-#include <QTreeWidget>
+#include "Data.h"
 
 namespace armarx
 {
+    // Internal derived QtTreeWidgetItem class. Contains additional information to compare its data agains aron types.
+    // It contains 3 columns: Key ; Value ; Type
+    // The key can only be edited if the parent object is a dict
     class AronTreeWidgetItem : public QObject, public QTreeWidgetItem
     {
         Q_OBJECT
     public:
-        AronTreeWidgetItem(const AronTreeWidgetItem& other) :
-            QObject(),
-            QTreeWidgetItem(other)
-        {
-            aronType = other.aronType;
-        }
+        AronTreeWidgetItem(bool editKey, bool editVal, QString key, aron::type::VariantPtr type);
 
         using QTreeWidgetItem::QTreeWidgetItem;
 
-        AronTreeWidgetItem* copy(); // differs from clone!!!!
-
         static AronTreeWidgetItem* DynamicCast(QTreeWidgetItem*);
-
         static AronTreeWidgetItem* DynamicCastAndCheck(QTreeWidgetItem*);
 
         aron::type::VariantPtr aronType;
+        // if editing the first column should be allowed
+        const bool col0Editable = false;
+        // if editing the second column should be allowed
+        const bool col1Editable = false;
+
+        bool isValueErrorneous();
+        // marks the gui in a specific color. Also stores if there is currently an error.
+        // the only way to reset the color back to normal is with resetError() (error is sticky)
+        void setValueErrorState(bool isErrorSource, bool isTransitiveError);
+        void setKeyErrorState(bool hasError);
+        // reset error storage that influences coloring for this and all children
+        void resetError();
+
+        // Checks if the children of a dict are unique
+        // should not be called on other types! (does nothing then)
+        void checkKeyValidityOfChildren();
+
+        // main logic on changes. Gets called from the onTreeWidgetItemChanged() slot in AronTreeWidgetController.
+        // (This class cannot directly consume this signal, at least I did not find a nice way...)
+        void onUserChange(int changedColumn);
+
+    private:
+        // because the editable keyword counts for all columns, it is possible to TAB into uneditable keys.
+        // We do not want those to change, so just change them back once they finished editing.
+        void preventIllegalKeyChange();
 
+        bool itemValueError = false;
+        bool transitiveValueError = false;
+        bool keyValueError = false;
+        // hacky storage of previous key value for items that usually should not be editable.
+        // Problem: Dict-keys are editable, one can tab from that to any other value field and edit it.
+        // Fix: Once the change is commited, the AronTreeWidgetController notices the change and checks if it was allowed.
+        QString unchangeableKey = "";
     };
-}
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/ListDictHelper.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/ListDictHelper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9866e8bc9f8c35a00e6411331461511e4c031e9f
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/ListDictHelper.cpp
@@ -0,0 +1,28 @@
+#include "ListDictHelper.h"
+
+namespace armarx::misc
+{
+    QString
+    generateNumElementsText(int num)
+    {
+        QString numElemsText = "<";
+        if (num == 0)
+        {
+            numElemsText.append("no");
+        }
+        else
+        {
+            numElemsText.append(QString::number(num));
+        }
+        if (num > 1 || num == 0)
+        {
+            numElemsText.append(" elements>");
+        }
+        else
+        {
+            numElemsText.append(" element>");
+        }
+        return numElemsText;
+    }
+
+} // namespace armarx::misc
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/ListDictHelper.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/ListDictHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5d991ad2861aef5c32fc82c033c9090070f13b5
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/ListDictHelper.h
@@ -0,0 +1,8 @@
+#include <QString>
+
+
+namespace armarx::misc
+{
+    // helper that generates a string on how many items are available
+    QString generateNumElementsText(int num);
+} // namespace armarx::misc
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp
index f7d83d98b6cde491cad878822b69b50adb34d355..71a88e54fcf49d77ea5de6804ef06a11e90e6ae8 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp
@@ -1,6 +1,7 @@
 #include "AronTreeWidgetDictInputModalController.h"
 
 #include <RobotAPI/libraries/aron/core/type/variant/All.h>
+
 #include "../../visitors/AronTreeWidgetCreator.h"
 
 namespace armarx
@@ -29,7 +30,7 @@ namespace armarx
     {
         for (const auto& added : addedItems)
         {
-            item->addChild(added->copy());
+            //item->addChild(added->copy());
         }
 
         AronTreeWidgetModal::submit();
@@ -59,12 +60,14 @@ namespace armarx
             auto d = aron::type::Dict::DynamicCastAndCheck(t);
             auto ac = d->getAcceptedType();
 
-            AronTreeWidgetCreatorVisitor v;
+            AronTreeWidgetCreatorVisitor v(nullptr);
+            v.setTopLevelWidget(widget.treeWidgetDict);
             aron::type::visit(v, ac);
 
             if (v.createdQWidgetItem)
             {
-                v.createdQWidgetItem->setText(aron_tree_widget::constantes::TREE_WIDGET_ITEM_NAME, s);
+                v.createdQWidgetItem->setText(aron_tree_widget::constantes::TREE_WIDGET_ITEM_NAME,
+                                              s);
                 addedItems.push_back(v.createdQWidgetItem);
                 widget.treeWidgetDict->addTopLevelItem(v.createdQWidgetItem);
             }
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..98e271cd81c8180af051e094169f63b58176b0e8
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.cpp
@@ -0,0 +1,243 @@
+#include "AronTreeWidgetContextMenu.h"
+
+#include <QMenu>
+#include <QPoint>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+
+#include "../AronTreeWidgetItem.h"
+#include "../ListDictHelper.h"
+#include "AronTreeWidgetCreator.h"
+
+namespace armarx
+{
+    AronTreeWidgetContextMenuVisitor::AronTreeWidgetContextMenuVisitor(
+        AronTreeWidgetItem* i,
+        const QPoint& pos,
+        QTreeWidget* contextMenuParent,
+        int x) :
+        parentItem(i), contextMenuParent(contextMenuParent), pos(pos), index(x)
+    {
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::addDeleteAction()
+    {
+        auto* castedParent = AronTreeWidgetItem::DynamicCast(parentItem->QTreeWidgetItem::parent());
+        if (!castedParent)
+        {
+            // must be top level element
+            return;
+        }
+        auto aronType = castedParent->aronType->getDescriptor();
+        if (aron::type::Descriptor::DICT == aronType || aron::type::Descriptor::LIST == aronType)
+        {
+            QMenu contextMenu("Context menu", contextMenuParent);
+            actions.emplace_back("remove element", contextMenuParent);
+            action_callbacks.push_back([this]() mutable { this->executeDelete(); });
+        }
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::executeDelete()
+    {
+        auto* containerPtr = parentItem->QTreeWidgetItem::parent();
+        containerPtr->removeChild(parentItem);
+        auto* castedContainer = AronTreeWidgetItem::DynamicCast(containerPtr);
+
+        // if the parent item is a List, we need to redo the numbers
+        if (castedContainer &&
+            castedContainer->aronType->getDescriptor() == aron::type::Descriptor::LIST)
+        {
+            // start renumbering from the removed child onwards
+            for (int i = index; i < castedContainer->childCount(); ++i)
+            {
+                std::string numberString = std::to_string(i);
+                castedContainer->child(i)->setText(0, numberString.c_str());
+            }
+            // This displays the number of children also when the list is collapsed
+            QString numElemsText = misc::generateNumElementsText(castedContainer->childCount());
+            containerPtr->setText(1, numElemsText);
+            // set italic
+            auto currFont = castedContainer->font(1);
+            currFont.setItalic(true);
+            castedContainer->setFont(1, currFont);
+        }
+    }
+
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::ObjectPtr&)
+    {
+        addDeleteAction();
+    }
+
+    // lol
+    void
+    armarx::AronTreeWidgetContextMenuVisitor::addAddAction()
+    {
+        actions.emplace_back("Add element", contextMenuParent);
+        action_callbacks.push_back([this]() mutable { this->executeAddElement(); });
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::executeAddElement()
+    {
+        AronTreeWidgetCreatorVisitor creator(parentItem);
+        aron::type::visit(creator, parentItem->aronType->getChildren()[0]);
+
+        if (!creator.createdQWidgetItem)
+        {
+            throw std::runtime_error("Creation of TreeElementChild failed unexpectedly");
+        }
+        // if it is a list, we update the number of children at the top
+        auto* castedContainer = AronTreeWidgetItem::DynamicCast(parentItem);
+
+        // if the parent item is a List, we need to redo the numbers
+        if (castedContainer &&
+            castedContainer->aronType->getDescriptor() == aron::type::Descriptor::LIST)
+        {
+            // This displays the number of children also when the list is collapsed
+            auto numElemsText = misc::generateNumElementsText(castedContainer->childCount());
+            castedContainer->setText(1, numElemsText);
+            // set italic
+            auto currFont = castedContainer->font(1);
+            currFont.setItalic(true);
+            castedContainer->setFont(1, currFont);
+        }
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::DictPtr&)
+    {
+        addAddAction();
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::PairPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::TuplePtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::ListPtr&)
+    {
+        addAddAction();
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::NDArrayPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::MatrixPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::QuaternionPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::ImagePtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::PointCloudPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::IntEnumPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::IntPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::LongPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::FloatPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::DoublePtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::BoolPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitAronVariant(const aron::type::StringPtr&)
+    {
+        addDeleteAction();
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::visitUnknown(Input&)
+    {
+        ARMARX_WARNING << "Tried to open Context menu on unknown aron type";
+    }
+
+    void
+    AronTreeWidgetContextMenuVisitor::showMenuAndExecute()
+    {
+        QMenu menu("Context Menu", contextMenuParent);
+        for (auto& el : actions)
+        {
+            menu.addAction(&el);
+        }
+        auto* chosenAction = menu.exec(contextMenuParent->mapToGlobal(pos));
+
+        if (!chosenAction)
+        {
+            return;
+        }
+
+        // not elegant, but is a small loop anyway
+        auto it = actions.begin();
+        size_t count = 0;
+        while (it != actions.end())
+        {
+            if (chosenAction == &*it)
+            {
+                action_callbacks[count]();
+                break;
+            }
+            ++it;
+            ++count;
+        }
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h
new file mode 100644
index 0000000000000000000000000000000000000000..510f68292b91bf9934dcecd4300d698e64d516b3
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetContextMenu.h
@@ -0,0 +1,67 @@
+#pragma once
+
+
+#include <QAction>
+
+#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>
+
+class QTreeWidget;
+class QPoint;
+
+namespace armarx
+{
+
+    class AronTreeWidgetItem;
+
+    // Visitor on aron types. It creates a  context menu dependent on the type of the AronTreeWidgetItem.
+    // Its only used for Lists and Dicts.
+    class AronTreeWidgetContextMenuVisitor : public armarx::aron::type::ConstVariantVisitor
+    {
+
+        AronTreeWidgetItem* parentItem;
+        QTreeWidget* contextMenuParent;
+        const QPoint& pos;
+        int index;
+
+    public:
+        AronTreeWidgetContextMenuVisitor() = delete;
+        AronTreeWidgetContextMenuVisitor(AronTreeWidgetItem* i,
+                                         const QPoint& pos,
+                                         QTreeWidget* contextMenuParent,
+                                         int x);
+
+        void visitAronVariant(const aron::type::ObjectPtr&) final;
+        void visitAronVariant(const aron::type::DictPtr&) final;
+        void visitAronVariant(const aron::type::PairPtr&) final;
+        void visitAronVariant(const aron::type::TuplePtr&) final;
+        void visitAronVariant(const aron::type::ListPtr&) final;
+        void visitAronVariant(const aron::type::NDArrayPtr&) final;
+        void visitAronVariant(const aron::type::MatrixPtr&) final;
+        void visitAronVariant(const aron::type::QuaternionPtr&) final;
+        void visitAronVariant(const aron::type::ImagePtr&) final;
+        void visitAronVariant(const aron::type::PointCloudPtr&) final;
+        void visitAronVariant(const aron::type::IntEnumPtr&) final;
+        void visitAronVariant(const aron::type::IntPtr&) final;
+        void visitAronVariant(const aron::type::LongPtr&) final;
+        void visitAronVariant(const aron::type::FloatPtr&) final;
+        void visitAronVariant(const aron::type::DoublePtr&) final;
+        void visitAronVariant(const aron::type::BoolPtr&) final;
+        void visitAronVariant(const aron::type::StringPtr&) final;
+        void visitUnknown(Input&) final;
+
+        void showMenuAndExecute();
+
+    private:
+        std::list<QAction> actions;
+        std::vector<std::function<void()>> action_callbacks;
+
+        // Creates a remove option if the element is a direct child of a list or dict
+        void addDeleteAction();
+        void executeDelete();
+
+        void addAddAction();
+        void executeAddElement();
+    };
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
index 7d78147bca4aa47088e8a605e7494f38b2ea5776..c0a8088db7b5ad4e4e1db955b42e9316164038b3 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp
@@ -26,16 +26,68 @@
 #include "AronTreeWidgetConverter.h"
 
 // armarx
+#include <SimoxUtility/algorithm/string.h>
+
 #include <ArmarXCore/core/logging/Logging.h>
 
+#include "RobotAPI/libraries/aron/core/data/variant/All.h"
+
 // qt
 #include <QTreeWidgetItem>
 
+#include "../widgets/EditMatrixWidget.h"
+#include "../widgets/IntEnumWidget.h"
+#include "../widgets/QuaternionWidget.h"
+
+
 namespace armarx
 {
+    bool
+    AronTreeWidgetConverterVisitor::isConversionSuccessful()
+    {
+        return !isDirectError && !hasTransitiveError;
+    }
+
+    bool
+    AronTreeWidgetConverterVisitor::onlyChildFailedConversion()
+    {
+        return hasTransitiveError;
+    }
+
+    bool
+    AronTreeWidgetConverterVisitor::hasDirectError() const
+    {
+        return isDirectError;
+    }
+
+    void
+    AronTreeWidgetConverterVisitor::handleErrors(AronTreeWidgetConverterVisitor childV,
+                                                 bool ownFault)
+    {
+        ARMARX_TRACE;
+        isDirectError |= ownFault;
+        hasTransitiveError |= childV.isDirectError || childV.hasTransitiveError;
+
+        auto* aronItem = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
+        ARMARX_CHECK(aronItem);
+        aronItem->setValueErrorState(isDirectError, hasTransitiveError);
+    }
+
+    void
+    AronTreeWidgetConverterVisitor::handleErrors(bool ownFault)
+    {
+        ARMARX_TRACE;
+        isDirectError = ownFault;
+        auto* aronItem = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
+        ARMARX_CHECK(aronItem);
+        aronItem->setValueErrorState(isDirectError, false);
+    }
+
+
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::ObjectPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronDict = std::make_shared<aron::data::Dict>(i->getPath());
         createdAron = createdAronDict;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -43,16 +95,22 @@ namespace armarx
         unsigned int x = 0;
         for (const auto& [key, value] : i->getMemberTypes())
         {
+            ARMARX_TRACE;
             AronTreeWidgetConverterVisitor v(el, x++);
             aron::type::visit(v, value);
 
-            createdAronDict->addElement(key, v.createdAron);
+            handleErrors(v);
+            if (v.isConversionSuccessful())
+            {
+                createdAronDict->addElement(key, v.createdAron);
+            }
         }
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::DictPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronDict = std::make_shared<aron::data::Dict>(i->getPath());
         createdAron = createdAronDict;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -62,38 +120,72 @@ namespace armarx
             auto it = el->child(x);
             AronTreeWidgetConverterVisitor v(el, x);
             aron::type::visit(v, i->getAcceptedType());
-
-            if (v.createdAron)
+            auto key = it->text(0).toStdString();
+            // TODO: handle key errors more elegantly / separately, fine for now
+            handleErrors(v, createdAronDict->hasElement(key));
+            if (v.createdAron && v.isConversionSuccessful() && !createdAronDict->hasElement(key))
             {
-                createdAronDict->addElement(it->text(0).toStdString(), v.createdAron);
+                createdAronDict->addElement(key, v.createdAron);
             }
         }
     }
 
     void
-    AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::PairPtr& i)
+    AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::ListPtr& i)
     {
-        // TODO
+        ARMARX_TRACE;
+        auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
+        createdAron = createdAronList;
+        auto* elem = parentItem->child(index);
+        auto childrenTypes = i->getChildren();
+        ARMARX_CHECK(childrenTypes.size() == 1);
+        for (int j = 0; j < elem->childCount(); ++j)
+        {
+            AronTreeWidgetConverterVisitor convVisitor(elem, j);
+            aron::type::visit(convVisitor, childrenTypes[0]);
+            handleErrors(convVisitor);
+
+            if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
+            {
+                createdAronList->addElement(convVisitor.createdAron);
+            }
+        }
     }
 
+
     void
-    AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::TuplePtr& i)
+    AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::PairPtr& i)
     {
-        // TODO
+        ARMARX_TRACE;
+        auto createdAronPair = std::make_shared<aron::data::List>(i->getPath());
+        createdAron = createdAronPair;
+        auto* elem = parentItem->child(index);
+
+        for (int j = 0; j < 2; ++j)
+        {
+            AronTreeWidgetConverterVisitor convVisitor(elem, j);
+            handleErrors(convVisitor);
+            if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
+            {
+                createdAronPair->addElement(convVisitor.createdAron);
+            }
+        }
     }
 
     void
-    AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::ListPtr& i)
+    AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::TuplePtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
         createdAron = createdAronList;
         QTreeWidgetItem* el = parentItem->child(index);
 
         for (int x = 0; x < el->childCount(); ++x)
         {
-            auto it = el->child(x);
-            AronTreeWidgetConverterVisitor v(el, x);
-            aron::type::visit(v, i->getAcceptedType());
+            auto* it = el->child(x);
+            AronTreeWidgetConverterVisitor v(it, x);
+            aron::type::visit(v, i->getAcceptedType(x));
+            handleErrors(v);
 
             if (v.createdAron)
             {
@@ -105,42 +197,129 @@ namespace armarx
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::NDArrayPtr& i)
     {
-        // TODO
+        ARMARX_TRACE;
+        ARMARX_ERROR << "Currently do not support supplying raw NDArrays!";
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::MatrixPtr& i)
     {
-        // TODO
+        ARMARX_TRACE;
+        auto createdMatrix = std::make_shared<aron::data::NDArray>(i->getPath());
+        int dataSize = 0;
+        switch (i->getElementType())
+        {
+            case armarx::aron::type::matrix::INT16:
+                dataSize = 2;
+                break;
+            case armarx::aron::type::matrix::INT32:
+            case armarx::aron::type::matrix::FLOAT32:
+                dataSize = 4;
+                break;
+            case armarx::aron::type::matrix::FLOAT64:
+            case armarx::aron::type::matrix::INT64:
+                dataSize = 8;
+                break;
+        };
+        createdMatrix->setShape({i->getRows(), i->getCols(), dataSize});
+        createdMatrix->setType(i->getFullName());
+        int totalByteSize = i->getRows() * i->getCols() * dataSize;
+        createdAron = createdMatrix;
+
+        auto* currElem = parentItem->child(index);
+        auto* rootWidget = currElem->treeWidget();
+        ARMARX_CHECK(rootWidget);
+        auto* widget = rootWidget->itemWidget(currElem, 1);
+        auto* matrixWidget = EditMatrixWidget::DynamicCastAndCheck(widget);
+
+        handleErrors(matrixWidget->hasParseErrors());
+        if (matrixWidget->hasParseErrors())
+        {
+            return;
+        }
+        // write to aron data
+        std::vector<unsigned char> elems;
+        elems.reserve(totalByteSize);
+        // CAUTION: Raw data has column based storage
+        for (size_t col = 0; col < (size_t)i->getCols(); ++col)
+        {
+            for (size_t row = 0; row < (size_t)i->getRows(); ++row)
+            {
+                // gets us directly the byte wise format
+                auto parsed = matrixWidget->parseElement(row, col);
+                // append vector to vector
+                elems.insert(elems.end(), parsed.begin(), parsed.end());
+            }
+        }
+        createdMatrix->setData(totalByteSize, elems.data());
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::QuaternionPtr& i)
     {
-        // TODO
+        ARMARX_TRACE;
+        auto createdQuat = std::make_shared<aron::data::NDArray>(i->getPath());
+        createdAron = createdQuat;
+        int dataSize = i->getElementType() == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8;
+        createdQuat->setShape({1, 4, dataSize});
+        createdQuat->setType(i->getFullName());
+        auto* currTreeElem = parentItem->child(index);
+        auto* itemWidget = currTreeElem->treeWidget()->itemWidget(currTreeElem, 1);
+        auto* quatWidget = QuaternionWidget::DynamicCastAndCheck(itemWidget);
+
+        // error handling
+        handleErrors(quatWidget->hasParseErrors());
+        if (quatWidget->hasParseErrors())
+        {
+            return;
+        }
+
+        // write to aron data
+        auto serialized = quatWidget->parseAllToNDArray();
+        if ((int)serialized.size() != dataSize * 4)
+        {
+            ARMARX_ERROR
+                << "serialized quaternions did not return byte sequence of correct length!";
+        }
+        createdQuat->setData(serialized.size(), serialized.data());
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::ImagePtr& i)
     {
+        ARMARX_TRACE;
         // TODO
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::PointCloudPtr& i)
     {
+        ARMARX_TRACE;
         // TODO
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::IntEnumPtr& i)
     {
-        // TODO
+        ARMARX_TRACE;
+        QTreeWidgetItem* el = parentItem->child(index);
+        auto* genericWidget = el->treeWidget()->itemWidget(el, 1);
+        auto* intEnumWidget = IntEnumWidget::DynamicCastAndCheck(genericWidget);
+        if (!intEnumWidget)
+        {
+            // already reporting error; continue here
+            return;
+        }
+        bool success;
+        std::tie(success, createdAron) = intEnumWidget->parseToAron();
+
+        handleErrors(!success);
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::IntPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronInt = std::make_shared<aron::data::Int>(i->getPath());
         createdAron = createdAronInt;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -151,14 +330,25 @@ namespace armarx
             createdAronInt->setValue(0);
             return;
         }
-
-        int val = std::stoi(str);
-        createdAronInt->setValue(val);
+        try
+        {
+            int val = simox::alg::to_<int>(str);
+            createdAronInt->setValue(val);
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            handleErrors();
+            ARMARX_VERBOSE << "Conversion from String to Int failed. Error:\"" << err.what()
+                           << "\"";
+            return;
+        }
+        handleErrors(false);
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::LongPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronLong = std::make_shared<aron::data::Long>(i->getPath());
         createdAron = createdAronLong;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -166,15 +356,27 @@ namespace armarx
         std::string str = el->text(1).toStdString();
         if (str.empty())
         {
+            //TODO: similar behaviour for rest?
             str = el->text(3).toStdString();
         }
-
-        createdAronLong->fromString(str);
+        try
+        {
+            createdAronLong->setValue(simox::alg::to_<long>(str));
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            handleErrors();
+            ARMARX_VERBOSE << "Conversion from String to Long failed. Error:\"" << err.what()
+                           << "\"";
+            return;
+        }
+        handleErrors(false);
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::FloatPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronFloat = std::make_shared<aron::data::Float>(i->getPath());
         createdAron = createdAronFloat;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -184,13 +386,24 @@ namespace armarx
         {
             str = el->text(3).toStdString();
         }
-
-        createdAronFloat->fromString(str);
+        try
+        {
+            createdAronFloat->setValue(simox::alg::to_<float>(str));
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            handleErrors();
+            ARMARX_VERBOSE << "Conversion from String to Float failed. Error:\"" << err.what()
+                           << "\"";
+            return;
+        }
+        handleErrors(false);
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::DoublePtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronDouble = std::make_shared<aron::data::Double>(i->getPath());
         createdAron = createdAronDouble;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -200,13 +413,24 @@ namespace armarx
         {
             str = el->text(3).toStdString();
         }
-
-        createdAronDouble->fromString(str);
+        try
+        {
+            createdAronDouble->setValue(simox::alg::to_<double>(str));
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            handleErrors();
+            ARMARX_VERBOSE << "Conversion from String to Double failed. Error:\"" << err.what()
+                           << "\"";
+            return;
+        }
+        handleErrors(false);
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::BoolPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronBool = std::make_shared<aron::data::Bool>(i->getPath());
         createdAron = createdAronBool;
         QTreeWidgetItem* el = parentItem->child(index);
@@ -216,24 +440,36 @@ namespace armarx
         {
             str = el->text(3).toStdString();
         }
-
-        createdAronBool->fromString(str);
+        try
+        {
+            createdAronBool->setValue(simox::alg::to_<bool>(str));
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            handleErrors();
+            ARMARX_VERBOSE << "Conversion from String to Bool failed. Error:\"" << err.what()
+                           << "\"";
+            return;
+        }
+        handleErrors(false);
     }
 
     void
     AronTreeWidgetConverterVisitor::visitAronVariant(const aron::type::StringPtr& i)
     {
+        ARMARX_TRACE;
         auto createdAronString = std::make_shared<aron::data::String>(i->getPath());
         createdAron = createdAronString;
         QTreeWidgetItem* el = parentItem->child(index);
 
         std::string str = el->text(1).toStdString();
-        createdAronString->fromString(str);
+        createdAronString->setValue(str);
     }
 
-    void AronTreeWidgetConverterVisitor::visitUnknown(Input&)
+    void
+    AronTreeWidgetConverterVisitor::visitUnknown(Input&)
     {
-        ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type to an aron data object.";
+        ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type "
+                            "to an aron data object.";
     }
-}
-
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.h
index eb056cdc2a65f14ef4d884124d6cb14ac2e9ed7e..c127ac5e49276e878221dc39a5db8a7b821ccec7 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.h
@@ -21,8 +21,8 @@
  */
 #pragma once
 
-#include <RobotAPI/libraries/aron/core/type/variant/All.h>
 #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>
 
 // forward declarations of qt
@@ -32,8 +32,7 @@ class QTreeWidgetItem;
 namespace armarx
 {
     // Conversion from TreeView to aron data
-    class AronTreeWidgetConverterVisitor :
-            public armarx::aron::type::ConstVariantVisitor
+    class AronTreeWidgetConverterVisitor : public armarx::aron::type::ConstVariantVisitor
     {
     public:
         QTreeWidgetItem* parentItem;
@@ -41,10 +40,27 @@ namespace armarx
         aron::data::VariantPtr createdAron = nullptr;
 
         AronTreeWidgetConverterVisitor() = delete;
-        AronTreeWidgetConverterVisitor(QTreeWidgetItem* i, int x) :
-            parentItem(i), index(x)
-        {}
+        AronTreeWidgetConverterVisitor(QTreeWidgetItem* i, int x) : parentItem(i), index(x)
+        {
+        }
+        // if the conversion was successful after calling visit()
+        bool isConversionSuccessful();
+        // returns true if this type itself was sucessfully parsed, but some contained object failed.
+        // also false if there is no error
+        bool onlyChildFailedConversion();
+
+        bool hasDirectError() const;
+
+    private:
+        bool isDirectError = false;
+        bool hasTransitiveError = false;
+        // adds all errors from other visitor to our own error collection -> collecting errors
+        // with ownFault, we also add this node to the collection
+        void handleErrors(AronTreeWidgetConverterVisitor childV, bool ownFault = false);
+        // we are the cause...
+        void handleErrors(bool ownFault = true);
 
+    public:
         void visitAronVariant(const aron::type::ObjectPtr&) final;
         void visitAronVariant(const aron::type::DictPtr&) final;
         void visitAronVariant(const aron::type::PairPtr&) final;
@@ -64,6 +80,4 @@ namespace armarx
         void visitAronVariant(const aron::type::StringPtr&) final;
         void visitUnknown(Input&) final;
     };
-}
-
-
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp
index ee43334bb26862322610746269fee97a16d0cccd..84cb58585e3b4e7f3a058db66f3b5f3a40f54aea 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp
@@ -22,28 +22,98 @@
 
 #include <string>
 
+#include "../widgets/EditMatrixWidget.h"
+#include "../widgets/IntEnumWidget.h"
+#include "../widgets/QuaternionWidget.h"
+
 // base class
 #include "AronTreeWidgetCreator.h"
 
 // data
+#include <QComboBox>
+
 #include "../AronTreeWidgetItem.h"
 #include "../Data.h"
+#include "../ListDictHelper.h"
+#include "AronTreeWidgetContextMenu.h"
 
 namespace armarx
 {
+
+    AronTreeWidgetCreatorVisitor::AronTreeWidgetCreatorVisitor(QTreeWidgetItem* parentInstance) :
+        parentOfCreatedObj(parentInstance)
+    {
+        // The parent of the root aron Tree Widget will not be aron type.
+        // there an explicit setTopLevelWidget() is required.
+        auto* aronParent = AronTreeWidgetItem::DynamicCast(parentInstance);
+        if (aronParent)
+        {
+            toplevelWidget = aronParent->treeWidget();
+        }
+    }
+
+    std::string
+    AronTreeWidgetCreatorVisitor::generateUniqueKeyFromSet(std::set<std::string>&& usedKeys)
+    {
+        size_t num = 0;
+        while (true)
+        {
+            std::string proposedName = this->defaultMapKeyName + std::to_string(num);
+            auto it = usedKeys.find(proposedName);
+            if (it == usedKeys.end())
+            {
+                break;
+            }
+            ++num;
+        }
+        return this->defaultMapKeyName + std::to_string(num);
+    }
+
     void
-    AronTreeWidgetCreatorVisitor::createSimpleTreeViewWidget(Input& i, const std::string& defaul)
+    AronTreeWidgetCreatorVisitor::insertNewTreeViewWidget(Input& i, const std::string& defaul)
     {
         ARMARX_CHECK_NOT_NULL(i);
 
         auto key = i->getPath().getLastElement();
-        createdQWidgetItem = new AronTreeWidgetItem();
-        createdQWidgetItem->aronType = i;
-        createdQWidgetItem->setText(0, QString::fromStdString(key));
+        bool isDictChild = false;
+        // edit key, to be a unique string, if the parent is a dict
+        auto* aronParent = AronTreeWidgetItem::DynamicCast(parentOfCreatedObj);
+        if (aronParent && aronParent->aronType->getDescriptor() == aron::type::Descriptor::DICT)
+        {
+            isDictChild = true;
+            std::set<std::string> usedKeys;
+            for (int i = 0; i < parentOfCreatedObj->childCount(); ++i)
+            {
+                auto* sibling = AronTreeWidgetItem::DynamicCast(parentOfCreatedObj->child(i));
+                if (sibling)
+                {
+                    usedKeys.insert(sibling->text(0).toStdString());
+                }
+            }
+            key = generateUniqueKeyFromSet(std::move(usedKeys));
+        }
+        // if it's a list -> choose the right number
+        else if (aronParent &&
+                 aronParent->aronType->getDescriptor() == aron::type::Descriptor::LIST)
+        {
+            key = std::to_string(parentOfCreatedObj->childCount());
+        }
+
+        createdQWidgetItem =
+            new AronTreeWidgetItem(isDictChild, editableValue, QString::fromStdString(key), i);
         createdQWidgetItem->setText(1, QString::fromStdString(defaul));
         createdQWidgetItem->setText(2, QString::fromStdString(i->getShortName()));
-        createdQWidgetItem->setText(3, QString::fromStdString(aron_tree_widget::constantes::ITEM_EMPTY_MESSAGE) /*QString::fromStdString(i->getDefaultFromString())*/);
-        createdQWidgetItem->setFlags(createdQWidgetItem->flags() | Qt::ItemIsEditable);
+        createdQWidgetItem->setText(
+            3,
+            QString::fromStdString(
+                aron_tree_widget::constantes::
+                    ITEM_EMPTY_MESSAGE) /*QString::fromStdString(i->getDefaultFromString())*/);
+
+        if (editableValue || isDictChild)
+        {
+            createdQWidgetItem->setFlags(createdQWidgetItem->flags() | Qt::ItemIsEditable);
+        }
+        parentOfCreatedObj->addChild(createdQWidgetItem);
     }
 
     void
@@ -57,73 +127,203 @@ namespace armarx
             key = i->getPath().getLastElement();
         }
 
-        createdQWidgetItem = new AronTreeWidgetItem();
-        createdQWidgetItem->setText(0, QString::fromStdString(key));
+        createdQWidgetItem =
+            new AronTreeWidgetItem(editableValue, false, QString::fromStdString(key), i);
+        parentOfCreatedObj->addChild(createdQWidgetItem);
 
         for (const auto& [key, value] : i->getMemberTypes())
         {
-            AronTreeWidgetCreatorVisitor v;
+            AronTreeWidgetCreatorVisitor v(createdQWidgetItem);
             aron::type::visit(v, value);
 
-            if (v.createdQWidgetItem)
-            {
-                createdQWidgetItem->addChild(v.createdQWidgetItem);
-            }
+            assert(v.createdQWidgetItem);
         }
     }
 
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::DictPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        ARMARX_CHECK_NOT_NULL(i);
+
+        insertNewTreeViewWidget(i, "");
+        // The DictType has only one member, its key-type. This also must be present
+        ARMARX_CHECK_EQUAL(i->getChildren().size(), 1);
+    }
     void
-    AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PairPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PairPtr& pair)
+    {
+        // create default, uneditable tree widget item.
+        insertNewTreeViewWidget(pair, "");
+        // attach two children
+        ARMARX_CHECK(pair->getChildren().size() == 2);
+        for (size_t i = 0; i < 2; ++i)
+        {
+            AronTreeWidgetCreatorVisitor v(createdQWidgetItem);
+            aron::type::visit(v, pair->getChildren()[i]);
+            if (v.createdQWidgetItem)
+            {
+                std::string descr = "p[" + std::to_string(i) + "]";
+                v.createdQWidgetItem->setText(0, descr.c_str());
+            }
+        }
+    }
     void
-    AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& tuple)
+    {
+        // CAUTION; UNTESTED
+        // create default, uneditable tree widget item.
+        insertNewTreeViewWidget(tuple, "");
+        // attach all children
+        for (size_t i = 0; i < tuple->getChildren().size(); ++i)
+        {
+            AronTreeWidgetCreatorVisitor v(createdQWidgetItem);
+            aron::type::visit(v, tuple->getChildren()[i]);
+            if (v.createdQWidgetItem)
+            {
+                std::string descr = "tup[" + std::to_string(i) + "]";
+                v.createdQWidgetItem->setText(0, descr.c_str());
+            }
+        }
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::ListPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        insertNewTreeViewWidget(i, "");
+        auto txt = misc::generateNumElementsText(0);
+        createdQWidgetItem->setText(1, txt);
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::NDArrayPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        insertNewTreeViewWidget(i, "");
+    }
+
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::MatrixPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        editableValue = false;
+        insertNewTreeViewWidget(i, "");
+        // special code to print the type of base type used
+        QString type = "";
+        switch (i->getElementType())
+        {
+            case armarx::aron::type::matrix::INT16:
+                type = "<int16>";
+                break;
+            case armarx::aron::type::matrix::INT32:
+                type = "<int32>";
+                break;
+            case armarx::aron::type::matrix::INT64:
+                type = "<int64>";
+                break;
+            case armarx::aron::type::matrix::FLOAT32:
+                type = "<float>";
+                break;
+            case armarx::aron::type::matrix::FLOAT64:
+                type = "<double>";
+                break;
+        }
+        type = createdQWidgetItem->text(2) + type;
+        createdQWidgetItem->setText(2, type);
+
+        // Widget fiddling source: https://blog.manash.io/quick-qt-6-how-to-add-qpushbutton-or-widgets-to-a-qtreewidget-as-qtreewidgetitem-2ae9f54c0e5f
+        // overlay custom widget in column 1
+        auto* toplevelWidget = createdQWidgetItem->treeWidget();
+        EditMatrixWidget* matWidget = new EditMatrixWidget(
+            i->getRows(), i->getCols(), i->getElementType(), createdQWidgetItem);
+        toplevelWidget->setItemWidget(createdQWidgetItem, 1, matWidget);
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::QuaternionPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        editableValue = false;
+        insertNewTreeViewWidget(i, "");
+        // special code to print the type of base type used
+        QString type = "";
+        switch (i->getElementType())
+        {
+            case armarx::aron::type::quaternion::FLOAT32:
+                type = "<float>";
+                break;
+            case armarx::aron::type::quaternion::FLOAT64:
+                type = "<double>";
+                break;
+        }
+        type = createdQWidgetItem->text(2) + type;
+        createdQWidgetItem->setText(2, type);
+
+        auto* toplevelWidget = createdQWidgetItem->treeWidget();
+        QuaternionWidget* quatWidget =
+            new QuaternionWidget(i->getElementType(), createdQWidgetItem);
+        toplevelWidget->setItemWidget(createdQWidgetItem, 1, quatWidget);
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::ImagePtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        insertNewTreeViewWidget(i, "");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PointCloudPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        insertNewTreeViewWidget(i, "");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::IntEnumPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        editableValue = false;
+        ARMARX_CHECK_NOT_NULL(i);
+        ARMARX_CHECK_GREATER(i->getAcceptedValueNames().size(), 0);
+
+        insertNewTreeViewWidget(i, "");
+        IntEnumWidget* widget = new IntEnumWidget(i, createdQWidgetItem);
+        createdQWidgetItem->treeWidget()->setItemWidget(createdQWidgetItem, 1, widget);
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::IntPtr& i)
-    { createSimpleTreeViewWidget(i, "0"); }
+    {
+        editableValue = true;
+        insertNewTreeViewWidget(i, "0");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::LongPtr& i)
-    { createSimpleTreeViewWidget(i, "0"); }
+    {
+        editableValue = true;
+        insertNewTreeViewWidget(i, "0");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::FloatPtr& i)
-    { createSimpleTreeViewWidget(i, "0.0"); }
+    {
+        editableValue = true;
+        insertNewTreeViewWidget(i, "0.0");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::DoublePtr& i)
-    { createSimpleTreeViewWidget(i, "0.0"); }
+    {
+        editableValue = true;
+        insertNewTreeViewWidget(i, "0.0");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::BoolPtr& i)
-    { createSimpleTreeViewWidget(i, "false"); }
+    {
+        editableValue = true;
+        insertNewTreeViewWidget(i, "false");
+    }
     void
     AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::StringPtr& i)
-    { createSimpleTreeViewWidget(i, ""); }
+    {
+        insertNewTreeViewWidget(i, "");
+    }
 
-    void AronTreeWidgetCreatorVisitor::visitUnknown(Input&)
+    void
+    AronTreeWidgetCreatorVisitor::visitUnknown(Input&)
     {
-        ARMARX_WARNING_S << "Received an unknown type when trying to create a tree view widget for a skill argument type.";
+        ARMARX_WARNING_S << "Received an unknown type when trying to create a tree view widget for "
+                            "a skill argument type.";
     }
-}
 
+    void
+    AronTreeWidgetCreatorVisitor::setTopLevelWidget(QTreeWidget* widget)
+    {
+        toplevelWidget = widget;
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.h
index 63dde7ef0be04d8d790c5f8434ae1b82faeb107a..b3d2ffb54cca6bf7fe8aac2395d733f3ba458817 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.h
@@ -21,8 +21,10 @@
  */
 #pragma once
 
-#include <RobotAPI/libraries/aron/core/type/variant/All.h>
+#include <QTreeWidgetItem>
+
 #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>
 
 namespace armarx
@@ -30,15 +32,20 @@ namespace armarx
     class AronTreeWidgetItem;
 
     // Convert aron type to tree widgets
-    class AronTreeWidgetCreatorVisitor :
-            public armarx::aron::type::ConstVariantVisitor
+    class AronTreeWidgetCreatorVisitor : public armarx::aron::type::ConstVariantVisitor
     {
     public:
-        AronTreeWidgetItem* createdQWidgetItem;
+        AronTreeWidgetItem* createdQWidgetItem = nullptr;
+
+        AronTreeWidgetCreatorVisitor() = delete;
 
-        AronTreeWidgetCreatorVisitor() = default;
+        // Takes the parent tree element and attaches the newly crated object during visit() to it.
+        // This allows us to also use information of the parent object during creation (like if this child is a dict entry or part of a list)
+        // IMPORTANT: For the root element, manually set the topLevelWidget after this constructor
+        AronTreeWidgetCreatorVisitor(QTreeWidgetItem* parentInstance);
+
+        void insertNewTreeViewWidget(Input& i, const std::string&);
 
-        void createSimpleTreeViewWidget(Input& i, const std::string&);
 
         void visitAronVariant(const aron::type::ObjectPtr&) final;
         void visitAronVariant(const aron::type::DictPtr& i) final;
@@ -58,7 +65,17 @@ namespace armarx
         void visitAronVariant(const aron::type::BoolPtr& i) final;
         void visitAronVariant(const aron::type::StringPtr& i) final;
         void visitUnknown(Input&) final;
-    };
-}
 
+        // setter for the widget attachment point. Only needs to be manually set for the root element.
+        void setTopLevelWidget(QTreeWidget* widget);
 
+    private:
+        void handleEditable();
+        std::string generateUniqueKeyFromSet(std::set<std::string>&& usedKeys);
+        QTreeWidgetItem* parentOfCreatedObj = nullptr;
+        QTreeWidget* toplevelWidget = nullptr;
+        const std::string defaultMapKeyName = "key_";
+        // controls, if values (column 1) can be edited directly
+        bool editableValue = false;
+    };
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp
index 7ff248bd58499028bcf43a158f83f67c1259b43c..fc58634bb9bc02834d4e72663e3c16ffe36d6de6 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp
@@ -28,7 +28,7 @@
 
 // modals
 #include "../modal/text/AronTreeWidgetTextInputModalController.h"
-#include "../modal/dict/AronTreeWidgetDictInputModalController.h"
+//#include "../modal/dict/AronTreeWidgetDictInputModalController.h"
 
 // qt
 #include <QTreeWidget>
@@ -37,84 +37,6 @@
 namespace armarx
 {
 
-    void AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::ObjectPtr& i)
-    {
-        // should not happen, right?
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::DictPtr& i)
-    {
-        createdModal = std::make_shared<AronTreeWidgetDictInputModalController>(label, item, parent);
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::PairPtr& i)
-    {
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::ListPtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::NDArrayPtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::MatrixPtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::QuaternionPtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::ImagePtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::PointCloudPtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::IntEnumPtr& i)
-    { }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::IntPtr& i)
-    {
-        createdModal = std::make_shared<AronTreeWidgetTextInputModalController>(label, item, parent);
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::LongPtr& i)
-    {
-        createdModal = std::make_shared<AronTreeWidgetTextInputModalController>(label, item, parent);
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::FloatPtr& i)
-    {
-        createdModal = std::make_shared<AronTreeWidgetTextInputModalController>(label, item, parent);
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::DoublePtr& i)
-    {
-        createdModal = std::make_shared<AronTreeWidgetTextInputModalController>(label, item, parent);
-    }
-
-    void
-    AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::BoolPtr& i)
-    {
-        createdModal = std::make_shared<AronTreeWidgetTextInputModalController>(label, item, parent);
-    }
-
     void
     AronTreeWidgetModalCreatorVisitor::visitAronVariant(const aron::type::StringPtr& i)
     {
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.h
index e22930a1080977d0feb6475c72a3b6c848d5d8e5..f4c8f0223a039c6b9be926d6bddf360bce32f629 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.h
@@ -29,15 +29,17 @@
 
 namespace armarx
 {
-    // Convert aron type to tree widget
+    // Convert aron type to tree widget.
+    // (Widgets are only created for string types to enter longer texts.
+    // However, the visitor implementation allows modals for differnt types. Might be useful in the future..)
     class AronTreeWidgetModalCreatorVisitor :
             public armarx::aron::type::ConstVariantVisitor
     {
     public:
-        std::string label;
-        AronTreeWidgetItem* item;
-        QTreeWidget* parent;
-        AronTreeWidgetModalControllerPtr createdModal;
+        std::string label = "";
+        AronTreeWidgetItem* item = nullptr;
+        QTreeWidget* parent = nullptr;
+        AronTreeWidgetModalControllerPtr createdModal = nullptr;
 
         AronTreeWidgetModalCreatorVisitor() = delete;
         AronTreeWidgetModalCreatorVisitor(const std::string& label, AronTreeWidgetItem* item, QTreeWidget* parent) :
@@ -46,22 +48,6 @@ namespace armarx
             parent(parent)
         {}
 
-        void visitAronVariant(const aron::type::ObjectPtr&) final;
-        void visitAronVariant(const aron::type::DictPtr& i) final;
-        void visitAronVariant(const aron::type::PairPtr& i) final;
-        void visitAronVariant(const aron::type::TuplePtr& i) final;
-        void visitAronVariant(const aron::type::ListPtr& i) final;
-        void visitAronVariant(const aron::type::NDArrayPtr& i) final;
-        void visitAronVariant(const aron::type::MatrixPtr& i) final;
-        void visitAronVariant(const aron::type::QuaternionPtr& i) final;
-        void visitAronVariant(const aron::type::ImagePtr& i) final;
-        void visitAronVariant(const aron::type::PointCloudPtr& i) final;
-        void visitAronVariant(const aron::type::IntEnumPtr& i) final;
-        void visitAronVariant(const aron::type::IntPtr& i) final;
-        void visitAronVariant(const aron::type::LongPtr& i) final;
-        void visitAronVariant(const aron::type::FloatPtr& i) final;
-        void visitAronVariant(const aron::type::DoublePtr& i) final;
-        void visitAronVariant(const aron::type::BoolPtr& i) final;
         void visitAronVariant(const aron::type::StringPtr& i) final;
         void visitUnknown(Input&) final;
     };
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
index 87d99fe162344661a0511f49563c5d601342fe11..cf719f8a2d1360d574fb8ebcac867378c3fd6f1b 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp
@@ -20,34 +20,106 @@
  *             GNU General Public License
  */
 
+#include "AronTreeWidgetSetter.h"
+
 #include <string>
 
-#include "AronTreeWidgetSetter.h"
+#include "../ListDictHelper.h"
+#include "../widgets/EditMatrixWidget.h"
+#include "../widgets/IntEnumWidget.h"
+#include "../widgets/QuaternionWidget.h"
+#include "AronTreeWidgetContextMenu.h"
+#include "AronTreeWidgetCreator.h"
+
+
+template <typename T>
+std::string
+usString(T number, size_t precision = 3)
+{
+    std::stringstream ss;
+    const char* locale = "C";
+    ss.imbue(std::locale(locale));
+
+    ss << std::fixed << std::setprecision(precision) << number;
+    return ss.str();
+}
+
 
 //visitors
 namespace armarx
 {
-    bool AronTreeWidgetSetterVisitor::checkTreeWidgetItemForSimilarName(const std::string& name) const
+    bool
+    AronTreeWidgetSetterVisitor::checkTreeWidgetItemForSimilarName(const std::string& name) const
     {
         QTreeWidgetItem* el = parentItem->child(index);
+
+        // do not check attribute name, if the element is part of a list or map
+        auto* castedThis = AronTreeWidgetItem::DynamicCast(el->parent());
+        if (castedThis)
+        {
+            auto descr = castedThis->aronType->getDescriptor();
+            if (descr == aron::type::Descriptor::LIST || descr == aron::type::Descriptor::DICT)
+            {
+                return true;
+            }
+        }
         std::string n = el->text(0).toStdString();
         if (name != n)
         {
-            ARMARX_WARNING_S << "Could not set a tree widget value for the element with key '" << name << "' because it is different from the expected name '" << n << "'.";
+            ARMARX_WARNING_S << "Could not set a tree widget value for the element with key '"
+                             << name << "' because it is different from the expected name '" << n
+                             << "'.";
             return false;
         }
         return true;
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::DictPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::adjustNumberOfChildren(AronTreeWidgetItem* parent,
+                                                        size_t numChildren)
+    {
+        if (((size_t)parent->childCount()) < numChildren)
+        {
+            // The type to create must be the only child of the current aron type
+            ARMARX_CHECK_EQUAL(parent->aronType->childrenSize(), 1);
+            size_t childrenToAdd = numChildren - parent->childCount();
+            for (size_t j = 0; j < childrenToAdd; ++j)
+            {
+                AronTreeWidgetCreatorVisitor childCreator(parent);
+                aron::type::visit(childCreator, parent->aronType->getChildren()[0]);
+                ARMARX_CHECK_NOT_NULL(childCreator.createdQWidgetItem);
+            }
+        }
+        else if ((size_t)parent->childCount() > numChildren)
+        {
+            size_t numChilds = (size_t)parent->childCount() - numChildren;
+            // pop the last child
+            for (size_t j = 0; j < numChilds; ++j)
+            {
+                parent->removeChild(parent->child(parent->childCount() - 1));
+            }
+        }
+    }
+
+
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::DictPtr& i)
     {
-        if (i->getPath().size() == 0 || checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) // either it is the root or it has a name
+        // either it is the root or it has a name
+        if (i->getPath().size() == 0 ||
+            checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
+            auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
+            // allocate enough child items
+            adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
 
+            // write child values
             unsigned int x = 0;
             for (const auto& [key, value] : i->getElements())
             {
+                el->child(x)->setText(0, {key.c_str()});
+
                 AronTreeWidgetSetterVisitor v(el, x++);
                 aron::data::visit(v, value);
             }
@@ -55,72 +127,224 @@ namespace armarx
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::ListPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::ListPtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
+            auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el);
+            adjustNumberOfChildren(aronTreeWidget, i->childrenSize());
 
             unsigned int x = 0;
             for (const auto& value : i->getElements())
             {
-                AronTreeWidgetSetterVisitor v(el, x++);
+                AronTreeWidgetSetterVisitor v(el, x);
                 aron::data::visit(v, value);
+                auto* currChild = el->child(x);
+                std::string listNum = usString(x);
+                currChild->setText(0, listNum.c_str());
+
+                ++x;
+            }
+            // This displays the number of children also when the list is collapsed
+            QString numElemsText = misc::generateNumElementsText(i->getElements().size());
+            aronTreeWidget->setText(1, numElemsText);
+            // set italic
+            auto currFont = aronTreeWidget->font(1);
+            currFont.setItalic(true);
+            aronTreeWidget->setFont(1, currFont);
+        }
+    }
+
+
+    void
+    visitMatrix(EditMatrixWidget* matrixWidget,
+                const std::shared_ptr<armarx::aron::type::Matrix>& matrixType,
+                const aron::data::NDArrayPtr& arr)
+    {
+        auto elemType = matrixType->getElementType();
+        auto* rawData = arr->getData();
+        // string can convert any item
+        auto toString = [elemType, rawData](size_t elementNr) -> std::string
+        {
+            switch (elemType)
+            {
+                case aron::type::matrix::ElementType::FLOAT32:
+                {
+                    static_assert(sizeof(float) == 4);
+                    float* interpreted = reinterpret_cast<float*>(rawData);
+                    float laundered = std::launder(interpreted)[elementNr];
+                    return usString<float>(laundered);
+                }
+                case aron::type::matrix::ElementType::FLOAT64:
+                {
+                    static_assert(sizeof(double) == 8);
+                    double* interpreted = reinterpret_cast<double*>(rawData);
+                    float laundered = std::launder(interpreted)[elementNr];
+                    return usString<double>(laundered);
+                }
+                case aron::type::matrix::ElementType::INT16:
+                {
+                    int16_t* interpreted = reinterpret_cast<int16_t*>(rawData);
+                    int16_t laudered = std::launder(interpreted)[elementNr];
+                    return usString<int16_t>(laudered);
+                }
+                case aron::type::matrix::ElementType::INT32:
+                {
+                    int32_t* interpreted = reinterpret_cast<int32_t*>(rawData);
+                    int32_t laudered = std::launder(interpreted)[elementNr];
+                    return usString<int32_t>(laudered);
+                }
+                case aron::type::matrix::ElementType::INT64:
+                {
+                    int64_t* interpreted = reinterpret_cast<int64_t*>(rawData);
+                    int64_t laudered = std::launder(interpreted)[elementNr];
+                    return usString<int64_t>(laudered);
+                }
+            }
+            return "Error!";
+        };
+
+
+        for (size_t row = 0; (int)row < matrixType->getRows(); ++row)
+        {
+            for (size_t col = 0; (int)col < matrixType->getCols(); ++col)
+            {
+                matrixWidget->setText(row, col, toString(col * matrixType->getRows() + row));
+            }
+        }
+    }
+    void
+    visitQuaternion(QuaternionWidget* quatWidget,
+                    std::shared_ptr<armarx::aron::type::Quaternion>& quatType,
+                    const aron::data::NDArrayPtr& arr)
+    {
+        auto elemType = quatType->getElementType();
+        auto rawData = arr->getData();
+        auto shape = arr->getShape();
+        // string can convert any item
+        auto toString = [elemType, rawData](size_t elementNr) -> std::string
+        {
+            switch (elemType)
+            {
+                case aron::type::quaternion::ElementType::FLOAT32:
+                {
+                    static_assert(sizeof(float) == 4);
+                    float* interpreted = reinterpret_cast<float*>(rawData);
+                    float laundered = std::launder(interpreted)[elementNr];
+                    return usString<float>(laundered);
+                }
+                case aron::type::quaternion::ElementType::FLOAT64:
+                {
+                    static_assert(sizeof(double) == 8);
+                    double* interpreted = reinterpret_cast<double*>(rawData);
+
+                    float laundered = std::launder(interpreted)[elementNr];
+                    return usString<double>(laundered);
+                }
             }
+            return "Error!";
+        };
+        for (size_t i = 0; i < 4; ++i)
+        {
+            quatWidget->setText((QuaternionWidget::QuaternionComponents)i, toString(i));
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::NDArrayPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::NDArrayPtr& arr)
     {
+        // Matrices are handled as NDArray. Raw ndarrays cannot be created currently
+        auto* castedEl = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
+        ARMARX_CHECK(castedEl);
+
+        auto matrixCast = aron::type::Matrix::DynamicCast(castedEl->aronType);
+        auto quaternionCast = aron::type::Quaternion::DynamicCast(castedEl->aronType);
+
+        auto* rootWidget = castedEl->treeWidget();
+        ARMARX_CHECK(rootWidget);
+        auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(castedEl, 1));
+        auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(castedEl, 1));
 
+        if (matrixCast && matrixWidget)
+        {
+            visitMatrix(matrixWidget, matrixCast, arr);
+        }
+        else if (quaternionCast && quaternionWidget)
+        {
+            visitQuaternion(quaternionWidget, quaternionCast, arr);
+        }
+        else
+        {
+            ARMARX_ERROR
+                << "we do not support raw NDArrays. Ask Fabian Peller for more information.";
+        }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::IntPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::IntPtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
-            el->setText(1, QString::fromStdString(std::to_string(i->getValue())));
+            auto* enumWidget = IntEnumWidget::DynamicCast(el->treeWidget()->itemWidget(el, 1));
+            auto newText = QString::fromStdString(usString<int>(i->getValue()));
+            if (enumWidget)
+            {
+                // Its an IntEnum! -> Ask the custom widget
+                enumWidget->setText(newText);
+            }
+            else
+            {
+                // Its just an int. -> do the QTreeWidgetItem call
+                el->setText(1, newText);
+            }
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::LongPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::LongPtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
-            el->setText(1, QString::fromStdString(std::to_string(i->getValue())));
+            el->setText(1, QString::fromStdString(usString<long>(i->getValue())));
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::FloatPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::FloatPtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
-            el->setText(1, QString::fromStdString(std::to_string(i->getValue())));
+            el->setText(1, QString::fromStdString(usString<float>(i->getValue())));
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::DoublePtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::DoublePtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
-            el->setText(1, QString::fromStdString(std::to_string(i->getValue())));
+            el->setText(1, QString::fromStdString(usString<double>(i->getValue())));
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::BoolPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::BoolPtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
             QTreeWidgetItem* el = parentItem->child(index);
-            el->setText(1, QString::fromStdString(std::to_string(i->getValue())));
+            el->setText(1, QString::fromStdString(usString<bool>(i->getValue())));
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::StringPtr& i)
+    void
+    AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::StringPtr& i)
     {
         if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement()))
         {
@@ -129,9 +353,10 @@ namespace armarx
         }
     }
 
-    void AronTreeWidgetSetterVisitor::visitUnknown(Input&)
+    void
+    AronTreeWidgetSetterVisitor::visitUnknown(Input&)
     {
-        ARMARX_WARNING_S << "Received an unknown type when trying to set a skill argument type from an aron data object.";
+        ARMARX_WARNING_S << "Received an unknown type when trying to set a skill argument type "
+                            "from an aron data object.";
     }
-}
-
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.h
index 336be31e20d4ff44496a8a2f8424d7dd3c1419f1..5090c12e82d28498efe8e1e63015e659f1e1abce 100644
--- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.h
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.h
@@ -23,17 +23,18 @@
 
 #include <stack>
 
-#include "../AronTreeWidgetItem.h"
-
-#include <RobotAPI/libraries/aron/core/type/variant/All.h>
 #include <RobotAPI/libraries/aron/core/data/variant/All.h>
 #include <RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h>
+#include <RobotAPI/libraries/aron/core/type/variant/All.h>
+
+#include "../AronTreeWidgetItem.h"
 
 namespace armarx
 {
-    // Conversion from TreeView to aron data
-    class AronTreeWidgetSetterVisitor :
-            public armarx::aron::data::ConstVariantVisitor
+    // Conversion from aron data to Tree View data
+    // This should be used to programatically change data to be displayed in the GUI.
+    // This code will not be called, if changes are made on the GUI side.
+    class AronTreeWidgetSetterVisitor : public armarx::aron::data::ConstVariantVisitor
     {
     public:
         QTreeWidgetItem* parentItem;
@@ -41,9 +42,9 @@ namespace armarx
         AronTreeWidgetItem* qWidgetItem;
 
         AronTreeWidgetSetterVisitor() = delete;
-        AronTreeWidgetSetterVisitor(QTreeWidgetItem* i, int x) :
-            parentItem(i), index(x)
-        {}
+        AronTreeWidgetSetterVisitor(QTreeWidgetItem* i, int x) : parentItem(i), index(x)
+        {
+        }
 
         virtual void visitAronVariant(const aron::data::DictPtr&) final;
         virtual void visitAronVariant(const aron::data::ListPtr&) final;
@@ -58,7 +59,6 @@ namespace armarx
 
     private:
         bool checkTreeWidgetItemForSimilarName(const std::string& name) const;
+        void adjustNumberOfChildren(AronTreeWidgetItem* parent, size_t numChildren);
     };
-}
-
-
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/CustomWidget.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/CustomWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..51836fde9dc7a71fa44740c415fbaf03c3df79e7
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/CustomWidget.cpp
@@ -0,0 +1,42 @@
+#include "CustomWidget.h"
+
+#include "ArmarXCore/core/exceptions/local/ExpressionException.h"
+
+namespace armarx
+{
+    CustomWidget::CustomWidget(QTreeWidgetItem* overlayingItem) : overlayingItem(overlayingItem)
+    {
+        // connect to general QTreeWidgetItem callback.
+        // This also lets the conversion start for other objects. (Not just this widget)
+        ARMARX_CHECK(connect(this,
+                             SIGNAL(elemChanged(QTreeWidgetItem*, int)),
+                             overlayingItem->treeWidget(),
+                             SIGNAL(itemChanged(QTreeWidgetItem*, int))));
+    }
+
+    CustomWidget*
+    CustomWidget::DynamicCast(QWidget* elem)
+    {
+        return dynamic_cast<CustomWidget*>(elem);
+    }
+
+    CustomWidget*
+    CustomWidget::DynamicCastAndCheck(QWidget* elem)
+    {
+        if (!elem)
+        {
+            return nullptr;
+        }
+        auto* casted = DynamicCast(elem);
+        ARMARX_CHECK_NOT_NULL(casted);
+        return casted;
+    }
+
+    void
+    CustomWidget::setSupressSignals(bool doSupress)
+    {
+        QObject::blockSignals(doSupress);
+    }
+
+
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/CustomWidget.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/CustomWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..49477ffa148e6a5c38279015a356571e107dadb7
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/CustomWidget.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <QTreeWidgetItem>
+#include <QWidget>
+
+namespace armarx
+{
+
+    class CustomWidget : public QWidget
+    {
+        Q_OBJECT
+
+    public:
+        CustomWidget(QTreeWidgetItem* overlayingItem);
+        static CustomWidget* DynamicCast(QWidget*);
+        static CustomWidget* DynamicCastAndCheck(QWidget*);
+
+        virtual void setSupressSignals(bool doSupress);
+
+    protected:
+        QTreeWidgetItem* overlayingItem;
+
+    signals:
+        void elemChanged(QTreeWidgetItem* elem, int col);
+    };
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/EditMatrixWidget.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/EditMatrixWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8e01710f03cf9fabe1f9f50b060bc058016099c8
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/EditMatrixWidget.cpp
@@ -0,0 +1,250 @@
+#include "EditMatrixWidget.h"
+
+#include <QGridLayout>
+#include <QLabel>
+
+#include "ArmarXCore/core/exceptions/local/ExpressionException.h"
+#include "ArmarXCore/core/logging/Logging.h"
+
+#include "../../ColorPalettes.h"
+#include "../visitors/AronTreeWidgetCreator.h"
+#include "NDArrayHelper.h"
+
+namespace armarx
+{
+    EditMatrixWidget::EditMatrixWidget(long numRows,
+                                       long numCols,
+                                       aron::type::matrix::ElementType elemType,
+                                       QTreeWidgetItem* currentItem) :
+        CustomWidget(currentItem)
+    {
+        realRows = numRows;
+        realCols = numCols;
+        this->elemType = elemType;
+        // init surrounding layout
+        outerVerticalLayout = new QVBoxLayout();
+        innerHorizontalLayout = new QHBoxLayout();
+        outerVerticalLayout->addItem(innerHorizontalLayout);
+
+
+        QGridLayout* innerGrid = new QGridLayout();
+        const long createRows = std::min(numRows, MAX_ROWS_DISPLAY);
+        const long createCols = std::min(numCols, MAX_COLS_DISPLAY);
+
+        for (long i = 0; i < createRows * createCols; ++i)
+        {
+            auto* edit = new QLineEdit();
+            dispElements.push_back(edit);
+            int currRow = i / createCols;
+            int currCol = i % createCols;
+
+            innerGrid->addWidget(edit, currRow, currCol);
+            std::stringstream ss;
+            ss << "(" << currRow << ", " << currCol << ")";
+            std::string text = ss.str();
+
+            edit->setText(text.c_str());
+        }
+        innerHorizontalLayout->addItem(innerGrid);
+
+        // check, if we need to signal to the user, that not all elements are displayed.
+        if (numRows > MAX_ROWS_DISPLAY)
+        {
+            QLabel* fullLabel = new QLabel("...");
+            outerVerticalLayout->addWidget(fullLabel);
+        }
+        if (numCols > MAX_COLS_DISPLAY)
+        {
+            QLabel* fullLabel = new QLabel("...");
+            innerHorizontalLayout->addWidget(fullLabel);
+        }
+        setLayout(outerVerticalLayout);
+
+        // add hidden elements in vector
+        {
+            const auto hiddenCols = numCols - createCols;
+            // the 0th element holds all columns that are
+            // to the right of the displayed cols AND besides the displayed rows!
+            hiddenElems.push_back(std::vector<std::string>(hiddenCols * createRows, ""));
+
+            // add all rows that are hidden
+            for (long i = 0; i < numRows - createRows; ++i)
+            {
+                // add full cols; everything is hidden here
+                hiddenElems.push_back(std::vector<std::string>(numCols, ""));
+            }
+        }
+
+        for (size_t i = 0; i < dispElements.size(); ++i)
+        {
+            ARMARX_CHECK(connect(
+                dispElements[i], SIGNAL(editingFinished()), this, SLOT(matrixElementChanged())));
+        }
+    }
+
+    EditMatrixWidget*
+    EditMatrixWidget::DynamicCast(QWidget* elem)
+    {
+        return dynamic_cast<EditMatrixWidget*>(elem);
+    }
+
+    EditMatrixWidget*
+    EditMatrixWidget::DynamicCastAndCheck(QWidget* elem)
+    {
+        if (!elem)
+        {
+            return nullptr;
+        }
+        auto* casted = DynamicCast(elem);
+        ARMARX_CHECK_NOT_NULL(casted);
+        return casted;
+    }
+
+    void
+    EditMatrixWidget::setText(long row, long col, const std::string& str)
+    {
+        ARMARX_CHECK(row < realRows);
+        ARMARX_CHECK(col < realCols);
+        auto dispCols = getDisplayedCols();
+        auto dispRows = getDisplayedRows();
+        if (row < dispRows && col < dispCols)
+        {
+            dispElements[row * dispCols + col]->setText(str.c_str());
+            dispElements[row * dispCols + col]->setCursorPosition(0);
+        }
+        else if (row < dispRows)
+        {
+            long idx = row * (realCols - dispCols) + col - dispCols;
+            hiddenElems.at(0).at(idx) = str;
+        }
+        else
+        {
+            hiddenElems.at(row - dispRows + 1).at(col) = str;
+        }
+    }
+
+    std::string
+    EditMatrixWidget::getText(long row, long col)
+    {
+        ARMARX_CHECK(row < realRows);
+        ARMARX_CHECK(col < realCols);
+        const auto dispRows = getDisplayedRows();
+        const auto dispCols = getDisplayedCols();
+        if (row < dispRows && col < dispCols)
+        {
+            auto txt = dispElements.at(row * dispCols + col)->text();
+            return txt.toStdString();
+        }
+        else if (row < getDisplayedRows())
+        {
+            // the stuff besides the displayed rows
+            long idx = row * (realCols - dispCols) + col - dispCols;
+            return hiddenElems.at(0).at(idx);
+        }
+        else
+        {
+            // stuff beneath displayed rows
+            return hiddenElems.at(row - dispRows + 1).at(col);
+        }
+    }
+
+    void
+    EditMatrixWidget::highlightUnparsableEntries()
+    {
+        auto dispRows = getDisplayedRows();
+        auto dispCols = getDisplayedCols();
+        for (long row = 0; row < dispRows; ++row)
+        {
+            for (long col = 0; col < dispCols; ++col)
+            {
+                auto parsed = parseElement(row, col);
+                if (parsed.empty())
+                {
+                    dispElements.at(row * dispCols + col)
+                        ->setPalette(gui_color_palette::getErrorPalette());
+                }
+                else
+                {
+                    dispElements.at(row * dispCols + col)
+                        ->setPalette(gui_color_palette::getNormalPalette());
+                }
+            }
+        }
+    }
+
+    bool
+    EditMatrixWidget::hasParseErrors()
+    {
+        // also parse the hidden stuff!
+        for (long row = 0; row < realRows; ++row)
+        {
+            for (long col = 0; col < realCols; ++col)
+            {
+                auto parsed = parseElement(row, col);
+                if (parsed.empty())
+                {
+                    if (row >= getDisplayedRows() || col >= getDisplayedCols())
+                    {
+                        ARMARX_ERROR
+                            << "Programming error! Could not parse content in EditMatrixWidget "
+                               "that was set programatically from inside the SkillManagerPlugin. "
+                               "The error occured in row "
+                            << row << " and col " << col << ".";
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    std::vector<unsigned char>
+    EditMatrixWidget::parseElement(long row, long col)
+    {
+        std::string str = getText(row, col);
+        try
+        {
+            switch (elemType)
+            {
+                case armarx::aron::type::matrix::INT16:
+                    return NDArrayHelper::toByteVector<int16_t>(str);
+
+                case armarx::aron::type::matrix::INT32:
+                    return NDArrayHelper::toByteVector<int32_t>(str);
+
+                case armarx::aron::type::matrix::INT64:
+                    return NDArrayHelper::toByteVector<int64_t>(str);
+
+                case armarx::aron::type::matrix::FLOAT32:
+                    return NDArrayHelper::toByteVector<float>(str);
+
+                case armarx::aron::type::matrix::FLOAT64:
+                    return NDArrayHelper::toByteVector<double>(str);
+            }
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            return {};
+        }
+        return {};
+    }
+
+    long
+    EditMatrixWidget::getDisplayedRows() const
+    {
+        return std::min(realRows, MAX_ROWS_DISPLAY);
+    }
+    long
+    EditMatrixWidget::getDisplayedCols() const
+    {
+        return std::min(realCols, MAX_COLS_DISPLAY);
+    }
+    void
+    EditMatrixWidget::matrixElementChanged()
+    {
+        blockSignals(true);
+        highlightUnparsableEntries();
+        blockSignals(false);
+        emit elemChanged(overlayingItem, 1);
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/EditMatrixWidget.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/EditMatrixWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..1fdaaa9630a09ab4a73f83fc05fa065fd0663e4d
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/EditMatrixWidget.h
@@ -0,0 +1,81 @@
+#pragma once
+#include <vector>
+
+#include <QHBoxLayout>
+#include <QLineEdit>
+#include <QObject>
+#include <QTreeWidgetItem>
+#include <QVBoxLayout>
+
+#include "RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.h"
+
+#include "CustomWidget.h"
+
+namespace armarx
+{
+    // Custom Widget used to display Matrices
+    // MAX_ROWS_DISPLAY and MAX_COLS_DISPLAY are the maximal number of elements displayable
+    // everything else will not be displayed. However, there can still be made changes to this data with setText()
+    class EditMatrixWidget : public CustomWidget
+    {
+        Q_OBJECT
+    public:
+        EditMatrixWidget() = delete;
+        EditMatrixWidget(long numRows,
+                         long numCols,
+                         aron::type::matrix::ElementType elemType,
+                         QTreeWidgetItem* currentWidget);
+
+        static EditMatrixWidget* DynamicCast(QWidget*);
+        static EditMatrixWidget* DynamicCastAndCheck(QWidget*);
+
+        // Sets the text on all visible rows and cols.
+        void setText(long row, long col, const std::string& str);
+        std::string getText(long row, long col);
+        void highlightUnparsableEntries();
+        bool hasParseErrors();
+        // returns an empty vector if parsing failed. Else, contains the individual bytes.
+        std::vector<unsigned char> parseElement(long row, long col);
+
+
+    private:
+        // Dimensions of the underlying Type to represent
+        long realRows = 1;
+        long realCols = 1;
+
+        // maximum of rows / cols to display
+        static constexpr long MAX_ROWS_DISPLAY = 5;
+        static constexpr long MAX_COLS_DISPLAY = 5;
+        long getDisplayedRows() const;
+        long getDisplayedCols() const;
+
+        // Want to add dots to show the user that not all is displayed. This needs some wrapping layouts
+        QVBoxLayout* outerVerticalLayout;
+        QHBoxLayout* innerHorizontalLayout;
+
+        // Using row major layout
+        std::vector<QLineEdit*> dispElements;
+        // rows<cols<text>>: stores get and set messages for hidden elements (if there is not enough space for all elements)
+        std::vector<std::vector<std::string>> hiddenElems;
+
+        template <typename T>
+        static std::vector<unsigned char> toByteVector(const std::string& str);
+
+        // TODO: It would be nice to have this code somewhere else, this way, at least the GUI-responses
+        // are restricted to this Widget (signal & slot stuff)
+        aron::type::matrix::ElementType elemType;
+
+    private slots:
+        void matrixElementChanged();
+    };
+
+    template <typename T>
+    std::vector<unsigned char>
+    EditMatrixWidget::toByteVector(const std::string& str)
+    {
+        auto val = simox::alg::to_<T>(str);
+        std::vector<unsigned char> res(sizeof(val), 0);
+        *reinterpret_cast<T*>(res.data()) = val;
+        return res;
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/IntEnumWidget.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/IntEnumWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bfe1be2bf154768ae5ff49eff04d13caf492d133
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/IntEnumWidget.cpp
@@ -0,0 +1,139 @@
+#include "IntEnumWidget.h"
+
+#include <QHBoxLayout>
+
+#include "RobotAPI/libraries/aron/core/type/variant/All.h"
+
+#include "../../ColorPalettes.h"
+#include "../visitors/AronTreeWidgetConverter.h"
+
+namespace armarx
+{
+    IntEnumWidget::IntEnumWidget(const aron::type::IntEnumPtr& enumPtr,
+                                 QTreeWidgetItem* currentItem) :
+        CustomWidget(currentItem), element_type(enumPtr)
+    {
+        auto names = enumPtr->getAcceptedValueNames();
+        auto outerLayout = new QHBoxLayout();
+        outerLayout->setContentsMargins(0, 0, 0, 0);
+        innerWidget = new QComboBox();
+        outerLayout->addWidget(innerWidget);
+
+        for (const auto& n : names)
+        {
+            innerWidget->addItem(n.c_str());
+        }
+        innerWidget->setInsertPolicy(QComboBox::NoInsert);
+        innerWidget->setEditable(true);
+        innerWidget->setCurrentIndex(0);
+
+        setLayout(outerLayout);
+        ARMARX_CHECK(connect(innerWidget,
+                             SIGNAL(currentTextChanged(const QString&)),
+                             this,
+                             SLOT(textChanged(const QString&))));
+    }
+
+    IntEnumWidget*
+    IntEnumWidget::DynamicCast(QWidget* widget)
+    {
+        return dynamic_cast<IntEnumWidget*>(widget);
+    }
+
+    IntEnumWidget*
+    IntEnumWidget::DynamicCastAndCheck(QWidget* elem)
+    {
+        if (!elem)
+        {
+            return nullptr;
+        }
+        auto* casted = DynamicCast(elem);
+        ARMARX_CHECK_NOT_NULL(casted);
+        return casted;
+    }
+
+    bool
+    IntEnumWidget::hasParseErrors()
+    {
+        return parseToAron().first;
+    }
+
+    void
+    IntEnumWidget::setText(const QString& text)
+    {
+        innerWidget->setEditText(text);
+        highlightUnparsableEntries();
+    }
+
+    QString
+    IntEnumWidget::getText()
+    {
+        return innerWidget->currentText();
+    }
+
+    std::pair<bool, aron::data::IntPtr>
+    IntEnumWidget::parseToAron()
+    {
+        auto crAron = std::make_shared<aron::data::Int>(element_type->getPath());
+
+        // first look for strings in value map
+        auto valueMap = element_type->getAcceptedValueMap();
+        std::string toParse = getText().toStdString();
+
+        auto searchRes = valueMap.find(toParse);
+        if (searchRes != valueMap.end())
+        {
+            crAron->setValue(searchRes->second);
+            return {true, crAron};
+        }
+        // maybe its the number directly
+        auto accVals = element_type->getAcceptedValues();
+        int res;
+        try
+        {
+            res = simox::alg::to_<int>(toParse);
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            ARMARX_VERBOSE << "Failed to parse IntEnum: Could not convert  \'" << toParse
+                           << "\' to an int. It also was not one of the accepted strings.";
+            return {false, nullptr};
+        }
+        if (std::find(accVals.begin(), accVals.end(), res) != accVals.end())
+        {
+
+            crAron->setValue(res);
+        }
+        else
+        {
+            ARMARX_VERBOSE << "Parsed int " << res
+                           << "but this int is not part of the accepted values.";
+            return {false, nullptr};
+        }
+        return {true, crAron};
+    }
+
+    void
+    IntEnumWidget::highlightUnparsableEntries()
+    {
+        auto parsed = parseToAron().first;
+        if (parsed)
+        {
+            innerWidget->setPalette(gui_color_palette::getNormalPalette());
+        }
+        else
+        {
+            innerWidget->setPalette(gui_color_palette::getErrorPalette());
+        }
+    }
+
+    void
+    IntEnumWidget::textChanged(const QString&)
+    {
+        setSupressSignals(true);
+        highlightUnparsableEntries();
+        setSupressSignals(false);
+        // fire change signal
+        emit CustomWidget::elemChanged(overlayingItem, 1);
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/IntEnumWidget.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/IntEnumWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..095ea480f00a6962bb0ebf407c4f43a8379a59e3
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/IntEnumWidget.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <QComboBox>
+
+#include "RobotAPI/libraries/aron/core/data/variant/primitive/Int.h"
+#include "RobotAPI/libraries/aron/core/type/variant/forward_declarations.h"
+
+#include "../AronTreeWidgetItem.h"
+#include "CustomWidget.h"
+
+namespace armarx
+{
+    // Custom wrapper around the QComboBox widget to represent IntEnums
+    // This class handles parsing once the user edited the field and is also responsible
+    // to parse the according aron data from text
+    class IntEnumWidget : public CustomWidget
+    {
+        Q_OBJECT
+    public:
+        IntEnumWidget(const aron::type::IntEnumPtr&, QTreeWidgetItem* currentItem);
+        // needs to be called after the constructor, because qt needs the meta object to be fully constructed at this point
+        void postCtorCall();
+
+        static IntEnumWidget* DynamicCast(QWidget*);
+        static IntEnumWidget* DynamicCastAndCheck(QWidget*);
+
+        bool hasParseErrors();
+        void setText(const QString& text);
+        QString getText();
+        std::pair<bool, aron::data::IntPtr> parseToAron();
+
+    private:
+        const aron::type::IntEnumPtr element_type;
+        QComboBox* innerWidget;
+
+        bool noParseErrors = true;
+
+        void highlightUnparsableEntries();
+    private slots:
+        void textChanged(const QString&);
+    };
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/NDArrayHelper.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/NDArrayHelper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a9599a2dbdfd456e1237542d34006f5d4c4c9bbf
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/NDArrayHelper.cpp
@@ -0,0 +1 @@
+#include "NDArrayHelper.h"
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/NDArrayHelper.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/NDArrayHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed91b874cc5f91ee24cf95eb6b46013da7b9d590
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/NDArrayHelper.h
@@ -0,0 +1,30 @@
+#pragma once
+#include <string>
+#include <vector>
+
+#include <SimoxUtility/algorithm/string.h>
+
+class NDArrayHelper
+{
+public:
+    // Uses the simox utility to parse floatingpoint and fixed precision types
+    // it then writes the result into a byte vector
+    // an empty byte vector encodes a parsing error.
+    template <typename T>
+    std::vector<unsigned char> static toByteVector(const std::string& str)
+    {
+        try
+        {
+            auto val = simox::alg::to_<T>(str);
+            std::vector<unsigned char> res(sizeof(val), 0);
+            T* reinterpPtr = reinterpret_cast<T*>(res.data());
+            T* laundered = std::launder(reinterpPtr);
+            *laundered = val;
+            return res;
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            return {};
+        }
+    }
+};
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/QuaternionWidget.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/QuaternionWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1d6fa3b946a704b180109c2598b663e2ba03bad
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/QuaternionWidget.cpp
@@ -0,0 +1,160 @@
+#include "QuaternionWidget.h"
+
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+
+#include "../../ColorPalettes.h"
+#include "NDArrayHelper.h"
+namespace armarx
+{
+
+    QuaternionWidget*
+    QuaternionWidget::DynamicCast(QWidget* elem)
+    {
+        return dynamic_cast<QuaternionWidget*>(elem);
+    }
+
+    QuaternionWidget*
+    QuaternionWidget::DynamicCastAndCheck(QWidget* elem)
+    {
+        if (!elem)
+        {
+            return nullptr;
+        }
+        auto* casted = DynamicCast(elem);
+        ARMARX_CHECK_NOT_NULL(casted);
+        return casted;
+    }
+
+    void
+    QuaternionWidget::setText(QuaternionComponents col, const std::string& str)
+    {
+        size_t idx = (size_t)col;
+        xyzw_components.at(idx)->setText(str.c_str());
+        highlightUnparsableEntries();
+    }
+
+    bool
+    QuaternionWidget::hasParseErrors()
+    {
+        return parseErrors;
+    }
+
+    armarx::QuaternionWidget::QuaternionWidget(aron::type::quaternion::ElementType elType,
+                                               QTreeWidgetItem* currentItem) :
+        CustomWidget(currentItem), element_type(elType)
+    {
+        auto outerLayout = new QHBoxLayout();
+        auto labelCol1 = new QVBoxLayout();
+        auto labelCol2 = new QVBoxLayout();
+        auto xzEdit = new QVBoxLayout();
+        auto ywEdit = new QVBoxLayout();
+
+        outerLayout->addLayout(labelCol1);
+        outerLayout->addLayout(xzEdit);
+        outerLayout->addLayout(labelCol2);
+        outerLayout->addLayout(ywEdit);
+
+        xyzw_components.reserve(4);
+        for (size_t i = 0; i < 4; ++i)
+        {
+            xyzw_components.push_back(new QLineEdit());
+        }
+
+        // Tabbing order >> Viewing order. Thats why the indeces are a bit switched
+        labelCol1->addWidget(new QLabel("x"));
+        xzEdit->addWidget(xyzw_components.at(0));
+
+        labelCol2->addWidget(new QLabel("z"));
+        ywEdit->addWidget(xyzw_components.at(2));
+
+        labelCol1->addWidget(new QLabel("y"));
+        xzEdit->addWidget(xyzw_components.at(1));
+
+        labelCol2->addWidget(new QLabel("w"));
+        ywEdit->addWidget(xyzw_components.at(3));
+
+        for (const auto& el : xyzw_components)
+        {
+            ARMARX_CHECK(
+                connect(el, SIGNAL(editingFinished()), this, SLOT(quaternionElementChanged())));
+        }
+
+        setLayout(outerLayout);
+        highlightUnparsableEntries();
+    }
+
+    void
+    QuaternionWidget::highlightUnparsableEntries()
+    {
+        parseErrors = false;
+        for (size_t i = 0; i < 4; ++i)
+        {
+            bool ok = false;
+            switch (element_type)
+            {
+                case armarx::aron::type::quaternion::FLOAT32:
+                {
+                    float flt;
+                    std::tie(ok, flt) = parseQuatVals<float>((QuaternionComponents)i);
+                    break;
+                }
+                case armarx::aron::type::quaternion::FLOAT64:
+                {
+                    double dbl;
+                    std::tie(ok, dbl) = parseQuatVals<double>((QuaternionComponents)i);
+                    break;
+                }
+            }
+            if (ok)
+            {
+                xyzw_components.at(i)->setPalette(gui_color_palette::getNormalPalette());
+            }
+            else
+            {
+                xyzw_components.at(i)->setPalette(gui_color_palette::getErrorPalette());
+                parseErrors = true;
+            }
+        }
+    }
+
+    std::vector<unsigned char>
+    QuaternionWidget::parseAllToNDArray()
+    {
+        std::vector<unsigned char> res;
+        bool success = true;
+        if (element_type == aron::type::quaternion::FLOAT32)
+        {
+            res.reserve(16);
+            for (size_t i = 0; i < 4; ++i)
+            {
+                auto bytevec =
+                    NDArrayHelper::toByteVector<float>(xyzw_components.at(i)->text().toStdString());
+                success &= !bytevec.empty();
+                res.insert(res.end(), bytevec.begin(), bytevec.end());
+            }
+        }
+        else
+        {
+            res.reserve(32);
+            for (size_t i = 0; i < 4; ++i)
+            {
+                auto bytevec = NDArrayHelper::toByteVector<double>(
+                    xyzw_components.at(i)->text().toStdString());
+                success &= !bytevec.empty();
+                res.insert(res.end(), bytevec.begin(), bytevec.end());
+            }
+        }
+        return (success) ? res : std::vector<unsigned char>();
+    }
+
+    void
+    QuaternionWidget::quaternionElementChanged()
+    {
+        CustomWidget::setSupressSignals(true);
+        highlightUnparsableEntries();
+        CustomWidget::setSupressSignals(false);
+        emit CustomWidget::elemChanged(overlayingItem, 1);
+    }
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/QuaternionWidget.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/QuaternionWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..d55d2bba35e2712d1d161c83ed86b06b300bcf2d
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/widgets/QuaternionWidget.h
@@ -0,0 +1,68 @@
+#pragma once
+#include <vector>
+
+#include <QLineEdit>
+#include <QObject>
+#include <QVBoxLayout>
+
+#include "RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.h"
+
+#include "CustomWidget.h"
+
+
+namespace armarx
+{
+    // Custom Widget which represents a Quaternion - This class does not normalize the inputs
+    // It can parse its data to NDArray and also handles user edit signals itself. (And also the highlighting if errors occur)
+    class QuaternionWidget : public CustomWidget
+    {
+        Q_OBJECT
+    public:
+        QuaternionWidget(aron::type::quaternion::ElementType type, QTreeWidgetItem* currentItem);
+
+        static QuaternionWidget* DynamicCast(QWidget*);
+        static QuaternionWidget* DynamicCastAndCheck(QWidget*);
+
+        enum struct QuaternionComponents
+        {
+            X = 0,
+            Y,
+            Z,
+            W
+        };
+        void setText(QuaternionComponents col, const std::string& str);
+        std::string getText(QuaternionComponents col);
+        bool hasParseErrors();
+        std::vector<unsigned char> parseAllToNDArray();
+
+    private:
+        std::vector<QLineEdit*> xyzw_components;
+        aron::type::quaternion::ElementType element_type;
+        bool parseErrors = false;
+
+        void highlightUnparsableEntries();
+        template <typename T>
+        std::pair<bool, T> parseQuatVals(QuaternionComponents comp);
+
+    private slots:
+        void quaternionElementChanged();
+    };
+
+    template <typename T>
+    std::pair<bool, T>
+    QuaternionWidget::parseQuatVals(QuaternionWidget::QuaternionComponents comp)
+    {
+        // size_t data_size = element_type == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8;
+        try
+        {
+            T val = simox::alg::to_<T>(xyzw_components.at((size_t)comp)->text().toStdString());
+            return {true, val};
+        }
+        catch (const simox::error::SimoxError& err)
+        {
+            return {false, NAN};
+        }
+    }
+
+
+} // namespace armarx
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/.cmake/api/v1/query/cache-v2 b/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/.cmake/api/v1/query/cache-v2
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/.cmake/api/v1/query/cmakeFiles-v1 b/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/.cmake/api/v1/query/cmakeFiles-v1
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/.cmake/api/v1/query/codemodel-v2 b/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/.cmake/api/v1/query/codemodel-v2
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/qtcsettings.cmake b/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/qtcsettings.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fccf6a67eee120cbb1092f841fda5cca870a5a14
--- /dev/null
+++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/build/qtcsettings.cmake
@@ -0,0 +1,8 @@
+# This file is managed by Qt Creator, do not edit!
+
+set("CMAKE_BUILD_TYPE" "RelWithDebInfo" CACHE "STRING" "" FORCE)
+set("CMAKE_PROJECT_INCLUDE_BEFORE" "/common/homes/students/bodmer/opt/qtcreator/qtcreator/share/qtcreator/package-manager/auto-setup.cmake" CACHE "PATH" "" FORCE)
+set("QT_QMAKE_EXECUTABLE" "/usr/lib/qt5/bin/qmake" CACHE "STRING" "" FORCE)
+set("CMAKE_PREFIX_PATH" "/usr" CACHE "STRING" "" FORCE)
+set("CMAKE_C_COMPILER" "/usr/bin/gcc" CACHE "STRING" "" FORCE)
+set("CMAKE_CXX_COMPILER" "/usr/bin/g++" CACHE "STRING" "" FORCE)
\ No newline at end of file
diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt
index 5d9d3c04b278f8032125f98cf82d63aaa8253155..9e290598fee8047f853044e54ea3775b62ab49f7 100644
--- a/source/RobotAPI/interface/CMakeLists.txt
+++ b/source/RobotAPI/interface/CMakeLists.txt
@@ -108,6 +108,7 @@ set(SLICE_FILES
 
     aron.ice
     aron/Aron.ice
+    aron/test/AronConversionTestInterface.ice
 
 
     armem.ice
diff --git a/source/RobotAPI/interface/aron/test/AronConversionTestInterface.ice b/source/RobotAPI/interface/aron/test/AronConversionTestInterface.ice
new file mode 100644
index 0000000000000000000000000000000000000000..924f40c6d8664123c822eb9f7eb338d8d50b52d5
--- /dev/null
+++ b/source/RobotAPI/interface/aron/test/AronConversionTestInterface.ice
@@ -0,0 +1,61 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * package    SpeechX::aron_cpp_to_python_conv_test
+ * author     Rainer Kartmann ( rainer dot kartmann at kit dot edu )
+ * date       2023
+ * copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *            GNU General Public License
+ */
+
+
+#pragma once
+
+#include <RobotAPI/interface/aron/Aron.ice>
+
+
+module armarx { module aron {  module test
+{
+
+module dto
+{
+
+    struct TestAronConversionRequest
+    {
+        string aronClassName;
+        ::armarx::aron::data::dto::Dict probe;
+    };
+    struct TestAronConversionResponse
+    {
+        bool success;
+        string errorMessage;
+
+        ::armarx::aron::data::dto::Dict probe;
+    };
+
+};
+
+
+module dti
+{
+
+    interface AronConversionTestInterface
+    {
+        dto::TestAronConversionResponse testAronConversion(dto::TestAronConversionRequest req);
+    };
+
+};
+
+};};};
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h
index 0b877909c4a35e5b867d21de7840b1625b5e74dc..02b2bcae49014e801c59d001fe9150dcae7a1b95 100644
--- a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h
@@ -32,6 +32,12 @@ namespace armarx::armem::base
         /// An optional confidence, may be used for things like decay.
         float confidence = 1.0;
 
+        /// An optional value indicating the last access
+        Time lastAccessed = Time::Invalid();
+
+        /// A counter how often the instance has been accessed
+        unsigned long accessed = 0;
+
 
         bool operator==(const EntityInstanceMetadata& other) const;
         inline bool operator!=(const EntityInstanceMetadata& other) const
diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
index b6497f8ff421feb16b7f7b07ede1f2d3e57c2266..efc18d58c99ee298b71ce2e775a012d7e6050b04 100644
--- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
@@ -261,12 +261,12 @@ namespace armarx::armem::base
          * @param commit The commit.
          * @return The resulting memory IDs.
          */
-        std::vector<UpdateResult> update(const Commit& commit)
+        std::vector<UpdateResult> update(const Commit& commit, const bool addMissingCoreSegmentDuringUpdate = false, const bool checkMemoryName = true)
         {
             std::vector<UpdateResult> results;
             for (const EntityUpdate& update : commit.updates)
             {
-                results.push_back(this->update(update));
+                results.push_back(this->update(update, addMissingCoreSegmentDuringUpdate, checkMemoryName));
             }
             return results;
         }
@@ -276,11 +276,14 @@ namespace armarx::armem::base
          * @param update The update.
          * @return The resulting entity snapshot's ID.
          */
-        UpdateResult update(const EntityUpdate& update)
+        UpdateResult update(const EntityUpdate& update, const bool addMissingCoreSegmentDuringUpdate = false, const bool checkMemoryName = true)
         {
-            this->_checkContainerName(update.entityID.memoryName, this->name());
+            if (checkMemoryName)
+            {
+                this->_checkContainerName(update.entityID.memoryName, this->name());
+            }
 
-            auto [inserted, coreSeg] = _addCoreSegmentIfMissing(update.entityID.coreSegmentName);
+            auto [inserted, coreSeg] = _addCoreSegmentIfMissing(update.entityID.coreSegmentName, addMissingCoreSegmentDuringUpdate);
 
             // Update entry.
             UpdateResult ret(coreSeg->update(update));
@@ -349,14 +352,14 @@ namespace armarx::armem::base
 
     protected:
 
-        std::pair<bool, CoreSegmentT*> _addCoreSegmentIfMissing(const std::string& coreSegmentName)
+        std::pair<bool, CoreSegmentT*> _addCoreSegmentIfMissing(const std::string& coreSegmentName, const bool addMissingCoreSegmentDuringUpdate)
         {
             CoreSegmentT* coreSeg = nullptr;
 
             auto it = this->_container.find(coreSegmentName);
             if (it == this->_container.end())
             {
-                if (_addMissingCoreSegmentDuringUpdate)
+                if (addMissingCoreSegmentDuringUpdate)
                 {
                     // Insert into map.
                     coreSeg = &addCoreSegment(coreSegmentName);
@@ -373,13 +376,5 @@ namespace armarx::armem::base
                 return {false, coreSeg};
             }
         }
-
-
-    public:
-
-        // ToDo: Remove from base structure - this should be specific to the server versions.
-        // If necessary at all.
-        bool _addMissingCoreSegmentDuringUpdate = false;
-
     };
 }
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/object/json/JsonConverter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/object/json/JsonConverter.cpp
index f2baa4865ff5d2a832e61acc857863d2c6ca545a..1495b275baa88a14aecb9487db781ac0236b57d5 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/converter/object/json/JsonConverter.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/object/json/JsonConverter.cpp
@@ -1,5 +1,6 @@
 #include "JsonConverter.h"
 
+#include <ArmarXCore/core/logging/Logging.h>
 #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 
 namespace armarx::armem::server::ltm::converter::object
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h
index b975b352f007c8ebd3364af641ef75c3a7fc6a08..ebe21f4c1c35a03ab8a0b5219d26e57417c4533a 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h
@@ -65,7 +65,7 @@ namespace armarx::armem::server::ltm
         }
 
         /// iterate over all provider segments of this ltm
-        virtual bool forEachProviderSegment(std::function<void(ProviderSegmentT&)>&& func) const = 0;
+        virtual bool forEachProviderSegment(std::function<void(ProviderSegmentT&)> func) const = 0;
 
         /// find provider segment
         virtual std::shared_ptr<ProviderSegmentT> findProviderSegment(const std::string&) const = 0;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h
index 9dedb572fdc8b4ff31c6018f238009d45fde6763..15ebde328ec72b9f189f542087fd7753c2a3faf0 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h
@@ -59,11 +59,11 @@ namespace armarx::armem::server::ltm
         }
 
         /// iterate over all entity snapshots of this ltm
-        virtual bool forEachSnapshot(std::function<void(EntitySnapshotT&)>&& func) const = 0;
-        virtual bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshotT&)>&& func) const = 0;
-        virtual bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshotT&)>&& func) const = 0;
-        virtual bool forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshotT&)>&& func) const = 0;
-        virtual bool forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshotT&)>&& func) const = 0;
+        virtual bool forEachSnapshot(std::function<void(EntitySnapshotT&)> func) const = 0;
+        virtual bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshotT&)> func) const = 0;
+        virtual bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshotT&)> func) const = 0;
+        virtual bool forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshotT&)> func) const = 0;
+        virtual bool forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshotT&)> func) const = 0;
 
         /// find entity snapshot segment
         virtual std::shared_ptr<EntitySnapshotT> findSnapshot(const Time&) const = 0;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h
index bec7576234c8f6bbc9064745f2d0cdc0f8ef333b..1b32ee2c9fc10bdb476b36b7046f46fc8518e462 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h
@@ -123,10 +123,10 @@ namespace armarx::armem::server::ltm
         }
 
         /// iterate over all core segments of this ltm
-        virtual bool forEachCoreSegment(std::function<void(CoreSegmentT&)>&& func) const = 0;
+        virtual bool forEachCoreSegment(std::function<void(CoreSegmentT&)> func) const = 0;
 
         /// find core segment
-        virtual std::shared_ptr<CoreSegmentT> findCoreSegment(const std::string&) const = 0;
+        virtual std::shared_ptr<CoreSegmentT> findCoreSegment(const std::string&) const = 0; // TODO make unique!!
 
         /// default parameters. Implementation should use the configuration to configure
         virtual void createPropertyDefinitions(PropertyDefinitionsPtr& defs, const std::string& prefix)
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp
index 6f38d6ea21317b44d37045c985f15d5efe2103da..d5318e1f1e6ec9933ddc7e6b50f3894044111917 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp
@@ -33,4 +33,9 @@ namespace armarx::armem::server::ltm
     {
         return _id.getLeafItem();
     }
+
+    void MemoryItem::setMemoryName(const std::string& memoryName)
+    {
+        _id.memoryName = memoryName;
+    }
 } // namespace armarx::armem::server::ltm
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h
index 570231509806a4f6a56d55ab4a4a2d7442de8807..b8d17fe471c17e62aa188406648515e5a32f384a 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h
@@ -21,6 +21,7 @@ namespace armarx::armem::server::ltm
         std::string name() const;
 
         virtual void setMemoryID(const MemoryID&);
+        void setMemoryName(const std::string& memoryName);
 
     protected:
         std::shared_ptr<Processors> processors;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h
index b5aa8f0ee95711001d378f06ef5c674266dc021b..c241d7889621f534991733baf82973e28428a641 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h
@@ -65,7 +65,7 @@ namespace armarx::armem::server::ltm
         }
 
         /// iterate over all core segments of this ltm
-        virtual bool forEachEntity(std::function<void(EntityT&)>&& func) const = 0;
+        virtual bool forEachEntity(std::function<void(EntityT&)> func) const = 0;
 
         /// find entity segment
         virtual std::shared_ptr<EntityT> findEntity(const std::string&) const = 0;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp
index 785276d04bd1e366be172ba7a07560a96a0c7755..cfc859a5f89418247c1d7f383cfea1b5bce8aa2a 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp
@@ -16,7 +16,7 @@ namespace armarx::armem::server::ltm::disk
     {
     }
 
-    bool CoreSegment::forEachProviderSegment(std::function<void(ProviderSegment&)>&& func) const
+    bool CoreSegment::forEachProviderSegment(std::function<void(ProviderSegment&)> func) const
     {
         auto mPath = getMemoryBasePathForMode(currentMode, currentExport);
         auto relPath = getRelativePathForMode(currentMode);
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h
index 6dfc00e7e5e37814027cfc10a3be53dd83dff603..78ff8be3f12d35eeebbed370cc04559b37a57822 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h
@@ -18,7 +18,7 @@ namespace armarx::armem::server::ltm::disk
 
         CoreSegment(const std::filesystem::path& parentPath, const MemoryID& id, const std::shared_ptr<Processors>& p, const DiskMemoryItem::MemoryEncodingMode mode, const unsigned long e);
 
-        bool forEachProviderSegment(std::function<void(ProviderSegment&)>&& func) const override;
+        bool forEachProviderSegment(std::function<void(ProviderSegment&)> func) const override;
 
         std::shared_ptr<ProviderSegment> findProviderSegment(const std::string&) const override;
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp
index 6c87da45e576c10c18c6680141e00ed8c19aa3ba..8b00d8d39b8fa49de6c31d8b617549d97e6a45cb 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp
@@ -21,7 +21,7 @@ namespace armarx::armem::server::ltm::disk
     {
     }
 
-    bool Entity::forEachSnapshot(std::function<void(EntitySnapshot&)>&& func) const
+    bool Entity::forEachSnapshot(std::function<void(EntitySnapshot&)> func) const
     {
         auto mPath = getMemoryBasePathForMode(currentMode, currentExport);
         auto relPath = getRelativePathForMode(currentMode);
@@ -75,7 +75,7 @@ namespace armarx::armem::server::ltm::disk
         return true;
     }
 
-    bool Entity::forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)>&& func) const
+    bool Entity::forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)> func) const
     {
         ARMARX_WARNING << "PLEASE NOTE THAT QUERYING THE LTM INDEX WISE MAY BE BUGGY BECAUSE THE FILESYSTEM ITERATOR IS UNSORTED!";
 
@@ -106,7 +106,7 @@ namespace armarx::armem::server::ltm::disk
         return forEachSnapshot(std::move(f));
     }
 
-    bool Entity::forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)>&& func) const
+    bool Entity::forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)> func) const
     {
         auto f = [&](EntitySnapshot& e)
         {
@@ -120,7 +120,7 @@ namespace armarx::armem::server::ltm::disk
         return forEachSnapshot(std::move(f));
     }
 
-    bool Entity::forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshot&)>&& func) const
+    bool Entity::forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshot&)> func) const
     {
         auto f = [&](EntitySnapshot& e)
         {
@@ -134,7 +134,7 @@ namespace armarx::armem::server::ltm::disk
         return forEachSnapshot(std::move(f));
     }
 
-    bool Entity::forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)>&& func) const
+    bool Entity::forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)> func) const
     {
         auto f = [&](EntitySnapshot& e)
         {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h
index 759b22733612c700ec0461541976cf3872d9df07..3d98ef1bf8abe315e005a110ad6fa807f373d7ba 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h
@@ -18,11 +18,11 @@ namespace armarx::armem::server::ltm::disk
     public:
         Entity(const std::filesystem::path& parentPath, const MemoryID& id, const std::shared_ptr<Processors>& p, const DiskMemoryItem::MemoryEncodingMode mode, const unsigned long e);
 
-        bool forEachSnapshot(std::function<void(EntitySnapshot&)>&& func) const override;
-        bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)>&& func) const override;
-        bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)>&& func) const override;
-        bool forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshot&)>&& func) const override;
-        bool forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)>&& func) const override;
+        bool forEachSnapshot(std::function<void(EntitySnapshot&)> func) const override;
+        bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)> func) const override;
+        bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)> func) const override;
+        bool forEachSnapshotBeforeOrAt(const Time& time, std::function<void(EntitySnapshot&)> func) const override;
+        bool forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)> func) const override;
 
         std::shared_ptr<EntitySnapshot> findSnapshot(const Time&) const override;
         std::shared_ptr<EntitySnapshot> findLatestSnapshot() const override;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp
index 72ed4653638d77adf1c1dc760354c8dcf12d43d3..f1706a545a0f3d81cee3637e3bef3f5eb7df0e17 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp
@@ -80,6 +80,7 @@ namespace armarx::armem::server::ltm::disk
 
                 if (std::find(allFilesInIndexFolder.begin(), allFilesInIndexFolder.end(), dataFilename) != allFilesInIndexFolder.end())
                 {
+                    //ARMARX_INFO << "Convert data for entity " << id();
                     auto datafilecontent = util::readDataFromFile(mPath, relDataPath);
                     auto dataaron = dictConverter.convert(datafilecontent, "");
                     datadict = aron::data::Dict::DynamicCastAndCheck(dataaron);
@@ -110,6 +111,7 @@ namespace armarx::armem::server::ltm::disk
                     ARMARX_ERROR << "Could not find the data file '" << relDataPath.string() << "'. Continuing without data.";
                 }
 
+                //ARMARX_INFO << "Convert metadata for entity " << id();
                 if (std::find(allFilesInIndexFolder.begin(), allFilesInIndexFolder.end(), metadataFilename) != allFilesInIndexFolder.end())
                 {
                     auto metadatafilecontent = util::readDataFromFile(mPath, relMetadataPath);
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp
index 6d0b4e1fa18ee244643c5fc45755af0468d056db..a2a374c6de24e4fd1dca370149841d79f85de027 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp
@@ -65,7 +65,7 @@ namespace armarx::armem::server::ltm::disk
         }
     }
 
-    bool Memory::forEachCoreSegment(std::function<void(CoreSegment&)>&& func) const
+    bool Memory::forEachCoreSegment(std::function<void(CoreSegment&)> func) const
     {
         for (unsigned long i = 0; i <= maxExportIndex; ++i)
         {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h
index c9f1e95b216a0dd0dac6ff67c9f28c9ef1b38d5c..afd3a09004eea72c406ebfea844ffa80b257fc84 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h
@@ -29,7 +29,7 @@ namespace armarx::armem::server::ltm::disk
 
         void configure(const nlohmann::json& config) final;
 
-        bool forEachCoreSegment(std::function<void(CoreSegment&)>&& func) const final;
+        bool forEachCoreSegment(std::function<void(CoreSegment&)> func) const final;
         std::shared_ptr<CoreSegment> findCoreSegment(const std::string& coreSegmentName) const final;
 
     protected:
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp
index ede13058b8a8abbca1eb348b3fa483234e4eae76..32500f7d6a799f678d5fdf1fce09024d93c4a796 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp
@@ -18,7 +18,7 @@ namespace armarx::armem::server::ltm::disk
     {
     }
 
-    bool ProviderSegment::forEachEntity(std::function<void(Entity&)>&& func) const
+    bool ProviderSegment::forEachEntity(std::function<void(Entity&)> func) const
     {
         auto mPath = getMemoryBasePathForMode(currentMode, currentExport);
         auto relPath = getRelativePathForMode(currentMode);
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h
index 0402f4b98408b73719ea2d2889d02c195186aac6..dfa7c42714310a042dc344c043794eca4536ea00 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h
@@ -17,7 +17,7 @@ namespace armarx::armem::server::ltm::disk
     public:
         ProviderSegment(const std::filesystem::path& parentPath, const MemoryID& id, const std::shared_ptr<Processors>& p, const DiskMemoryItem::MemoryEncodingMode mode, const unsigned long e);
 
-        bool forEachEntity(std::function<void(Entity&)>&& func) const override;
+        bool forEachEntity(std::function<void(Entity&)> func) const override;
 
         std::shared_ptr<Entity> findEntity(const std::string&) const override;
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp
index daea3fcfc439326545a79ad00ac53e9133afa195..1a40e26a04923bccb123b4b07f00ab9be190efa9 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp
@@ -1,5 +1,7 @@
 #include "filesystem_util.h"
 
+#include <algorithm>
+
 #include <RobotAPI/libraries/armem/core/error/ArMemError.h>
 
 
@@ -97,6 +99,7 @@ namespace armarx::armem::server::ltm::disk
                     ret.push_back(subdirPath.filename());
                 }
             }
+            std::sort(ret.begin(), ret.end());
             return ret;
         }
 
@@ -111,6 +114,7 @@ namespace armarx::armem::server::ltm::disk
                     ret.push_back(subdirPath.filename());
                 }
             }
+            std::sort(ret.begin(), ret.end());
             return ret;
         }
     }
diff --git a/source/RobotAPI/libraries/armem/server/plugins/Plugin.h b/source/RobotAPI/libraries/armem/server/plugins/Plugin.h
index 02c89e5f323b4376ca4493f6b0f1e8efa22f3b60..aa6afd8171ff50cf43b955ff145a4770cf8f24b7 100644
--- a/source/RobotAPI/libraries/armem/server/plugins/Plugin.h
+++ b/source/RobotAPI/libraries/armem/server/plugins/Plugin.h
@@ -41,7 +41,7 @@ namespace armarx::armem::server::plugins
 
     public:
 
-        /// Set the name of the wm and the ltm (if enabled).
+        /// Set the name of the wm and the ltm
         void setMemoryName(const std::string& memoryName);
 
 
diff --git a/source/RobotAPI/libraries/armem/server/test/ArMemLTMTest.cpp b/source/RobotAPI/libraries/armem/server/test/ArMemLTMTest.cpp
index 7999a6a5752cd1bc9432f9caec95a6f928645a20..edaa7bb5c5d92b57b0edf3918d1674db34337680 100644
--- a/source/RobotAPI/libraries/armem/server/test/ArMemLTMTest.cpp
+++ b/source/RobotAPI/libraries/armem/server/test/ArMemLTMTest.cpp
@@ -31,9 +31,16 @@
 #include <RobotAPI/libraries/aron/core/data/variant/All.h>
 #include <RobotAPI/libraries/aron/core/type/variant/All.h>
 
+#include <RobotAPI/libraries/armem/server/ltm/disk/Memory.h>
 
 //#include "../core/io/diskWriter/NlohmannJSON/NlohmannJSONDiskWriter.h"
 
+// TODO: REMOVE ME!!
+#include <VirtualRobot/Robot.h>
+#include <VirtualRobot/RobotNodeSet.h>
+#include <VirtualRobot/Import/SimoxXMLFactory.h>
+#include <RobotAPI/libraries/armem_objects/aron/ObjectInstance.aron.generated.h>
+
 #include <filesystem>
 #include <iostream>
 
@@ -205,6 +212,61 @@ BOOST_AUTO_TEST_CASE(test_memory_export__easy_bool_setup)
     run<aron::type::Bool>("TestMemory_BoolSetup", "theBool");
 }
 
+BOOST_AUTO_TEST_CASE(test_memory_export__easy_fabian_setup)
+{
+    std::filesystem::path memoryExport = "/home/fabian/repos/projects/ltmtools/data/sim_2022_09_15";
+
+    armem::server::ltm::disk::Memory ltm(memoryExport, "Object");
+    auto ltm_c_seg = ltm.findCoreSegment("Instance");
+
+    ltm_c_seg->forEachProviderSegment([](const armem::server::ltm::disk::ProviderSegment& ltm_p_seg){
+        ltm_p_seg.forEachEntity([](const armem::server::ltm::disk::Entity& ltm_e){
+            ltm_e.forEachSnapshot([](const armem::server::ltm::disk::EntitySnapshot& ltm_snapshot){
+                armem::wm::EntitySnapshot s;
+                ltm_snapshot.loadAllReferences(s);
+                ltm_snapshot.resolve(s);
+
+                auto i = s.getInstance(0);
+                auto data = i.data();
+
+
+
+                auto p = data->getElement("pose");
+                auto p2 = armarx::aron::data::Dict::DynamicCastAndCheck(p);
+
+                armarx::objpose::arondto::ObjectPose px;
+                px.fromAron(p2);
+
+                auto a = p2->getElement("attachment");
+                auto a2 = armarx::aron::data::Dict::DynamicCastAndCheck(a);
+
+                armarx::objpose::arondto::ObjectAttachmentInfo ax;
+                ax.fromAron(a2);
+
+                if (ax.agentName != "")
+                {
+                    ARMARX_INFO << (ax.poseInFrame);
+                }
+            });
+        });
+    });
+
+
+    //auto ltm_p_seg = ltm_c_seg->findProviderSegment("Armar3");
+    //auto ltm_e = ltm_p_seg->findEntity("Armar3");
+
+    //armem::wm::Entity e;
+    //ltm_e->loadAllReferences(e);
+    //ltm_e->resolve(e);
+
+    //std::function<void(armarx::armem::wm::EntitySnapshot)> f = [](armem::wm::EntitySnapshot s){ ARMARX_INFO << s.id(); };
+
+    //e.forEachSnapshot(f);
+    //auto wm = ltm.loadAllAndResolve();
+
+
+}
+
 /*
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_rainer_setup)
 {
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
index 622031b7aead835f8d91b9eeac4ac06362d731a1..b9c789398b0d8ce5c6fb17e0c2cb44fb5bc5b531 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
@@ -150,7 +150,7 @@ namespace armarx::armem::gui
         connect(this, &This::connected, this, &This::startPeriodicUpdateTimer);
         connect(updateWidget, &armem::gui::PeriodicUpdateWidget::update, this, &This::startQueries);
 
-        connect(periodicUpdateTimer, &QTimer::timeout, this, &This::updateAvailableMemories);
+        connect(periodicUpdateTimer, &QTimer::timeout, this, &This::updateListOfActiveMemories);
         connect(periodicUpdateTimer, &QTimer::timeout, this, &This::processQueryResults);
 
         connect(memoryGroup->queryWidget(), &armem::gui::QueryWidget::storeInLTM, this, &This::queryAndStoreInLTM);
@@ -267,7 +267,7 @@ namespace armarx::armem::gui
         {
             std::stringstream ss;
             ss << "Memory name '" << memoryName
-               << "' is unknown. Known are: " << simox::alg::get_keys(memoryData);
+               << "' is unknown. Known are: " << simox::alg::join(simox::alg::get_keys(memoryData), ", ");
             statusLabel->setText(QString::fromStdString(ss.str()));
             return nullptr;
         }
@@ -288,7 +288,7 @@ namespace armarx::armem::gui
     {
         TIMING_START(MemoryStore);
 
-        auto enabledMemories = memoryGroup->queryWidget()->enabledMemories();
+        auto enabledMemories = memoryGroup->queryWidget()->getEnabledMemories();
         for (auto& [name, reader] : memoryReaders)
         {
             // skip if memory should not be queried
@@ -321,7 +321,7 @@ namespace armarx::armem::gui
 
         TIMING_START(MemoryStartRecording);
 
-        auto enabledMemories = memoryGroup->queryWidget()->enabledMemories();
+        auto enabledMemories = memoryGroup->queryWidget()->getEnabledMemories();
         for (auto& [name, reader] : memoryReaders)
         {
             // skip if memory should not be queried
@@ -341,7 +341,7 @@ namespace armarx::armem::gui
 
         TIMING_START(MemoryStopRecording);
 
-        auto enabledMemories = memoryGroup->queryWidget()->enabledMemories();
+        auto enabledMemories = memoryGroup->queryWidget()->getEnabledMemories();
         for (auto& [name, reader] : memoryReaders)
         {
             // skip if memory should not be queried
@@ -406,7 +406,8 @@ namespace armarx::armem::gui
         TIMING_START(MemoryExport)
 
         std::string status;
-        diskControl->storeOnDisk(directory, memoryData, &status);
+        std::vector<wm::Memory> memoryDataVec = simox::alg::get_values(memoryData);
+        diskControl->storeOnDisk(directory, memoryDataVec, &status);
 
         statusLabel->setText(QString::fromStdString(status));
         TIMING_END_STREAM(MemoryExport, ARMARX_VERBOSE)
@@ -418,19 +419,29 @@ namespace armarx::armem::gui
     {
 
         std::string status;
-        std::map<std::string, wm::Memory> data =
+        std::map<std::filesystem::path, wm::Memory> data =
             diskControl->loadFromDisk(directory, memoryGroup->queryInput(), &status);
 
-        for (auto& [name, memory] : data)
+        for (auto& [path, memory] : data)
         {
+            std::string name = memory.id().memoryName;
+            auto commit = armem::toCommit(memory);
+
             if (memoryWriters.count(name) > 0)
             {
-                auto commit = armem::toCommit(memory);
                 memoryWriters.at(name).commit(commit);
             }
             else
             {
-                ARMARX_WARNING << "No memory with name " << name << " available for commit.";
+                ARMARX_INFO << "No memory with name '" << name << "' available for commit. Create new virtual memory.";
+
+                // Please note: Here we assume that a memory server with the same name does not exist.
+                // I think this assumption is ok, since nobody should use filepaths as memory name.
+                // Nonetheless, we did not restrict the user to do so...
+                std::string virtualMemoryName = name + " (at " + path.string() + ")";
+                wm::Memory virtualMemory(virtualMemoryName);
+                virtualMemory.update(commit, true, false);
+                memoryData[virtualMemoryName] = virtualMemory;
             }
         }
 
@@ -487,7 +498,7 @@ namespace armarx::armem::gui
 
         // Can't use a structured binding here because you can't capture those in a lambda
         // according to the C++ standard.
-        auto enabledMemories = memoryGroup->queryWidget()->enabledMemories();
+        auto enabledMemories = memoryGroup->queryWidget()->getEnabledMemories();
         for (const auto& pair : memoryReaders)
         {
             // skip if memory should not be queried
@@ -592,7 +603,7 @@ namespace armarx::armem::gui
         }
 
         // Perhaps remove entries
-        auto enabledMemories = memoryGroup->queryWidget()->enabledMemories();
+        auto enabledMemories = memoryGroup->queryWidget()->getEnabledMemories();
         for (auto it = memoryData.begin(); it != memoryData.end();)
         {
             // Drop all entries in memoryData which are not in memoryReaders anymore.
@@ -764,7 +775,7 @@ namespace armarx::armem::gui
 
 
     void
-    MemoryViewer::updateAvailableMemories()
+    MemoryViewer::updateListOfActiveMemories()
     {
         if (is_connected and mns) // mns must be connected and mns must be available
         {
@@ -773,11 +784,13 @@ namespace armarx::armem::gui
                 memoryReaders = mns.getAllReaders(true);
                 memoryWriters = mns.getAllWriters(true);
 
-                std::vector<std::string> convVec;
-                std::transform(memoryReaders.begin(), memoryReaders.end(), std::back_inserter(convVec), [](const auto& p){return p.first;});
+                std::vector<std::string> activeMemoryNames;
+
+                // add all active memories to update list
+                std::transform(memoryReaders.begin(), memoryReaders.end(), std::back_inserter(activeMemoryNames), [](const auto& p){return p.first;});
 
                 TIMING_START(GuiUpdateAvailableMemories);
-                memoryGroup->queryWidget()->update(convVec);
+                memoryGroup->queryWidget()->update(activeMemoryNames);
                 TIMING_END_STREAM(GuiUpdateAvailableMemories, ARMARX_VERBOSE);
             }
             catch (...)
@@ -796,14 +809,16 @@ namespace armarx::armem::gui
     void
     MemoryViewer::updateMemoryTree()
     {
-        std::map<std::string, const armem::wm::Memory*> convMap;
+        std::map<std::string, const armem::wm::Memory*> memoriesToUpdate;
+
+        //auto checkboxStates = memoryGroup->queryWidget()->getAvailableMemoryStates();
         for (auto& [name, data] : memoryData)
         {
-            convMap[name] = &data;
+            memoriesToUpdate[name] = &data;
         }
 
         TIMING_START(GuiUpdateMemoryTree)
-        memoryGroup->tree()->update(convMap);
+        memoryGroup->tree()->update(memoriesToUpdate);
         TIMING_END_STREAM(GuiUpdateMemoryTree, ARMARX_VERBOSE)
 
         if (debugObserver)
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h
index 7be0874b265375827d22067e4325edcbf6c4bd12..69fb59d1c2f83b53ebd6587cfd63c148bcab9b7f 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h
@@ -110,7 +110,7 @@ namespace armarx::armem::gui
         void processQueryResults();
 
         void updateMemoryTree();
-        void updateAvailableMemories();
+        void updateListOfActiveMemories();
 
 
     signals:
diff --git a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp
index fe443952ce26bf9546c9238eaf1fa234f13368f6..a490d63436a484cee322d167a02675710c695260 100644
--- a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp
@@ -78,7 +78,7 @@ namespace armarx::armem::gui::disk
     void
     ControlWidget::storeOnDisk(
         QString directory,
-        const std::map<std::string, wm::Memory> memoryData,
+        const std::vector<wm::Memory> memoryData,
         std::string* outStatus)
     {
         std::filesystem::path path(directory.toUtf8().constData());
@@ -92,8 +92,9 @@ namespace armarx::armem::gui::disk
         else
         {
             int numStored = 0;
-            for (const auto& [name, data] : memoryData)
+            for (const auto& data : memoryData)
             {
+                std::string name = data.id().memoryName;
                 if (std::filesystem::is_regular_file(path / name))
                 {
                     status << "Could not export memory '" << name << "' to " << path << ": Cannot overwrite existing file.\n";
@@ -116,7 +117,7 @@ namespace armarx::armem::gui::disk
     }
 
 
-    std::map<std::string, wm::Memory>
+    std::map<std::filesystem::path, wm::Memory>
     ControlWidget::loadFromDisk(
         QString directory,
         const armem::client::QueryInput& _queryInput,
@@ -124,7 +125,7 @@ namespace armarx::armem::gui::disk
     {
         std::filesystem::path path(directory.toUtf8().constData());
 
-        std::map<std::string, wm::Memory> memoryData;
+        std::map<std::filesystem::path, wm::Memory> memoryData;
 
         auto setStatus = [&](const std::string& s){
             if (outStatus)
@@ -161,7 +162,7 @@ namespace armarx::armem::gui::disk
             }
         }
 
-        // TODO: Only add data that matchs query?
+        // TODO: Only add data that matches query?
         // We use LTM as query target for the disk
         // armem::client::QueryInput queryInput = _queryInput;
         // queryInput.addQueryTargetToAll(armem::query::data::QueryTarget::LTM);
@@ -172,8 +173,8 @@ namespace armarx::armem::gui::disk
             if (std::filesystem::is_directory(p))
             {
                 armem::server::ltm::disk::Memory ltm(p.parent_path(), p.filename());
-                armem::wm::Memory memory = ltm.loadAllAndResolve(); // load list of references
-                memoryData[memory.name()] = std::move(memory);
+                armem::wm::Memory memory = ltm.loadAllAndResolve(); // load list of references and load data
+                memoryData[p] = memory;
 
                 numLoaded++;
             }
diff --git a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.h b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.h
index b14c9b0a0810acbafba74638e6ebd87989e81165..5eb35b96057f0639a30d94df4dada8ecd38afd9a 100644
--- a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.h
+++ b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.h
@@ -5,6 +5,7 @@
 
 #include <QWidget>
 #include <QString>
+#include <filesystem>
 
 
 class QPushButton;
@@ -26,10 +27,10 @@ namespace armarx::armem::gui::disk
         void
         storeOnDisk(
             QString directory,
-            const std::map<std::string, wm::Memory> memoryData,
+            const std::vector<wm::Memory> memoryData,
             std::string* outStatus = nullptr);
 
-        std::map<std::string, wm::Memory>
+        std::map<std::filesystem::path, wm::Memory>
         loadFromDisk(
             QString directory,
             const armem::client::QueryInput& queryInput,
diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp
index 54e5aaec313825ae63bf8f15351339fce9288129..a3ce95672ec49cf3a3cffb426f28a04be4b43ccc 100644
--- a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp
@@ -162,8 +162,35 @@ namespace armarx::armem::gui
         return _dropDisabledCheckBox->isChecked();
     }
 
+    std::map<std::string, QueryWidget::ActiveMemoryState> QueryWidget::getAvailableMemoryStates() const
+    {
+        std::scoped_lock l(enabledMemoriesMutex);
+
+        std::map<std::string, QueryWidget::ActiveMemoryState> states;
+        int maxIndex = _availableMemoriesGroupBox->layout()->count();
+        for (int i = 0; i < maxIndex; ++i)
+        {
+            auto w = _availableMemoriesGroupBox->layout()->itemAt(i)->widget();
+            QCheckBox* box = static_cast<QCheckBox*>(w);
+            std::string memoryName = box->text().toStdString();
+            if (box->isEnabled() && box->isChecked())
+            {
+                states[memoryName] = ActiveMemoryState::FoundAndChecked;
+            }
+            else if (box->isEnabled() && !box->isChecked())
+            {
+                states[memoryName] = ActiveMemoryState::FoundAndNotChecked;
+            }
+            else
+            {
+                states[memoryName] = ActiveMemoryState::NotFound;
+            }
+        }
+        return states;
+    }
+
 
-    std::vector<std::string> QueryWidget::enabledMemories() const
+    std::vector<std::string> QueryWidget::getEnabledMemories() const
     {
         std::scoped_lock l(enabledMemoriesMutex);
 
diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h
index d3d534e5b4896d51d5d0a104852c1d6c64af982f..623b78c4126b6a09acd636c93b9d4c9b6f4934cf 100644
--- a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h
+++ b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h
@@ -22,6 +22,13 @@ namespace armarx::armem::gui
 
     public:
 
+        enum class ActiveMemoryState
+        {
+            FoundAndChecked,
+            FoundAndNotChecked,
+            NotFound
+        };
+
         QueryWidget();
 
         armem::query::DataMode dataMode() const;
@@ -31,7 +38,9 @@ namespace armarx::armem::gui
 
         int queryLinkRecursionDepth() const;
 
-        std::vector<std::string> enabledMemories() const;
+        std::map<std::string, ActiveMemoryState> getAvailableMemoryStates() const;
+
+        std::vector<std::string> getEnabledMemories() const;
 
         void update(const std::vector<std::string>& memoryNames);
 
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
index 3b22bf1d1368a51be9e3ea71da20b8a343f3079b..c17ce69020b2b7f2c363219339754919fc805723 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
@@ -178,7 +178,7 @@ namespace armarx::armem::server::obj::instance
         objpose::ObjectPoseSeq newObjectPoses;
         stats.numUpdated = 0;
 
-        // timestamp used to reduce the rpc calls for robot sync 
+        // timestamp used to reduce the rpc calls for robot sync
         Time robotSyncTimestamp = Time::Invalid();
 
         for (const objpose::data::ProvidedObjectPose& provided : providedPoses)
@@ -1317,7 +1317,7 @@ namespace armarx::armem::server::obj::instance
 
             if (robot)
             {
-                reader->synchronizeRobot(*robot, Clock::Now());
+                ARMARX_CHECK(reader->synchronizeRobot(*robot, Clock::Now()));
                 // Store robot if valid.
                 loaded.emplace(robotName, robot);
             }
diff --git a/source/RobotAPI/libraries/armem_objects/types.h b/source/RobotAPI/libraries/armem_objects/types.h
index c7e4fe4897c46202543e3d12628cf22e8083b0b3..79fe9ac956f65869ceb03b35db8545155c4c963c 100644
--- a/source/RobotAPI/libraries/armem_objects/types.h
+++ b/source/RobotAPI/libraries/armem_objects/types.h
@@ -23,6 +23,7 @@
 
 #include <Eigen/Geometry>
 
+#include <RobotAPI/libraries/ArmarXObjects/ObjectPose.h>
 #include <RobotAPI/libraries/armem/core/MemoryID.h>
 #include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem_robot/types.h>
@@ -31,6 +32,16 @@
 #include "aron_forward_declarations.h"
 
 
+namespace armarx::armem
+{
+    struct ObjectInstance
+    {
+        objpose::ObjectPose pose;
+        MemoryID classID;
+        MemoryID sourceID;
+    };
+}
+
 namespace armarx::armem::attachment
 {
     using AgentID = armem::MemoryID;
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h
index 19a184e8c4cee71e2a7866206f2ae55cd51f0d27..ab30cbc1317d98f802dc24cbe5d844da02b038e9 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h
@@ -27,7 +27,6 @@
 
 #include "RobotReader.h"
 
-
 namespace armarx::armem::robot_state
 {
     /**
@@ -47,7 +46,8 @@ namespace armarx::armem::robot_state
         void connect();
         void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def);
 
-        bool synchronizeRobot(VirtualRobot::Robot& robot, const armem::Time& timestamp);
+        [[nodiscard]] bool synchronizeRobot(VirtualRobot::Robot& robot,
+                                            const armem::Time& timestamp);
 
         [[nodiscard]] VirtualRobot::RobotPtr
         getRobot(const std::string& name,
@@ -70,14 +70,12 @@ namespace armarx::armem::robot_state
 
 
     private:
-
         [[nodiscard]] VirtualRobot::RobotPtr
         _getSynchronizedRobot(const std::string& name,
                               const armem::Time& timestamp = armem::Time::Invalid(),
                               const VirtualRobot::RobotIO::RobotDescription& loadMode =
-                                 VirtualRobot::RobotIO::RobotDescription::eStructure,
+                                  VirtualRobot::RobotIO::RobotDescription::eStructure,
                               bool blocking = true);
-
     };
 
 } // namespace armarx::armem::robot_state
diff --git a/source/RobotAPI/libraries/aron/CMakeLists.txt b/source/RobotAPI/libraries/aron/CMakeLists.txt
index ce4f7bc99cb8d923decfdd7fdb79390837e79150..e1ccc8560ff75b018fbc958d0f1febf0512d9590 100644
--- a/source/RobotAPI/libraries/aron/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/CMakeLists.txt
@@ -2,3 +2,4 @@ add_subdirectory(core)
 add_subdirectory(converter)
 add_subdirectory(codegeneration)
 add_subdirectory(common)
+add_subdirectory(test)
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/Writer.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/Writer.cpp
index 72a657218790d389d14283f7c22fb02ce183c357..85c6403e5e4452848c31ffbc3f59aa39c3fe46ee 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/Writer.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/Writer.cpp
@@ -253,7 +253,6 @@ namespace armarx::aron::codegenerator::cpp
             c->addInherit("public armarx::aron::cpp::AronGeneratedClass");
 
             // ctor
-            c->addCtor(generator.toCopyCtor(c->getName()));
             c->addCtor(generator.toInnerEnumCtor(c->getName()));
 
             // Specific methods
@@ -336,6 +335,10 @@ namespace armarx::aron::codegenerator::cpp
 
         // ctor
         c->addCtor(gen.toCtor(c->getName()));
+        c->addCtor(gen.toCopyCtor(c->getName()));
+
+        // dtor
+        c->addMethod(gen.toDtor(c->getName()));
 
         // Generic methods
         //std::cout << "Generate equals method" << std::endl;
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.cpp
index 72f2eb78f04b610b0be55fc7a4d9fdabb90cab6d..be87200f51f745b314ef7f3f7c2a67beb18d332a 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.cpp
@@ -41,6 +41,7 @@ namespace armarx::aron::codegenerator::cpp
     const std::string Generator::ARON_TEMPLATE_INSTANTIATIONS_ACCESSOR = Generator::ARON_VARIABLE_PREFIX + "_tmpls";
     const std::string Generator::ARON_VARIANT_RETURN_ACCESSOR = Generator::ARON_VARIABLE_PREFIX + "_variant";
     const std::string Generator::ARON_PATH_ACCESSOR = Generator::ARON_VARIABLE_PREFIX + "_p";
+    const std::string Generator::ARON_OTHER_ACCESSOR = Generator::ARON_VARIABLE_PREFIX + "_o";
 
     const SerializerFactoryPtr Generator::FACTORY = SerializerFactoryPtr(new GeneratorFactory());
 
@@ -168,17 +169,55 @@ namespace armarx::aron::codegenerator::cpp
 
     CppCtorPtr Generator::toCtor(const std::string& name) const
     {
-        CppCtorPtr c = CppCtorPtr(new CppCtor(name + "()"));
-        std::vector<std::pair<std::string, std::string>> initList = this->getCtorInitializers("");
-        CppBlockPtr b = std::make_shared<CppBlock>();
-        b->addLine("resetHard();");
-        b->appendBlock(this->getCtorBlock(""));
-        c->addInitListEntries(initList);
-        c->setBlock(b);
+        CppBlockPtr b = this->getCtorBlock("");
+        auto initList = this->getCtorInitializers("");
+
+        if (b->size() > 0 || initList.second)
+        {
+            CppCtorPtr c = CppCtorPtr(new CppCtor(name + "()"));
+            c->addInitListEntries(initList.first);
+            c->setBlock(b);
+            return c;
+        }
+
+        CppCtorPtr c = CppCtorPtr(new CppCtor(name + "() = default;"));
+        return c;
+    }
 
+    CppCtorPtr Generator::toCopyCtor(const std::string& name) const
+    {
+        CppBlockPtr b = this->getCopyCtorBlock("");
+        auto initList = this->getCopyCtorInitializers("");
+
+        if (b->size() > 0 || initList.second)
+        {
+            CppCtorPtr c = CppCtorPtr(new CppCtor(name + "(const " + name + "& " + ARON_OTHER_ACCESSOR + ")"));
+            c->addInitListEntries(initList.first);
+            c->setBlock(b);
+            return c;
+        }
+
+        CppCtorPtr c = CppCtorPtr(new CppCtor(name + "(const " + name + "& " + ARON_OTHER_ACCESSOR + ") = default;"));
         return c;
     }
 
+    CppMethodPtr Generator::toDtor(const std::string& name) const
+    {
+        CppBlockPtr b = this->getDtorBlock("");
+        if (b->size() > 0)
+        {
+            CppMethodPtr m = CppMethodPtr(new CppMethod("virtual ~" + name + "()"));
+            m->setBlock(b);
+
+            m->setEnforceBlockGeneration(true);
+            return m;
+        }
+
+        CppMethodPtr m = CppMethodPtr(new CppMethod("virtual ~" + name + "() = default;"));
+        m->setEnforceBlockGeneration(false);
+        return m;
+    }
+
     CppMethodPtr Generator::toResetSoftMethod() const
     {
         std::stringstream doc;
@@ -188,6 +227,8 @@ namespace armarx::aron::codegenerator::cpp
         CppMethodPtr m = CppMethodPtr(new CppMethod("virtual void resetSoft() override", doc.str()));
         CppBlockPtr b = this->getResetSoftBlock("");
         m->setBlock(b);
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -200,6 +241,8 @@ namespace armarx::aron::codegenerator::cpp
         CppMethodPtr m = CppMethodPtr(new CppMethod("virtual void resetHard() override", doc.str()));
         CppBlockPtr b = this->getResetHardBlock("");
         m->setBlock(b);
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -216,6 +259,8 @@ namespace armarx::aron::codegenerator::cpp
         std::string dummy;
         b->appendBlock(this->getWriteTypeBlock("", "", Path(), dummy));
         m->setBlock(b);
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -237,6 +282,7 @@ namespace armarx::aron::codegenerator::cpp
         b->addLineAsBlock("throw ::armarx::aron::error::AronException(__PRETTY_FUNCTION__, std::string(\"An error occured during the write method of an aron generated class. The full error log was:\\n\") + " + ARON_VARIABLE_PREFIX + "_e.what());");
 
         m->setBlock(b);
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -260,6 +306,8 @@ namespace armarx::aron::codegenerator::cpp
         b->addLine("catch(const std::exception& " + ARON_VARIABLE_PREFIX + "_e)");
         b->addLineAsBlock("throw ::armarx::aron::error::AronException(__PRETTY_FUNCTION__, std::string(\"An error occured during the read method of an aron generated class. The full error log was:\\n\") + " + ARON_VARIABLE_PREFIX + "_e.what());");
         m->setBlock(b);
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -272,6 +320,8 @@ namespace armarx::aron::codegenerator::cpp
         CppMethodPtr m = CppMethodPtr(new CppMethod(info.returnType + " " + info.methodName + "() const", doc.str()));
         m->addLine(info.writerClassType + " writer;");
         m->addLine("return " + info.enforceConversion + "(this->write(writer))" + info.enforceMemberAccess + ";");
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -284,6 +334,8 @@ namespace armarx::aron::codegenerator::cpp
         CppMethodPtr m = CppMethodPtr(new CppMethod("void " + info.methodName + "(const " + info.argumentType + "& input)", doc.str()));
         m->addLine(info.readerClassType + " reader;");
         m->addLine("this->read(reader, " + info.enforceConversion + "(input)" + info.enforceMemberAccess + ");");
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -297,6 +349,8 @@ namespace armarx::aron::codegenerator::cpp
         m->addLine(info.returnType + " t;");
         m->addLine("t.fromAron(input);");
         m->addLine("return t;");
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -309,6 +363,8 @@ namespace armarx::aron::codegenerator::cpp
         CppMethodPtr m = CppMethodPtr(new CppMethod("static " + info.returnType + " " + info.methodName + "()", doc.str()));
         m->addLine(info.writerClassType + " writer;");
         m->addLine("return " + info.enforceConversion + "(writeType(writer))" + info.enforceMemberAccess + ";");
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -323,6 +379,8 @@ namespace armarx::aron::codegenerator::cpp
         CppBlockPtr b = this->getEqualsBlock("", "i");
         b->addLine("return true;");
         m->setBlock(b);
+
+        m->setEnforceBlockGeneration(true);
         return m;
     }
 
@@ -337,9 +395,9 @@ namespace armarx::aron::codegenerator::cpp
         return {field};
     }
 
-    std::vector<std::pair<std::string, std::string>> Generator::getCtorInitializers(const std::string&) const
+    std::pair<std::vector<std::pair<std::string, std::string>>, bool> Generator::getCtorInitializers(const std::string&) const
     {
-        return {};
+        return {{}, false};
     }
 
     CppBlockPtr Generator::getCtorBlock(const std::string&) const
@@ -347,6 +405,27 @@ namespace armarx::aron::codegenerator::cpp
         return std::make_shared<CppBlock>();
     }
 
+    std::pair<std::vector<std::pair<std::string, std::string>>, bool> Generator::getCopyCtorInitializers(const std::string& name) const
+    {
+        const auto& t = getType();
+        if (t.getMaybe() == type::Maybe::UNIQUE_PTR || t.getMaybe() == type::Maybe::RAW_PTR)
+        {
+            return {{{name, ARON_OTHER_ACCESSOR + "." + name + " ? " + resolveMaybeGenerator("*" + ARON_OTHER_ACCESSOR + "." + name) + " : nullptr"}}, true};
+        }
+
+        return {{{name, ARON_OTHER_ACCESSOR + "." + name}}, false};
+    }
+
+    CppBlockPtr Generator::getCopyCtorBlock(const std::string&) const
+    {
+        return std::make_shared<CppBlock>();
+    }
+
+    CppBlockPtr Generator::getDtorBlock(const std::string&) const
+    {
+        return std::make_shared<CppBlock>();
+    }
+
     CppBlockPtr Generator::getResetHardBlock(const std::string& cppAccessor) const
     {
         CppBlockPtr block_if_data = std::make_shared<CppBlock>();
@@ -388,24 +467,35 @@ namespace armarx::aron::codegenerator::cpp
         return s;
     }
 
-    std::string Generator::resolveMaybeGenerator(const std::string& s) const
+    std::string Generator::resolveMaybeGenerator(const std::string& args) const
     {
         const auto& t = getType();
         if (t.getMaybe() == type::Maybe::OPTIONAL)
         {
-            return s + " = std::make_optional<" + getInstantiatedCppTypename() + ">();";
+            return "std::make_optional<" + getInstantiatedCppTypename() + ">(" + args + ")";
         }
         if (t.getMaybe() == type::Maybe::RAW_PTR)
         {
-            return s + " = new " + getInstantiatedCppTypename() + "();";
+            return "new " + getInstantiatedCppTypename() + "(" + args + ")";
         }
         if (t.getMaybe() == type::Maybe::SHARED_PTR)
         {
-            return s + " = std::make_shared<" + getInstantiatedCppTypename() + ">();";
+            return "std::make_shared<" + getInstantiatedCppTypename() + ">(" + args + ")";
         }
         if (t.getMaybe() == type::Maybe::UNIQUE_PTR)
         {
-            return s + " = std::make_unique<" + getInstantiatedCppTypename() + ">();";
+            return "std::make_unique<" + getInstantiatedCppTypename() + ">(" + args + ")";
+        }
+        return "";
+
+    }
+
+    std::string Generator::resolveMaybeGeneratorWithSetter(const std::string& s, const std::string& args) const
+    {
+        auto gen = resolveMaybeGenerator(args);
+        if (!gen.empty())
+        {
+            return s + " = " + gen + ";";
         }
         return "";
     }
@@ -496,7 +586,7 @@ namespace armarx::aron::codegenerator::cpp
             b->addLine("if (not (" + ARON_READER_ACCESSOR + ".readNull(" + variantAccessor + "))) // if aron contains data");
             {
                 CppBlockPtr ifb = std::make_shared<CppBlock>();
-                ifb->addLine(resolveMaybeGenerator(cppAccessor));
+                ifb->addLine(resolveMaybeGeneratorWithSetter(cppAccessor));
                 ifb->appendBlock(block_if_data);
                 b->addBlock(ifb);
             }
@@ -520,5 +610,3 @@ namespace armarx::aron::codegenerator::cpp
         return block_if_data;
     }
 }
-
-
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.h
index 7b9c15a7d4c6f1409db4999b906933bff64f3370..18bec1e225a6fbae97c71c10a7bd82a21ba5604b 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/Generator.h
@@ -91,9 +91,16 @@ namespace armarx::aron::codegenerator::cpp
         virtual std::vector<CppFieldPtr> getPublicVariableDeclarations(const std::string&) const;
 
         CppCtorPtr toCtor(const std::string&) const;
-        virtual std::vector<std::pair<std::string, std::string>> getCtorInitializers(const std::string&) const;
+        virtual std::pair<std::vector<std::pair<std::string, std::string>>, bool> getCtorInitializers(const std::string&) const;
         virtual CppBlockPtr getCtorBlock(const std::string&) const;
 
+        CppCtorPtr toCopyCtor(const std::string&) const;
+        virtual std::pair<std::vector<std::pair<std::string, std::string>>, bool> getCopyCtorInitializers(const std::string&) const;
+        virtual CppBlockPtr getCopyCtorBlock(const std::string&) const;
+
+        CppMethodPtr toDtor(const std::string&) const;
+        virtual CppBlockPtr getDtorBlock(const std::string&) const;
+
         CppMethodPtr toResetSoftMethod() const;
         virtual CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const;
 
@@ -127,7 +134,8 @@ namespace armarx::aron::codegenerator::cpp
         std::string toPointerAccessor(const std::string&) const;
 
         std::string resolveMaybeAccessor(const std::string&) const;
-        std::string resolveMaybeGenerator(const std::string&) const;
+        std::string resolveMaybeGenerator(const std::string& args = "") const;
+        std::string resolveMaybeGeneratorWithSetter(const std::string&, const std::string& args = "") const;
 
         CppBlockPtr resolveMaybeResetHardBlock(const CppBlockPtr&, const std::string&) const;
         CppBlockPtr resolveMaybeResetSoftBlock(const CppBlockPtr&, const std::string&) const;
@@ -144,6 +152,7 @@ namespace armarx::aron::codegenerator::cpp
         static const std::string ARON_WRITER_ACCESSOR;
         static const std::string ARON_TEMPLATE_INSTANTIATIONS_ACCESSOR;
         static const std::string ARON_VARIANT_RETURN_ACCESSOR;
+        static const std::string ARON_OTHER_ACCESSOR;
 
     private:
         static const SerializerFactoryPtr FACTORY;
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.cpp
index 5b734427b84bbd9fa139f6518110b55b7daf48ae..617a658199e8380a3c6fe02ad13a5a13fad1e886 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.cpp
@@ -57,7 +57,7 @@ namespace armarx::aron::codegenerator::cpp::generator
             bool b = std::find(x.disallowedBases.begin(), x.disallowedBases.end(), t.getPath().getRootIdentifier()) == x.disallowedBases.end();
             return b;
         }
-        return true;
+        return false;
     }
 
     std::string checkForInstantiationTypenameReplacement(const type::Object& t)
@@ -99,7 +99,8 @@ namespace armarx::aron::codegenerator::cpp::generator
             checkForInstantiationTypenameReplacement(e),
             checkForClassNameReplacement(e),
             simox::meta::get_type_name<data::dto::Dict>(),
-            simox::meta::get_type_name<type::dto::AronObject>(), e)
+            simox::meta::get_type_name<type::dto::AronObject>(), e),
+        has_been_replaced(checkForAllowedReplacement(e))
     {
     }
 
@@ -160,7 +161,7 @@ namespace armarx::aron::codegenerator::cpp::generator
         std::string escaped_accessor = EscapeAccessor(cppAccessor);
         std::string resolved_accessor = resolveMaybeAccessor(cppAccessor);
 
-        if (const auto reset = resolveMaybeGenerator(cppAccessor); !reset.empty())
+        if (const auto reset = resolveMaybeGeneratorWithSetter(cppAccessor); !reset.empty())
         {
             block_if_data->addLine(reset);
         }
@@ -169,5 +170,31 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         return resolveMaybeReadBlock(block_if_data, cppAccessor, variantAccessor);
     }
+
+
+
+    CppBlockPtr Object::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        if (has_been_replaced)
+        {
+            return Base::getResetHardBlock(cppAccessor);
+        }
+
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + nextEl() + "resetHard();");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr Object::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        if (has_been_replaced)
+        {
+            return Base::getResetHardBlock(cppAccessor);
+        }
+
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + nextEl() + "resetSoft();");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
 
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.h
index b1a2995c443f4e680725fdcbfbf4ac6374d7c712..942dc161a8792b9b9455c08db5c40eba79260605 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/container/Object.h
@@ -37,12 +37,14 @@ namespace armarx::aron::codegenerator::cpp::generator
         std::string replacedInstantiatedTypename;
 
         std::vector<std::string> additionalIncludes; // additional includes for the replaced type and aron conversions
-        std::vector<std::string> disallowedBases; // disallow replacement if the used in a specific class
+        std::vector<std::string> disallowedBases; // disallow replacement if used in a specific class
     };
 
     class Object :
         public detail::ContainerGenerator<type::Object, Object>
     {
+        using Base = detail::ContainerGenerator<type::Object, Object>;
+
     public:
         // constructors
         Object(const type::Object&);
@@ -53,5 +55,10 @@ namespace armarx::aron::codegenerator::cpp::generator
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path&, std::string& variantAccessor) const final;
         CppBlockPtr getWriteBlock(const std::string& cppAccessor, const Path&, std::string& variantAccessor) const final;
         CppBlockPtr getReadBlock(const std::string& cppAccessor, const std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
+
+    private:
+        bool has_been_replaced = false;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/enum/IntEnum.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/enum/IntEnum.cpp
index c818db64a05d881f8f3efee3ae9d2a767c8383ed..00a9ab35d7f52eb757963c97355403377459737e 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/enum/IntEnum.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/enum/IntEnum.cpp
@@ -88,7 +88,7 @@ namespace armarx::aron::codegenerator::cpp::generator
     CppBlockPtr IntEnum::getReadBlock(const std::string& cppAccessor, const std::string& variantAccessor) const
     {
         CppBlockPtr block_if_data = std::make_shared<CppBlock>();
-        if (const auto reset = resolveMaybeGenerator(cppAccessor); !reset.empty())
+        if (const auto reset = resolveMaybeGeneratorWithSetter(cppAccessor); !reset.empty())
         {
             block_if_data->addLine(reset);
         }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.cpp
index fb3572e26adb9a61cf7bcde1396a1a2cb4bfff26..7dcadbb33ae84d70a180e89763ca37a634946268 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.cpp
@@ -49,4 +49,18 @@ namespace armarx::aron::codegenerator::cpp::generator
                    "armarx::aron::Path("+ARON_PATH_ACCESSOR+", {"+simox::alg::join(p.getPath(), ", ")+"})); // of " + typeAccessor);
         return b;
     }
+
+    CppBlockPtr Bool::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = false;");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr Bool::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = false;");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.h
index 85172f3de8745ac5b2feb465cd9ff8408e94cd56..381adec7bc759c7a20aedd54229dd499253110d1 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Bool.h
@@ -40,5 +40,7 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         /* virtual implementations */
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path& p, std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.cpp
index 7076794550d8e149f496677c079da4a3b7517e03..735f3ad9dc4efdf0f00a34093671644aebb0eb3f 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.cpp
@@ -50,4 +50,18 @@ namespace armarx::aron::codegenerator::cpp::generator
                    "armarx::aron::Path("+ARON_PATH_ACCESSOR+", {"+simox::alg::join(p.getPath(), ", ")+"})); // of " + typeAccessor);
         return b;
     }
+
+    CppBlockPtr Double::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0.0;");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr Double::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0.0;");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.h
index e109cc626500ce4004f2b69b670ed9574c947ea5..b9a96a077e225aad5b0871882e86e20f85fb3685 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Double.h
@@ -39,5 +39,7 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         /* virtual implementations */
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path& p, std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.cpp
index 6c740a79206d323e0b6e9bf0b66c19d82eb1593a..d3d27ea6c34713b3d81074c1ab64e37ed696d69c 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.cpp
@@ -50,4 +50,18 @@ namespace armarx::aron::codegenerator::cpp::generator
                    "armarx::aron::Path("+ARON_PATH_ACCESSOR+", {"+simox::alg::join(p.getPath(), ", ")+"})); // of " + typeAccessor);
         return b;
     }
+
+    CppBlockPtr Float::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0.0f;");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr Float::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0.0f;");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.h
index a2f52f4fb7d78ebcefcd96ba3eba8d0b31fc7dcb..f1c88c502f92b7d86afc7668eda0710f0f3351b7 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Float.h
@@ -39,5 +39,7 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         /* virtual implementations */
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path& p, std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.cpp
index 9242126f54ae10d3ee26fd6e242de8014c6a23f7..7a976bd83fffa4ad52bec05c2a5392bbf7400798 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.cpp
@@ -50,4 +50,18 @@ namespace armarx::aron::codegenerator::cpp::generator
                    "armarx::aron::Path("+ARON_PATH_ACCESSOR+", {"+simox::alg::join(p.getPath(), ", ")+"})); // of " + typeAccessor);
         return b;
     }
+
+    CppBlockPtr Int::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0;");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr Int::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0;");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.h
index eb18e445473f402c2be373da523ba92336a4ab48..b21abee9cef1850a1d55da0369a530b65585c210 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Int.h
@@ -39,5 +39,7 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         /* virtual implementations */
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path& p, std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.cpp
index 2231f3305264746bb5c31855cac0e6a5c3d712b0..fe6cd5e87f6f3db26873c351987f91d86556d27b 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.cpp
@@ -50,4 +50,18 @@ namespace armarx::aron::codegenerator::cpp::generator
                    "armarx::aron::Path("+ARON_PATH_ACCESSOR+", {"+simox::alg::join(p.getPath(), ", ")+"})); // of " + typeAccessor);
         return b;
     }
+
+    CppBlockPtr Long::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0;");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr Long::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = 0;");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.h
index 8e74bf85b421ff3101af4f86a3edcdc91858559a..09d923e487108a7c2c0927156af77c21fddf79ec 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/Long.h
@@ -39,5 +39,7 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         /* virtual implementations */
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path& p, std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.cpp
index a335fafcbd33ffca5c0a1658aaa1da5ccfeb4cc6..d51ee9ed159a5abb82442a5501ffebb3500aad15 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.cpp
@@ -50,4 +50,18 @@ namespace armarx::aron::codegenerator::cpp::generator
                    "armarx::aron::Path("+ARON_PATH_ACCESSOR+", {"+simox::alg::join(p.getPath(), ", ")+"})); // of " + typeAccessor);
         return b;
     }
+
+    CppBlockPtr String::getResetHardBlock(const std::string& cppAccessor) const
+    {
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = \"\";");
+        return resolveMaybeResetHardBlock(block_if_data, cppAccessor);
+    }
+
+    CppBlockPtr String::getResetSoftBlock(const std::string& cppAccessor) const
+    {
+        auto block_if_data = std::make_shared<CppBlock>();
+        block_if_data->addLine(cppAccessor + " = \"\";");
+        return this->resolveMaybeResetSoftBlock(block_if_data, cppAccessor);
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.h
index 7db96c8713e04a479d4f1623043f633d4d429f84..fd854ccee807d549fbe1448643eb31a4f069bcc8 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/primitive/String.h
@@ -39,5 +39,7 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         /* virtual implementations */
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path& p, std::string& variantAccessor) const final;
+        CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
+        CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.cpp
index 4e5b54e5c6a41bd74147a5445d4d5abdb298b5a4..f5463258db1423ba317c428b2d604907b913755a 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.cpp
@@ -150,12 +150,18 @@ namespace armarx::aron::codegenerator::cpp::generator
     }
 
 
-    CppCtorPtr IntEnumClass::toCopyCtor(const std::string& name) const
+    /*CppCtorPtr IntEnumClass::toCopyCtor(const std::string& name) const
     {
         CppCtorPtr c = std::make_shared<CppCtor>(name + "(const " + getFullInstantiatedCppTypename() + "& i)");
         std::vector<std::pair<std::string, std::string>> initList = {{"value", "i.value"}};
         c->addInitListEntries(initList);
+        c->setBlock(std::make_shared<CppBlock>());
         return c;
+    }*/
+
+    std::pair<std::vector<std::pair<std::string, std::string>>, bool> IntEnumClass::getCopyCtorInitializers(const std::string&) const
+    {
+        return {{{"value", ARON_OTHER_ACCESSOR + ".value"}}, false};
     }
 
     CppCtorPtr IntEnumClass::toInnerEnumCtor(const std::string& name) const
@@ -163,6 +169,7 @@ namespace armarx::aron::codegenerator::cpp::generator
         CppCtorPtr c = std::make_shared<CppCtor>(name + "(const " + std::string(IMPL_ENUM) + " e)");
         std::vector<std::pair<std::string, std::string>> initList = {{"value", "e"}};
         c->addInitListEntries(initList);
+        c->setBlock(std::make_shared<CppBlock>());
         return c;
     }
 
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.h
index b03310d425bb6783f618e9548d573a87b87c77dc..10d6ca0c14d8100e71d78944f24fd3f46870b8e1 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/IntEnumClass.h
@@ -42,6 +42,9 @@ namespace armarx::aron::codegenerator::cpp::generator
 
         // virtual implementations
         std::vector<CppFieldPtr> getPublicVariableDeclarations(const std::string&) const final;
+
+        std::pair<std::vector<std::pair<std::string, std::string>>, bool> getCopyCtorInitializers(const std::string&) const final;
+
         CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
         CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path&, std::string& variantAccessor) const final;
@@ -50,7 +53,7 @@ namespace armarx::aron::codegenerator::cpp::generator
         CppBlockPtr getEqualsBlock(const std::string&, const std::string&) const final;
 
         // TODO: Move some of those methods to upper class for enums (if we want to support multiple enums)
-        CppCtorPtr toCopyCtor(const std::string&) const;
+        //CppCtorPtr toCopyCtor(const std::string&) const;
         CppCtorPtr toInnerEnumCtor(const std::string&) const;
         CppEnumPtr toInnerEnumDefinition() const;
         CppMethodPtr toIntMethod() const;
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.cpp b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.cpp
index 5d5409792c245220df2a0f4918c02ef9412fa6af..e3af89daa12ecc2de2f4fe60d9269dd48f729c9a 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.cpp
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.cpp
@@ -238,4 +238,25 @@ namespace armarx::aron::codegenerator::cpp::generator
         }
         return block_if_data;
     }
+
+    std::pair<std::vector<std::pair<std::string, std::string>>, bool> ObjectClass::getCopyCtorInitializers(const std::string&) const
+    {
+        std::vector<std::pair<std::string, std::string>> ret;
+
+        if (type.getExtends() != nullptr)
+        {
+            const auto extends_s = FromAronType(*type.getExtends());
+            ret.push_back({extends_s->getFullInstantiatedCppTypename(), ARON_OTHER_ACCESSOR});
+        }
+
+        bool anyComplex = false;
+        for (const auto& [key, child] : type.getMemberTypes())
+        {
+            auto child_s = FromAronType(*child);
+            auto initList = child_s->getCopyCtorInitializers(key);
+            simox::alg::append(ret, initList.first);
+            anyComplex = anyComplex || initList.second;
+        }
+        return {ret, anyComplex};
+    }
 }
diff --git a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.h b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.h
index dd8e7d3d95bb291a54aeba45d46bae8bbf336834..772d138cb7cc521753ce6bd3086bb076d475b462 100644
--- a/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.h
+++ b/source/RobotAPI/libraries/aron/codegeneration/codegenerator/codewriter/cpp/generator/toplevel/ObjectClass.h
@@ -40,6 +40,9 @@ namespace armarx::aron::codegenerator::cpp::generator
         // virtual implementations
         std::vector<std::string> getRequiredIncludes() const final;
         std::vector<CppFieldPtr> getPublicVariableDeclarations(const std::string&) const final;
+
+        std::pair<std::vector<std::pair<std::string, std::string>>, bool> getCopyCtorInitializers(const std::string&) const final;
+
         CppBlockPtr getResetHardBlock(const std::string& cppAccessor) const final;
         CppBlockPtr getResetSoftBlock(const std::string& cppAccessor) const final;
         CppBlockPtr getWriteTypeBlock(const std::string& typeAccessor, const std::string& cppAccessor, const Path&, std::string& variantAccessor) const final;
diff --git a/source/RobotAPI/libraries/aron/converter/binary/CMakeLists.txt b/source/RobotAPI/libraries/aron/converter/binary/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7fa2684a23d3ef1e887a5f11b1c5aa83cbbe4b8f
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/converter/binary/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(LIB_NAME aronivtconverter)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+armarx_build_if(IVT_FOUND "IVT not available")
+armarx_build_if(OpenCV_FOUND "OpenCV not available")
+
+set(LIBS
+    aron 
+    ivt 
+    ivtopencv
+
+    ${IVT_LIBRARIES}
+)
+
+set(LIB_FILES
+    IVTConverter.cpp
+)
+
+set(LIB_HEADERS
+    IVTConverter.h
+)
+
+armarx_add_library("${LIB_NAME}" "${LIB_FILES}" "${LIB_HEADERS}" "${LIBS}")
+
+if(IVT_FOUND)
+    target_include_directories(aronivtconverter
+        SYSTEM PUBLIC 
+            ${IVT_INCLUDE_DIRS}
+    )
+endif()
+
+add_library(RobotAPI::aron::converter::ivt ALIAS aronivtconverter)
diff --git a/source/RobotAPI/libraries/aron/converter/binary/LTMVectorRepresentationConverter.cpp b/source/RobotAPI/libraries/aron/converter/binary/LTMVectorRepresentationConverter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..999359d6b79ef56bbe7352263556ad71316e7384
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/converter/binary/LTMVectorRepresentationConverter.cpp
@@ -0,0 +1,53 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
+ * Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author     Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+// STD/STL
+#include <numeric>
+
+// Header
+#include "IVTConverter.h"
+
+namespace armarx::aron::converter
+{
+    std::shared_ptr<CByteImage> AronIVTConverter::ConvertToCByteImage(const data::NDArrayPtr& nav)
+    {
+        ARMARX_CHECK_NOT_NULL(nav);
+
+        if (nav->getShape().size() != 3) // +1 for bytes per pixel
+        {
+            throw error::AronException(__PRETTY_FUNCTION__, "The size of an NDArray does not match.", nav->getPath());
+        }
+        auto dims = nav->getShape();
+
+        auto ret = std::make_shared<CByteImage>();
+        ret->Set(dims[0], dims[1], static_cast<CByteImage::ImageType>(std::stoi(nav->getType())));
+        memcpy(reinterpret_cast<unsigned char*>(ret->pixels), nav->getData(), std::accumulate(std::begin(dims), std::end(dims), 1, std::multiplies<int>()));
+        return ret;
+    }
+
+    data::NDArrayPtr ConvertFromCByteImage(const std::shared_ptr<CByteImage>& img)
+    {
+        // TODO:
+        return nullptr;
+    }
+}
diff --git a/source/RobotAPI/libraries/aron/converter/binary/LTMVectorRepresentationConverter.h b/source/RobotAPI/libraries/aron/converter/binary/LTMVectorRepresentationConverter.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d0c23d3b598c7dc55334c7181fa39885ee15ce4
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/converter/binary/LTMVectorRepresentationConverter.h
@@ -0,0 +1,45 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @author     Fabian Peller (fabian dot peller at kit dot edu)
+* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#pragma once
+
+// STD/STL
+#include <memory>
+#include <string>
+
+// IVT
+#include <Image/ByteImage.h>
+
+// ArmarX
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <RobotAPI/interface/aron.h>
+#include <RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h>
+
+
+namespace armarx::aron::converter
+{
+    class AronIVTConverter
+    {
+        AronIVTConverter() = delete;
+    public:
+        static std::shared_ptr<CByteImage> ConvertToCByteImage(const data::NDArrayPtr&);
+        static data::NDArrayPtr ConvertFromCByteImage(const std::shared_ptr<CByteImage>&);
+    };
+}
diff --git a/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp b/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp
index e6429e7fe75ba54fea8a38c6f41398c0d149d2a5..3729e90a5812a192c256f2deaaa13bbecad71bab 100644
--- a/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp
+++ b/source/RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.cpp
@@ -1,5 +1,7 @@
 #include "NLohmannJSONConverter.h"
 
+#include <ArmarXCore/core/logging/Logging.h>
+
 namespace armarx::aron::converter
 {
     nlohmann::json AronNlohmannJSONConverter::ConvertToNlohmannJSON(const data::VariantPtr& aron)
diff --git a/source/RobotAPI/libraries/aron/core/Exception.h b/source/RobotAPI/libraries/aron/core/Exception.h
index 5395c9eb65d2a61632ab56ad5ee1704a8679e6e1..fc080bafd09e2d7424bf0fc18538539f680329da 100644
--- a/source/RobotAPI/libraries/aron/core/Exception.h
+++ b/source/RobotAPI/libraries/aron/core/Exception.h
@@ -26,6 +26,7 @@
 // STD/STL
 
 // ArmarX
+#include <ArmarXCore/core/logging/Logging.h>
 #include <RobotAPI/interface/aron.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/core/exceptions/Exception.h>
diff --git a/source/RobotAPI/libraries/aron/core/aron_conversions.h b/source/RobotAPI/libraries/aron/core/aron_conversions.h
index d0f88cab840be59b86bbeb22d7229afb9f9f0b48..d27d6415877d4c15f9ddf36310e656590f8efd7e 100644
--- a/source/RobotAPI/libraries/aron/core/aron_conversions.h
+++ b/source/RobotAPI/libraries/aron/core/aron_conversions.h
@@ -3,12 +3,29 @@
 #include <map>
 #include <memory>
 #include <optional>
+#include <type_traits>
 #include <vector>
 
 #include "Path.h"
 
 namespace armarx::aron
 {
+
+namespace detail
+{
+
+    // Helper concept to avoid ambiguities
+    template<typename DtoT, typename BoT>
+    concept DtoAndBoAreSame = std::is_same<DtoT, BoT>::value;
+
+    template <class ...>
+    struct is_optional : public std::false_type {};
+
+    template <class ...Ts>
+    struct is_optional<std::optional<Ts...>> : public std::true_type {};
+
+}
+
     /**
      * Framework for converting ARON DTOs (Data Transfer Objects) to C++ BOs
      * (Business Objects) and back.
@@ -51,12 +68,6 @@ namespace armarx::aron
      * }
      * @endcode
      */
-
-    // Helper concept to avoid ambiguities
-    template<typename DtoT, typename BoT>
-    concept DtoAndBoAreSame = std::is_same<DtoT, BoT>::value;
-
-
     // Same type
     template <class T>
     void toAron(T& dto, const T& bo)
@@ -139,6 +150,24 @@ namespace armarx::aron
         }
     }
 
+
+    // One-sided optional
+    template <class DtoT, class BoT>
+    requires (not detail::is_optional<BoT>::value)
+    void toAron(std::optional<DtoT>& dto, const BoT& bo)
+    {
+        dto = DtoT{};
+        toAron(*dto, bo);
+    }
+    template <class DtoT, class BoT>
+    requires (not detail::is_optional<DtoT>::value)
+    void fromAron(DtoT& dto, const std::optional<BoT>& bo)
+    {
+        bo = BoT{};
+        fromAron(dto, *bo);
+    }
+
+
     // Flag-controlled optional
     template <class DtoT, class BoT>
     void toAron(DtoT& dto, bool& dtoValid, const BoT& bo, bool boValid)
@@ -154,6 +183,7 @@ namespace armarx::aron
         }
     }
 
+
     template <class DtoT, class BoT>
     void fromAron(const DtoT& dto, bool dtoValid, BoT& bo, bool& boValid)
     {
@@ -222,7 +252,7 @@ namespace armarx::aron
 
     // std::map
     template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
-    requires (!(DtoAndBoAreSame<DtoKeyT, BoKeyT> and DtoAndBoAreSame<DtoValueT, BoValueT>))
+    requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
     void toAron(std::map<DtoKeyT, DtoValueT>& dtoMap,
                 const std::map<BoKeyT, BoValueT>& boMap)
     {
@@ -236,7 +266,7 @@ namespace armarx::aron
         }
     }
     template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
-    requires (!(DtoAndBoAreSame<DtoKeyT, BoKeyT> and DtoAndBoAreSame<DtoValueT, BoValueT>))
+    requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
     void fromAron(const std::map<DtoKeyT, DtoValueT>& dtoMap,
                   std::map<BoKeyT, BoValueT>& boMap)
     {
@@ -252,7 +282,7 @@ namespace armarx::aron
 
 
     template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
-    requires (!(DtoAndBoAreSame<DtoKeyT, BoKeyT> and DtoAndBoAreSame<DtoValueT, BoValueT>))
+    requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
     std::map<DtoKeyT, DtoValueT> toAron(const std::map<BoKeyT, BoValueT>& boMap)
     {
         std::map<DtoKeyT, DtoValueT> dtoMap;
@@ -343,20 +373,20 @@ namespace armarx
 
     // std::vector
     template <class DtoT, class BoT>
-    requires (!aron::DtoAndBoAreSame<DtoT, BoT>)
+    requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>)
     void toAron(std::vector<DtoT>& dtos, const std::vector<BoT>& bos)
     {
         armarx::aron::toAron(dtos, bos);
     }
     template <class DtoT, class BoT>
-    requires (!aron::DtoAndBoAreSame<DtoT, BoT>)
+    requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>)
     void fromAron(const std::vector<DtoT>& dtos, std::vector<BoT>& bos)
     {
         armarx::aron::fromAron(dtos, bos);
     }
 
     template <class DtoT, class BoT>
-    requires (!aron::DtoAndBoAreSame<DtoT, BoT>)
+    requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>)
     std::vector<DtoT> toAron(const std::vector<BoT>& bos)
     {
         return armarx::aron::toAron<DtoT, BoT>(bos);
@@ -365,13 +395,13 @@ namespace armarx
 
     // std::map
     template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
-    requires (!(aron::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::DtoAndBoAreSame<DtoValueT, BoValueT>))
+    requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
     void toAron(std::map<DtoKeyT, DtoValueT>& dtoMap, const std::map<BoKeyT, BoValueT>& boMap)
     {
         armarx::aron::toAron(dtoMap, boMap);
     }
     template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
-    requires (!(aron::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::DtoAndBoAreSame<DtoValueT, BoValueT>))
+    requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
     void fromAron(const std::map<DtoKeyT, DtoValueT>& dtoMap, std::map<BoKeyT, BoValueT>& boMap)
     {
         armarx::aron::fromAron(dtoMap, boMap);
@@ -379,7 +409,7 @@ namespace armarx
 
 
     template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
-    requires (!(aron::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::DtoAndBoAreSame<DtoValueT, BoValueT>))
+    requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
     std::map<DtoKeyT, DtoValueT> toAron(const std::map<BoKeyT, BoValueT>& boMap)
     {
         armarx::aron::toAron<DtoKeyT, DtoValueT, BoKeyT, BoValueT>(boMap);
diff --git a/source/RobotAPI/libraries/aron/core/data/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/data/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp
index 21fdfc82b0fdec76910890100721d6f5ee19654c..e6beb0e9aab36bc5aa245155b7a42b3d0acb82ab 100644
--- a/source/RobotAPI/libraries/aron/core/data/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/rw/reader/nlohmannJSON/NlohmannJSONReader.cpp
@@ -52,7 +52,8 @@ namespace armarx::aron::data::reader
 
     data::Descriptor NlohmannJSONReader::getDescriptor(InputType& input)
     {
-        return ConstNlohmannJSONVisitor::GetDescriptor(input);
+        auto ret = ConstNlohmannJSONVisitor::GetDescriptor(input);
+        return ret;
     }
 
     void NlohmannJSONReader::readList(const nlohmann::json& input, std::vector<nlohmann::json>& elements, Path& p)
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp
index 111068b393c86b681179544c4d60fd02953f3f36..483088aa7ffaf706271072d5e13d55f26b8e4ec4 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp
@@ -142,6 +142,7 @@ namespace armarx::aron::data
     {
         if (t.empty())
         {
+            ARMARX_TRACE;
             throw error::AronException(__PRETTY_FUNCTION__, "The type cannot be empty", getPath());
         }
 
@@ -166,6 +167,7 @@ namespace armarx::aron::data
 
     type::VariantPtr NDArray::recalculateType() const
     {
+        ARMARX_TRACE;
         throw error::NotImplementedYetException(__PRETTY_FUNCTION__);
     }
 
@@ -179,29 +181,35 @@ namespace armarx::aron::data
         case type::Descriptor::MATRIX:
         {
             auto casted = type::Matrix::DynamicCastAndCheck(type);
+            ARMARX_TRACE;
             return (aron->shape.size() == 3 &&  aron->shape[0] == casted->getRows() && aron->shape[1] == casted->getCols());
         }
         case type::Descriptor::QUATERNION:
         {
             auto casted = type::Quaternion::DynamicCastAndCheck(type);
+            ARMARX_TRACE;
             return (aron->shape.size() == 3 && aron->shape[0] == 1 && aron->shape[1] == 4);
         }
         case type::Descriptor::POINTCLOUD:
         {
             auto casted = type::PointCloud::DynamicCastAndCheck(type);
+            ARMARX_TRACE;
             return (aron->shape.size() == 3);
         }
         case type::Descriptor::IMAGE:
         {
             auto casted = type::Image::DynamicCastAndCheck(type);
+            ARMARX_TRACE;
             return (aron->shape.size() == 3);
         }
         case type::Descriptor::NDARRAY:
         {
             auto casted = type::NDArray::DynamicCastAndCheck(type);
+            ARMARX_TRACE;
             return (aron->shape.size() == (unsigned int) casted->getNumberDimensions());
         }
         default:
+            ARMARX_TRACE;
             return false;
         }
     }
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 09cab7521090642ff509a0aa0fd9bdb17c99544c..9724ae6279a2b2a2140d5964d7d101f6e9fbabc8 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
@@ -137,6 +137,7 @@ namespace armarx::aron::data
     {
         if (hasElement(key))
         {
+            ARMARX_TRACE;
             throw error::AronException(__PRETTY_FUNCTION__, "The key '"+key+"' already exists in a aron dict.");
         }
         setElement(key, data);
@@ -152,6 +153,7 @@ namespace armarx::aron::data
         auto it = childrenNavigators.find(key);
         if (it == childrenNavigators.end())
         {
+            ARMARX_TRACE;
             throw error::AronException(__PRETTY_FUNCTION__, "Could not find key '" + key + "'. But I found the following keys: [" + simox::alg::join(this->getAllKeys(), ", ") + "]", getPath());
         }
         return it->second;
@@ -203,8 +205,10 @@ namespace armarx::aron::data
         return "armarx::aron::data::Dict";
     }
 
+    // TODO
     type::VariantPtr Dict::recalculateType() const
     {
+        ARMARX_TRACE;
         throw error::NotImplementedYetException(__PRETTY_FUNCTION__);
     }
 
@@ -227,29 +231,26 @@ namespace armarx::aron::data
                         ARMARX_TRACE;
                         return false;
                     }
-                    if (!objectTypeNav->getMemberType(key))
-                    {
-                        ARMARX_TRACE;
-                        return false;
-                    }
 
+                    auto childTypeNav = objectTypeNav->getMemberType(key);
                     if (!nav)
                     {
                         ARMARX_TRACE;
-                        auto childTypeNav = objectTypeNav->getMemberType(key);
-                        if (childTypeNav->getMaybe() == type::Maybe::NONE)
+                        if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
                         {
                             ARMARX_TRACE;
                             return false;
                         }
+                        ARMARX_TRACE;
                         return true;
                     }
-                    if (!nav->fullfillsType(objectTypeNav->getMemberType(key)))
+                    if (!nav->fullfillsType(childTypeNav))
                     {
                         ARMARX_TRACE;
                         return false;
                     }
                 }
+                ARMARX_TRACE;
                 return true;
             }
             case type::Descriptor::DICT:
@@ -259,20 +260,29 @@ namespace armarx::aron::data
                 for (const auto& [key, nav] : childrenNavigators)
                 {
                     (void) key;
-                    if (!nav || !dictTypeNav->getAcceptedType())
+                    auto childTypeNav = dictTypeNav->getAcceptedType();
+                    if (!nav)
                     {
                         ARMARX_TRACE;
-                        return false;
+                        if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
+                        {
+                            ARMARX_TRACE;
+                            return false;
+                        }
+                        ARMARX_TRACE;
+                        return true;
                     }
-                    if (!nav->fullfillsType(dictTypeNav->getAcceptedType()))
+                    if (!nav->fullfillsType(childTypeNav))
                     {
                         ARMARX_TRACE;
                         return false;
                     }
                 }
+                ARMARX_TRACE;
                 return true;
             }
             default:
+                ARMARX_TRACE;
                 return false;
         }
     }
@@ -296,11 +306,13 @@ namespace armarx::aron::data
     {
         if (!path.hasElement())
         {
+            ARMARX_TRACE;
             throw error::AronException(__PRETTY_FUNCTION__, "Could not navigate without a valid path", path);
         }
         std::string el = path.getFirstElement();
         if (!hasElement(el))
         {
+            ARMARX_TRACE;
             throw error::ValueNotValidException(__PRETTY_FUNCTION__, "Could not find an element of a path.", el, path);
         }
 
@@ -313,6 +325,7 @@ namespace armarx::aron::data
             Path next = path.withDetachedFirstElement();
             if (!childrenNavigators.at(el))
             {
+                ARMARX_TRACE;
                 throw error::AronException(__PRETTY_FUNCTION__, "Could not navigate into a NULL member. Seems like the member is optional and not set.", next);
             }
             return childrenNavigators.at(el)->navigateAbsolute(next);
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
index db80996a17bc20796dbca992bfd765ef31aad93d..c53b51ee1b04c3e903b4ddd718b9793d75303412 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
@@ -127,7 +127,8 @@ namespace armarx::aron::data
     {
         if (i > aron->elements.size())
         {
-            error::AronException(__PRETTY_FUNCTION__, "Cannot set a listelement at index " + std::to_string(i) + " because this list has size " + std::to_string(aron->elements.size()));
+            ARMARX_TRACE;
+            throw error::AronException(__PRETTY_FUNCTION__, "Cannot set a listelement at index " + std::to_string(i) + " because this list has size " + std::to_string(aron->elements.size()));
         }
 
         if (i == aron->elements.size())
@@ -165,6 +166,7 @@ namespace armarx::aron::data
     {
         if (i >= childrenNavigators.size())
         {
+            ARMARX_TRACE;
             throw error::ValueNotValidException(__PRETTY_FUNCTION__, "The index is out of bounds (size = " + std::to_string(childrenNavigators.size()) + ")", std::to_string(i), getPath());
         }
         return childrenNavigators[i];
@@ -208,6 +210,7 @@ namespace armarx::aron::data
     // TODO
     type::VariantPtr List::recalculateType() const
     {
+        ARMARX_TRACE;
         throw error::NotImplementedYetException(__PRETTY_FUNCTION__);
     }
 
@@ -224,17 +227,24 @@ namespace armarx::aron::data
                 auto listTypeNav = type::List::DynamicCastAndCheck(type);
                 for (const auto& nav : childrenNavigators)
                 {
-                    if (!nav && !listTypeNav->getAcceptedType())
+                    auto childTypeNav = listTypeNav->getAcceptedType();
+                    if (!nav)
                     {
+                        if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
+                        {
+                            ARMARX_TRACE;
+                            return false;
+                        }
                         ARMARX_TRACE;
-                        return false;
+                        return true;
                     }
-                    if (!nav->fullfillsType(listTypeNav->getAcceptedType()))
+                    if (!nav->fullfillsType(childTypeNav))
                     {
                         ARMARX_TRACE;
                         return false;
                     }
                 }
+                ARMARX_TRACE;
                 return true;
             }
             case type::Descriptor::TUPLE:
@@ -243,15 +253,30 @@ namespace armarx::aron::data
                 unsigned int i = 0;
                 for (const auto& nav : childrenNavigators)
                 {
-                    if (!nav && !tupleTypeNav->getAcceptedType(i))
+                    if (!tupleTypeNav->hasAcceptedType(i))
                     {
+                        ARMARX_TRACE;
+                        return false;
+                    }
+
+                    auto childTypeNav = tupleTypeNav->getAcceptedType(i);
+                    if (!nav)
+                    {
+                        if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
+                        {
+                            ARMARX_TRACE;
+                            return false;
+                        }
+                        ARMARX_TRACE;
                         return false;
                     }
                     if (!nav->fullfillsType(tupleTypeNav->getAcceptedType(i)))
                     {
+                        ARMARX_TRACE;
                         return false;
                     }
                 }
+                ARMARX_TRACE;
                 return true;
             }
             case type::Descriptor::PAIR:
@@ -259,19 +284,36 @@ namespace armarx::aron::data
                 auto pairTypeNav = type::Pair::DynamicCastAndCheck(type);
                 if (childrenSize() != 2)
                 {
+                    ARMARX_TRACE;
                     return false;
                 }
-                if (!childrenNavigators[0] && !pairTypeNav->getFirstAcceptedType())
+                auto firstChildTypeNav = pairTypeNav->getFirstAcceptedType();
+                if (!childrenNavigators[0])
                 {
+                    if (firstChildTypeNav && firstChildTypeNav->getMaybe() == type::Maybe::NONE)
+                    {
+                        ARMARX_TRACE;
+                        return false;
+                    }
+                    ARMARX_TRACE;
                     return false;
                 }
-                if (!childrenNavigators[1] && !pairTypeNav->getSecondAcceptedType())
+                auto secondChildTypeNav = pairTypeNav->getSecondAcceptedType();
+                if (!childrenNavigators[1])
                 {
+                    if (secondChildTypeNav && secondChildTypeNav->getMaybe() == type::Maybe::NONE)
+                    {
+                        ARMARX_TRACE;
+                        return false;
+                    }
+                    ARMARX_TRACE;
                     return false;
                 }
-                return childrenNavigators[0]->fullfillsType(pairTypeNav->getFirstAcceptedType()) && childrenNavigators[1]->fullfillsType(pairTypeNav->getSecondAcceptedType());
+                ARMARX_TRACE;
+                return childrenNavigators[0]->fullfillsType(firstChildTypeNav) && childrenNavigators[1]->fullfillsType(secondChildTypeNav);
             }
             default:
+                ARMARX_TRACE;
                 return false;
         }
     }
@@ -295,6 +337,7 @@ namespace armarx::aron::data
         unsigned int i = std::stoi(path.getFirstElement());
         if (!hasElement(i))
         {
+            ARMARX_TRACE;
             throw error::ValueNotValidException(__PRETTY_FUNCTION__, "Could not find an element of a path.", std::to_string(i), std::to_string(childrenSize()));
         }
 
@@ -307,6 +350,7 @@ namespace armarx::aron::data
             Path next = path.withDetachedFirstElement();
             if (!childrenNavigators.at(i))
             {
+                ARMARX_TRACE;
                 throw error::AronException(__PRETTY_FUNCTION__, "Could not navigate into a NULL member. Seems like the member is optional and not set.", next);
             }
             return childrenNavigators.at(i)->navigateAbsolute(next);
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp
index 0e68bbc6dc16c373dd63c4626a45f5b1377afad4..2f7fe6fc8e486c43c32875c1cf072e721146c402 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp
@@ -95,6 +95,7 @@ namespace armarx::aron::data
         }
         else
         {
+            ARMARX_TRACE;
             throw error::AronException(__PRETTY_FUNCTION__, "Could not set from string. Got: '" + setter + "'");
         }
     }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp b/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp
index 84adf5c1ea7643ece74e2bc3e224e5df075f7a12..e80e7d37e071585f8b6f3ae0e7d0f81d280b49e4 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.cpp
@@ -33,6 +33,7 @@ namespace armarx::aron::data
             return data::Descriptor::UNKNOWN;
         }
         std::string t = n[armarx::aron::data::rw::json::constantes::TYPE_SLUG];
+
         return armarx::aron::data::rw::json::conversion::String2Descriptor.at(t);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/rw.h b/source/RobotAPI/libraries/aron/core/rw.h
index 6257f2422687591b0991afed8a0577ee127207ef..95b6aac606f47d3c46de34ac5ec077ded28c41a4 100644
--- a/source/RobotAPI/libraries/aron/core/rw.h
+++ b/source/RobotAPI/libraries/aron/core/rw.h
@@ -26,7 +26,7 @@ namespace armarx::aron
     }
 
     template<class ReaderT, class DtoT, class BoT>
-    requires (data::isReader<ReaderT> && !DtoAndBoAreSame<DtoT, BoT>)
+    requires (data::isReader<ReaderT> && !detail::DtoAndBoAreSame<DtoT, BoT>)
     inline void read(ReaderT& aron_r, typename ReaderT::InputType& input, BoT& ret)
     {
         DtoT aron;
@@ -36,7 +36,7 @@ namespace armarx::aron
     }
 
     template<class WriterT, class DtoT, class BoT>
-    requires (data::isWriter<WriterT> && !DtoAndBoAreSame<DtoT, BoT>)
+    requires (data::isWriter<WriterT> && !detail::DtoAndBoAreSame<DtoT, BoT>)
     inline void write(WriterT& aron_w, const BoT& input, typename WriterT::ReturnType& ret, const armarx::aron::Path& aron_p = armarx::aron::Path())
     {
         DtoT aron;
diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp
index 0879de17b8e9258a211646e2b7c8d7c4bdc37ace..51d45e3975bb162460fd06893e91f388ac52b9f1 100644
--- a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp
+++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp
@@ -64,6 +64,11 @@ namespace armarx::aron::type
         return acceptedTypes;
     }
 
+    bool Tuple::hasAcceptedType(unsigned int i) const
+    {
+        return i < acceptedTypes.size();
+    }
+
     VariantPtr Tuple::getAcceptedType(unsigned int i) const
     {
         return acceptedTypes[i];
diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h
index d464f83269d5074e1ec6e759119b433c76de0f7d..3281584c15d6b4bb3e50c83ce598634a2bbec324 100644
--- a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h
+++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h
@@ -46,6 +46,7 @@ namespace armarx::aron::type
 
         // public member functions
         std::vector<VariantPtr> getAcceptedTypes() const;
+        bool hasAcceptedType(unsigned int i) const;
         VariantPtr getAcceptedType(unsigned int i) const;
         void addAcceptedType(const VariantPtr&);
 
diff --git a/source/RobotAPI/libraries/aron/test/AronConversionTester.cpp b/source/RobotAPI/libraries/aron/test/AronConversionTester.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aac543a04b6ba1696dedc7a21c7d4ea125896e4e
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/test/AronConversionTester.cpp
@@ -0,0 +1,38 @@
+/**
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    RobotAPI::ArmarXObjects::aron_cpp_to_python_conv_test
+ * @author     Rainer Kartmann ( rainer dot kartmann at kit dot edu )
+ * @date       2023
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+
+#include "AronConversionTester.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+
+namespace armarx::aron::test
+{
+
+    AronConversionTester::AronConversionTester(dti::AronConversionTestInterfacePrx python) : interface(python)
+    {
+        ARMARX_CHECK(python);
+    }
+
+
+} // namespace armarx::aron::test
diff --git a/source/RobotAPI/libraries/aron/test/AronConversionTester.h b/source/RobotAPI/libraries/aron/test/AronConversionTester.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7ad4b8dfdcf55a37f8efc3116c27440d925d428
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/test/AronConversionTester.h
@@ -0,0 +1,111 @@
+/**
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    RobotAPI::ArmarXObjects::aron_cpp_to_python_conv_test
+ * @author     Rainer Kartmann ( rainer dot kartmann at kit dot edu )
+ * @date       2023
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+
+#pragma once
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <ArmarXCore/core/logging/Logging.h>
+
+#include <RobotAPI/interface/aron/test/AronConversionTestInterface.h>
+
+
+namespace armarx::aron::test
+{
+
+    /**
+     * @brief Helper class for implementing distributed ARON conversion tests
+     * based on the `dti::AronConversionTestInterfacePrx`.
+     *
+     * Example usage:
+     *
+     * @code
+     *
+     * armarx::aron::test::dti::AronConversionTestInterfacePrx pythonComponent = ...;
+     *
+     * auto myAronClassProbeFn = []()
+     * {
+     *     my::arondto::MyAronClass probe;
+     *     probe.data = "42";
+     *     return probe,
+     * };
+     *
+     * armarx::aron::test::AronConversionTester tester(pythonComponent);
+     *
+     * tester.test<my::arondto::MyAronClass>(myAronClassProbeFn, "MyAronClass");
+     *
+     * @endcode
+     *
+     * Note that the `pythonComponent` must point to a corresponding
+     * implementation of the `AronConversionTestInterfacePrx`.
+     */
+    class AronConversionTester
+    {
+    public:
+        template <class AronClassT>
+        using ProbeFn = std::function<AronClassT()>;
+
+
+    public:
+        AronConversionTester(dti::AronConversionTestInterfacePrx interface);
+
+        /**
+         * @brief Test the conversion of a specific ARON class.
+         *
+         * @param probeFn A factory function creating a test instance of the
+         *      ARON class.
+         * @param aronClassName The name of the ARON class. Can be used by the
+         *      other component to decide which class to convert to.
+         */
+        template <class AronClassT>
+        void
+        test(ProbeFn<AronClassT> probeFn, const std::string& aronClassName)
+        {
+            std::stringstream ss;
+            ss << "Test for ARON class '" << aronClassName << "': ";
+
+            const AronClassT probe = probeFn();
+
+            dto::TestAronConversionRequest req;
+            req.aronClassName = aronClassName;
+            req.probe = probe.toAronDTO();
+
+            dto::TestAronConversionResponse res = interface->testAronConversion(req);
+
+            if (res.success)
+            {
+                const AronClassT probeOut = AronClassT::FromAron(res.probe);
+                ARMARX_CHECK(probeOut == probe);
+
+                ARMARX_IMPORTANT << ss.str() << "Success";
+            }
+            else
+            {
+                ARMARX_WARNING << ss.str() << "Conversion in Python component failed: \n" << res.errorMessage;
+            }
+        }
+
+    public:
+        dti::AronConversionTestInterfacePrx interface;
+    };
+
+} // namespace armarx::aron::test
diff --git a/source/RobotAPI/libraries/aron/test/CMakeLists.txt b/source/RobotAPI/libraries/aron/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3a199acf0f19c13f6253e66947e540bfe3950efd
--- /dev/null
+++ b/source/RobotAPI/libraries/aron/test/CMakeLists.txt
@@ -0,0 +1,25 @@
+set(LIB_NAME arontest)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+
+armarx_add_library(
+    LIBS
+        # ArmarXCore
+        ArmarXCore
+        # RobotAPI
+        RobotAPICore
+        RobotAPIInterfaces
+        aron
+
+    HEADERS
+        AronConversionTester.h
+
+    SOURCES
+        AronConversionTester.cpp
+)
+
+
+add_library(aron::test ALIAS arontest)
+add_library(${PROJECT_NAME}::Aron::test ALIAS arontest)
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 23a708aceace48317d04884a8579fd21001b92c3..60a38b465ddb8bd9d6cbdac5ec4952606624880c 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -33,7 +33,9 @@ namespace armarx
         }
         else
         {
-            ARMARX_INFO << "Trying to add a provider with name '" << info.providerName << "' but the provider already exists.";
+            ARMARX_INFO << "Trying to add a provider with name '" << info.providerName << "' but the provider already exists. "
+                        << "Overwriting the old provider info.";
+            skillProviderMap[info.providerName] = info.provider;
         }
     }
 
@@ -47,7 +49,7 @@ namespace armarx
         }
         else
         {
-            ARMARX_INFO << "Trying to remove a provider with name '" << providerName << "' but it couldn't found.";
+            ARMARX_INFO << "Trying to remove a provider with name '" << providerName << "' but it couldn't be found.";
         }
     }
 
@@ -79,31 +81,64 @@ namespace armarx
             providerName = info.skillId.providerName;
         }
 
+        bool remove = false;
         if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
         {
-            skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx;
-            getProxy(myPrx, -1);
+            const auto& n = it->first;
+            const auto& s = it->second;
 
-            skills::provider::dto::SkillExecutionRequest exInfo;
-            exInfo.skillName = info.skillId.skillName;
-            exInfo.executorName = info.executorName;
-            exInfo.callbackInterface = myPrx;
-            exInfo.params = info.params;
+            if (s)
+            {
+                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;
+
+                return s->executeSkill(exInfo);
+            }
+            else
+            {
+                remove = true;
+            }
 
-            return it->second->executeSkill(exInfo);
+            if (remove)
+            {
+                std::scoped_lock l(skillProviderMapMutex);
+                if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
+                {
+                    ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '" << n << "' during execution. Removing it from skills.";
+                    it = skillProviderMap.erase(it);
+                }
+            }
         }
         else
         {
             ARMARX_ERROR << "Could not execute a skill of provider '" + providerName + "' because the provider does not exist.";
             throw skills::error::SkillException(__PRETTY_FUNCTION__, "Skill execution failed. Could not execute a skill of provider '" + providerName + "' because the provider does not exist.");
         }
+        return {}; // Never happens
     }
 
     void SkillManagerComponentPluginUser::abortSkill(const std::string& providerName, const std::string& skillName, const Ice::Current &current)
     {
+        std::scoped_lock l(skillProviderMapMutex);
         if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
         {
-            it->second->abortSkill(skillName);
+            const auto& n = it->first;
+            const auto& s = it->second;
+            if (s)
+            {
+                s->abortSkill(skillName);
+            }
+            else
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '" << n << "'. Removing it from skills.";
+                it = skillProviderMap.erase(it);
+            }
         }
     }
 
@@ -116,10 +151,23 @@ namespace armarx
     skills::manager::dto::SkillDescriptionMapMap SkillManagerComponentPluginUser::getSkillDescriptions(const Ice::Current &current)
     {
         skills::manager::dto::SkillDescriptionMapMap ret;
-        for (const auto& [n, s] : skillProviderMap)
+
+        std::scoped_lock l(skillProviderMapMutex);
+        for (auto it = skillProviderMap.cbegin(); it != skillProviderMap.cend();)
         {
-            skills::provider::dto::SkillDescriptionMap m = s->getSkillDescriptions();
-            ret.insert({n, m});
+            const auto& n = it->first;
+            const auto& s = it->second;
+            if (s)
+            {
+                skills::provider::dto::SkillDescriptionMap m = s->getSkillDescriptions();
+                ret.insert({n, m});
+                ++it;
+            }
+            else
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '" << n << "'. Removing it from skills.";
+                it = skillProviderMap.erase(it);
+            }
         }
         return ret;
     }
@@ -127,10 +175,23 @@ namespace armarx
     skills::manager::dto::SkillStatusUpdateMapMap SkillManagerComponentPluginUser::getSkillExecutionStatuses(const Ice::Current &current)
     {
         skills::manager::dto::SkillStatusUpdateMapMap ret;
-        for (const auto& [n, s] : skillProviderMap)
+
+        std::scoped_lock l(skillProviderMapMutex);
+        for (auto it = skillProviderMap.cbegin(); it != skillProviderMap.cend();)
         {
-            skills::provider::dto::SkillStatusUpdateMap m = s->getSkillExecutionStatuses();
-            ret.insert({n, m});
+            const auto& n = it->first;
+            const auto& s = it->second;
+            if (s)
+            {
+                skills::provider::dto::SkillStatusUpdateMap m = s->getSkillExecutionStatuses();
+                ret.insert({n, m});
+                it++;
+            }
+            else
+            {
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '" << n << "'. Removing it from skills.";
+                it = skillProviderMap.erase(it);
+            }
         }
         return ret;
     }
diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
index 9f554e11e5c878bdd77cd7c866bef6871b3c6584..3f2b9371e2b087b4a5da77fb06e898bca525c320 100644
--- a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
+++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h
@@ -76,6 +76,7 @@ namespace armarx
             }
 
         private:
+            /// Override this method if you want to disable a skill based on certain conditions
             virtual bool isAvailable(const SpecializedInitInput&) const
             {
                 return true;
diff --git a/source/RobotAPI/libraries/skills/provider/mixins/RobotWritingSkillMixin.h b/source/RobotAPI/libraries/skills/provider/mixins/RobotWritingSkillMixin.h
new file mode 100644
index 0000000000000000000000000000000000000000..34856452c4b8bd3b4e61dd69ee03eb122d409566
--- /dev/null
+++ b/source/RobotAPI/libraries/skills/provider/mixins/RobotWritingSkillMixin.h
@@ -0,0 +1,28 @@
+#pragma once
+
+
+// Others
+#include <RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotWriter.h>
+
+namespace armarx::skills::mixin
+{
+    struct RobotWritingSkillMixin
+    {
+        armem::robot_state::VirtualRobotWriter robotWriter;
+
+        RobotWritingSkillMixin(armem::client::MemoryNameSystem& mns) :
+            robotWriter(mns)
+        {}
+    };
+
+    struct SpecificRobotWritingSkillMixin
+    {
+        std::string robotName;
+        armem::robot_state::VirtualRobotWriter robotWriter;
+
+        SpecificRobotWritingSkillMixin(const std::string& rn, armem::client::MemoryNameSystem& mns) :
+            robotName(rn),
+            robotWriter(mns)
+        {}
+    };
+}