diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8d684da402ca704e30e1d7219a24accd0e5f1742..100538b7b7a1e37d867cadf03cd1c6fe8240bb39 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,9 @@ set(ARMARX_ENABLE_AUTO_CODE_FORMATTING TRUE)
 armarx_project("RobotAPI")
 depends_on_armarx_package(ArmarXGui)
 
+find_package(DMP QUIET)
+
+
 add_subdirectory(source)
 
 install_project()
diff --git a/etc/doxygen/pages/GuiPlugins.dox b/etc/doxygen/pages/GuiPlugins.dox
index e090dfd4881e183d76f14e84129a755bf50b6597..ccfe2ca1998f1b6902f645cae8c2af9ef38d06b1 100644
--- a/etc/doxygen/pages/GuiPlugins.dox
+++ b/etc/doxygen/pages/GuiPlugins.dox
@@ -1,31 +1,64 @@
 /**
 \page RobotAPI-GuiPlugins RobotAPI Gui Plugins
 
-The following Gui Plugins are available:
+The following Gui Plugins are available in RobotAPI:
 
-\subpage RobotAPI-GuiPlugins-TCPMover
 
-\subpage RobotAPI-GuiPlugins-HandUnitWidget
+ArViz (3D Visualization):
 
-\subpage RobotAPI-GuiPlugins-HapticUnitPlugin
+\li \subpage RobotAPI-GuiPlugins-ArViz
 
-\subpage RobotAPI-GuiPlugins-KinematicUnitPlugin
+\li \subpage RobotAPI-GuiPlugins-ArVizDrawerGui
 
-\subpage RobotAPI-GuiPlugins-PlatformUnitPlugin
+Memory System:
 
-\subpage RobotAPI-GuiPlugins-RobotViewerPlugin
+\li \subpage RobotAPI-GuiPlugins-ArMemMemoryViewer
 
-\subpage RobotAPI-GuiPlugins-ViewSelection
 
-\subpage ArmarXGui-GuiPlugins-DebugDrawerViewer
+Controlling and Visualizing the Robot:
 
-\subpage ArmarXGui-GuiPlugins-LaserScannerPlugin
+\li \subpage RobotAPI-GuiPlugins-HandUnitWidget
 
-\subpage ArmarXGui-GuiPlugins-HomogeneousMatrixCalculator
+\li \subpage RobotAPI-GuiPlugins-KinematicUnitPlugin
 
-\subpage ArmarXGui-GuiPlugins-RobotUnitPlugin
+\li \subpage RobotAPI-GuiPlugins-PlatformUnitPlugin
 
-\subpage ArmarXGui-GuiPlugins-GuiHealthClient
+\li \subpage RobotAPI-GuiPlugins-RobotViewerPlugin
+
+\li \subpage RobotAPI-GuiPlugins-RobotUnitPlugin
+
+\li \subpage RobotAPI-GuiPlugins-TCPMover
+
+
+Miscellaneous:
+
+\li \subpage RobotAPI-GuiPlugins-BoxToGraspCandidates
+
+\li \subpage RobotAPI-GuiPlugins-DebugRobotUnitDataStreaming
+
+\li \subpage RobotAPI-GuiPlugins-FTSensorCalibrationGui
+
+\li \subpage RobotAPI-GuiPlugins-GraspCandidateViewer
+
+\li \subpage RobotAPI-GuiPlugins-GuiHealthClient
+
+\li \subpage RobotAPI-GuiPlugins-HapticUnitPlugin
+
+\li \subpage RobotAPI-GuiPlugins-HomogeneousMatrixCalculator
+
+\li \subpage RobotAPI-GuiPlugins-LaserScannerPlugin
+
+\li \subpage RobotAPI-GuiPlugins-ObjectPoseGui
+
+\li \subpage RobotAPI-GuiPlugins-SkillObserverMonitor
+
+\li \subpage RobotAPI-GuiPlugins-ViewSelection
+
+
+Debug Drawer (deprecated, superseded by ArViz):
+
+\li \subpage RobotAPI-GuiPlugins-DebugDrawerGuiPlugin
+
+\li \subpage RobotAPI-GuiPlugins-DebugDrawerViewer
 
-\subpage RobotAPI-GuiPlugins-CartesianWaypointControlGui
 */
diff --git a/etc/doxygen/pages/Tutorials.dox b/etc/doxygen/pages/Tutorials.dox
index 334f2ceea274b4d0c6c024bfe0af94a13eca555d..21411baf24e79bfbb71f8f6fc500efb874d7a6f1 100644
--- a/etc/doxygen/pages/Tutorials.dox
+++ b/etc/doxygen/pages/Tutorials.dox
@@ -2,8 +2,14 @@
 
 \page RobotAPI-Tutorials RobotAPI Tutorials
 
-Tutorials related to RobotAPI
+Tutorials related to RobotAPI:
+
 \li \subpage RobotAPI-Tutorial-MoveRobotWithGui
+
 \li \subpage RobotAPI-Tutorial-MoveRobotArmAlongRectangle
 
+\li  \ref Component-ArVizExample (Example component for how to use ArViz)
+
+\li  <a href="https://gitlab.com/ArmarX/Tutorials/-/tree/master/memory_tutorial">Memory Server and Client Tutorial</a>
+
 */
diff --git a/scenarios/ArViz/config/ArVizStorage.cfg b/scenarios/ArViz/config/ArVizStorage.cfg
index 0dcbd8d5775b8c0f562bba62b5f2fe282e2da6d0..30b8ea5904d318cf689370e81d3d3a7c47d07a68 100644
--- a/scenarios/ArViz/config/ArVizStorage.cfg
+++ b/scenarios/ArViz/config/ArVizStorage.cfg
@@ -68,7 +68,7 @@
 # ArmarX.ArVizStorage.TopicName = ArVizTopic
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
diff --git a/scenarios/ArViz/config/DebugObserver.cfg b/scenarios/ArViz/config/DebugObserver.cfg
index 4a0b9dac036cd4d103efd7d1b718d508f285d85a..8dc7ead26b3bd2f7678b3b3e7a1b00c01213225d 100644
--- a/scenarios/ArViz/config/DebugObserver.cfg
+++ b/scenarios/ArViz/config/DebugObserver.cfg
@@ -18,7 +18,7 @@
 # ArmarX.ApplicationName = ""
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
diff --git a/scenarios/ArVizExample/config/ArVizExample.cfg b/scenarios/ArVizExample/config/ArVizExample.cfg
index bbc0fa108ff0f746a7460ca98e1ef3e2b69302b3..0c0ee4c6e9a0e5ed6bbf7955e59b03a898c15528 100644
--- a/scenarios/ArVizExample/config/ArVizExample.cfg
+++ b/scenarios/ArVizExample/config/ArVizExample.cfg
@@ -61,7 +61,7 @@
 # ArmarX.ArVizExample.layers.ManyElements = false
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
diff --git a/scenarios/ArVizExample/config/ArVizStorage.cfg b/scenarios/ArVizExample/config/ArVizStorage.cfg
index 0dcbd8d5775b8c0f562bba62b5f2fe282e2da6d0..30b8ea5904d318cf689370e81d3d3a7c47d07a68 100644
--- a/scenarios/ArVizExample/config/ArVizStorage.cfg
+++ b/scenarios/ArVizExample/config/ArVizStorage.cfg
@@ -68,7 +68,7 @@
 # ArmarX.ArVizStorage.TopicName = ArVizTopic
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
diff --git a/scenarios/ArVizExample/config/DebugObserver.cfg b/scenarios/ArVizExample/config/DebugObserver.cfg
index 4a0b9dac036cd4d103efd7d1b718d508f285d85a..8dc7ead26b3bd2f7678b3b3e7a1b00c01213225d 100644
--- a/scenarios/ArVizExample/config/DebugObserver.cfg
+++ b/scenarios/ArVizExample/config/DebugObserver.cfg
@@ -18,7 +18,7 @@
 # ArmarX.ApplicationName = ""
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
diff --git a/scenarios/ArVizExample/config/RobotToArVizApp.cfg b/scenarios/ArVizExample/config/RobotToArVizApp.cfg
index b023833a9d18ac3f4c1d92911b29ad1f8699a22c..b33276fe2dc50c8d6eadcb7beb004710f336e825 100644
--- a/scenarios/ArVizExample/config/RobotToArVizApp.cfg
+++ b/scenarios/ArVizExample/config/RobotToArVizApp.cfg
@@ -18,7 +18,7 @@
 # ArmarX.ApplicationName = ""
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_CONFIG_DIR is set, the cache path will be made relative to ARMARX_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${ARMARX_WORKSPACE}/armarx_config)
 #  Attributes:
 #  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
diff --git a/source/RobotAPI/applications/RobotControlUI/CMakeLists.txt b/source/RobotAPI/applications/RobotControlUI/CMakeLists.txt
index 907e852da2eb889fd42e47bb09c214e9be96b091..250f9ed90ae99c36689d9578199494720d5af231 100644
--- a/source/RobotAPI/applications/RobotControlUI/CMakeLists.txt
+++ b/source/RobotAPI/applications/RobotControlUI/CMakeLists.txt
@@ -1,7 +1,11 @@
 
 armarx_component_set_name(RobotControlUI)
 
-set(COMPONENT_LIBS Simox::SimoxUtility ArmarXCore RobotAPIOperations)
+set(COMPONENT_LIBS
+    SimoxUtility  # Simox::SimoxUtility
+    ArmarXCore
+    RobotAPIOperations
+)
 
 set(SOURCES main.cpp
     RobotControlUI.cpp
diff --git a/source/RobotAPI/components/ArViz/ArVizStorage.cpp b/source/RobotAPI/components/ArViz/ArVizStorage.cpp
index b0b29f25911e2899083979af9b94987dd7b70bc8..1fbb408ccc47d4aaea245b50a8b0da3adbd302cf 100644
--- a/source/RobotAPI/components/ArViz/ArVizStorage.cpp
+++ b/source/RobotAPI/components/ArViz/ArVizStorage.cpp
@@ -60,10 +60,33 @@ namespace armarx
     }
 
 
+    std::string ArVizStorage::getDefaultName() const
+    {
+        return "ArVizStorage";
+    }
+
+
+    armarx::PropertyDefinitionsPtr ArVizStorage::createPropertyDefinitions()
+    {
+        armarx::PropertyDefinitionsPtr defs(new ComponentPropertyDefinitions(getConfigIdentifier()));
+
+        defs->optional(topicName, "TopicName",
+                       "Layer updates are sent over this topic.");
+
+        defs->optional(maxHistorySize, "MaxHistorySize",
+                       "How many layer updates are saved in the history until they are compressed")
+                .setMin(0);
+
+        defs->defineOptionalProperty<std::string>(
+                    "HistoryPath", "RobotAPI/ArVizStorage",
+                    "Destination path where the history are serialized to");
+
+        return defs;
+    }
+
+
     void ArVizStorage::onInitComponent()
     {
-        topicName = getProperty<std::string>("TopicName").getValue();
-        maxHistorySize = getProperty<int>("MaxHistorySize").getValue();
         std::filesystem::path historyPathProp = getProperty<std::string>("HistoryPath").getValue();
         historyPath = getAbsolutePath(historyPathProp);
         if (!std::filesystem::exists(historyPath))
@@ -106,14 +129,8 @@ namespace armarx
 
     void ArVizStorage::onExitComponent()
     {
-
     }
 
-    armarx::PropertyDefinitionsPtr ArVizStorage::createPropertyDefinitions()
-    {
-        return armarx::PropertyDefinitionsPtr(new ArVizPropertyDefinitions(
-                getConfigIdentifier()));
-    }
 
     void ArVizStorage::updateLayers(viz::data::LayerUpdateSeq const& updates, const Ice::Current&)
     {
diff --git a/source/RobotAPI/components/ArViz/ArVizStorage.h b/source/RobotAPI/components/ArViz/ArVizStorage.h
index 08b7d20ff5440d018e2c39604ab00dd7b4918f23..02ebc981525bdc26ce277867950e79bbed39d17a 100644
--- a/source/RobotAPI/components/ArViz/ArVizStorage.h
+++ b/source/RobotAPI/components/ArViz/ArVizStorage.h
@@ -36,72 +36,50 @@
 
 namespace armarx
 {
-    /**
-     * @class ArVizPropertyDefinitions
-     * @brief
-     */
-    class ArVizPropertyDefinitions:
-        public armarx::ComponentPropertyDefinitions
-    {
-    public:
-        ArVizPropertyDefinitions(std::string prefix):
-            armarx::ComponentPropertyDefinitions(prefix)
-        {
-            defineOptionalProperty<std::string>("TopicName", "ArVizTopic", "Layer updates are sent over this topic.");
-            defineOptionalProperty<int>("MaxHistorySize", 1000, "How many layer updates are saved in the history until they are compressed")
-            .setMin(0);
-            defineOptionalProperty<std::string>("HistoryPath", "RobotAPI/ArVizStorage", "Destination path where the history are serialized to");
-        }
-    };
 
     /**
-     * @defgroup Component-ArViz ArViz
+     * @defgroup Component-ArVizStorage ArVizStorage
      * @ingroup RobotAPI-Components
-     * A description of the component ArViz.
      *
-     * @class ArViz
-     * @ingroup Component-ArViz
-     * @brief Brief description of class ArViz.
+     * The ArViz storage stores visualization elements published by ArViz
+     * clients and provides them for visualizing components such as the
+     * ArViz gui plugin.
+     *
+     * In addition, the ArViz storage can be used to record and restore
+     * visualization episodes and restore.
+     *
+     *
+     * @class ArVizStorage
+     * @ingroup Component-ArVizStorage
+     *
+     * @brief Stores visualization elements drawn by ArViz clients.
      *
-     * Detailed description of class ArViz.
      */
     class ArVizStorage
         : virtual public armarx::Component
         , virtual public armarx::viz::StorageAndTopicInterface
     {
     public:
-        /**
-         * @see armarx::ManagedIceObject::getDefaultName()
-         */
-        std::string getDefaultName() const override
-        {
-            return "ArVizStorage";
-        }
-
-        /**
-         * @see armarx::ManagedIceObject::onInitComponent()
-         */
+
+        /// armarx::ManagedIceObject::getDefaultName()
+        std::string getDefaultName() const override;
+
+
+        /// PropertyUser::createPropertyDefinitions()
+        armarx::PropertyDefinitionsPtr createPropertyDefinitions() override;
+
+        /// armarx::ManagedIceObject::onInitComponent()
         void onInitComponent() override;
 
-        /**
-         * @see armarx::ManagedIceObject::onConnectComponent()
-         */
+        /// armarx::ManagedIceObject::onConnectComponent()
         void onConnectComponent() override;
 
-        /**
-         * @see armarx::ManagedIceObject::onDisconnectComponent()
-         */
+        /// armarx::ManagedIceObject::onDisconnectComponent()
         void onDisconnectComponent() override;
 
-        /**
-         * @see armarx::ManagedIceObject::onExitComponent()
-         */
+        /// armarx::ManagedIceObject::onExitComponent()
         void onExitComponent() override;
 
-        /**
-         * @see PropertyUser::createPropertyDefinitions()
-         */
-        armarx::PropertyDefinitionsPtr createPropertyDefinitions() override;
 
         // Topic interface
         void updateLayers(viz::data::LayerUpdateSeq const& updates, const Ice::Current&) override;
@@ -119,8 +97,8 @@ namespace armarx
         void recordBatch(viz::data::RecordingBatch& batch);
 
     private:
-        std::string topicName;
-        int maxHistorySize = 100;
+        std::string topicName = "ArVizTopic";
+        int maxHistorySize = 1000;
         std::filesystem::path historyPath;
 
         std::mutex historyMutex;
diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
index c05ba4c73fed76887733249df491d266935035ec..4d2be3924a99696bb013dc9cab0ed2c8201b1923 100644
--- a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
+++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
@@ -22,42 +22,75 @@
 
 #include "ArVizExample.h"
 
-
-
 #include <Eigen/Eigen>
 
 #include <SimoxUtility/color/cmaps.h>
 
 #include <ArmarXCore/core/time/CycleUtil.h>
-#include <ArmarXCore/libraries/DecoupledSingleComponent/Decoupled.h>
 #include <ArmarXCore/core/time/TimeUtil.h>
+#include <ArmarXCore/libraries/DecoupledSingleComponent/Decoupled.h>
 
 #include <RobotAPI/components/ArViz/Client/Client.h>
 
 
 namespace armarx
 {
-    ARMARX_DECOUPLED_REGISTER_COMPONENT(ArVizExample);
+
+    armarx::PropertyDefinitionsPtr ArVizExample::createPropertyDefinitions()
+    {
+        armarx::PropertyDefinitionsPtr defs(new ComponentPropertyDefinitions(getConfigIdentifier()));
+
+        // In this example, this is automatically done by deriving the component
+        // from armarx::ArVizComponentPluginUser.
+        if (false)
+        {
+            defs->defineOptionalProperty<std::string>("ArVizTopicName", "ArVizTopic", "Layer updates are sent over this topic.");
+        }
+
+        defs->optional(properties.manyLayers, "layers.ManyElements",
+                       "Show a layer with a lot of elements (used for testing, may impact performance).");
+
+        return defs;
+    }
+
+
+    std::string ArVizExample::getDefaultName() const
+    {
+        return "ArVizExample";
+    }
+
 
     void ArVizExample::onInitComponent()
     {
-        offeringTopicFromProperty("ArVizTopicName");
+        // In this example, this is automatically done by deriving the component
+        // from armarx::ArVizComponentPluginUser.
+        if (false)
+        {
+            offeringTopicFromProperty("ArVizTopicName");
+        }
     }
 
+
     void ArVizExample::onConnectComponent()
     {
-        task = new RunningTask<ArVizExample>(this, &ArVizExample::update);
+        task = new RunningTask<ArVizExample>(this, &ArVizExample::run);
         task->start();
     }
 
 
     void ArVizExample::onDisconnectComponent()
     {
-        task->stop();
+        const bool join = true;
+        task->stop(join);
         task = nullptr;
     }
 
 
+    void ArVizExample::onExitComponent()
+    {
+    }
+
+
     void fillTestLayer(viz::Layer& layer, double timeInSeconds)
     {
         {
@@ -128,7 +161,6 @@ namespace armarx
             Eigen::Vector3f direction = dirRot * Eigen::Vector3f::UnitX();
             arrow.direction(direction);
 
-
             Eigen::Vector3f pos = Eigen::Vector3f::Zero();
             pos.z() = +300.0f;
             pos.x() = -500.0f;
@@ -141,6 +173,7 @@ namespace armarx
 
     }
 
+
     void fillRobotHandsLayer(viz::Layer& layer)
     {
         Eigen::Vector3f pos = Eigen::Vector3f::Zero();
@@ -334,23 +367,31 @@ namespace armarx
             pos.x() = 100.0f * std::sin(timeInSeconds);
             pos.y() = 1000.0f;
 
-            viz::Object sponge = viz::Object("sponge")
-                                 .position(pos)
-                                 .file("ArmarXObjects", "ArmarXObjects/SecondHands/Screwbox_big/Screwbox_big.xml");
+            viz::Object sponge =
+                    viz::Object("screwbox")
+                    .position(pos)
+                    .file("PriorKnowledgeData",
+                          "PriorKnowledgeData/objects/Maintenance/bauhaus-screwbox-large/bauhaus-screwbox-large.xml");
 
             layer.add(sponge);
+            layer.add(viz::Pose("screwbox pose").position(pos));
         }
-
         {
             Eigen::Vector3f pos = Eigen::Vector3f::Zero();
             pos.x() = 300.0f + 100.0f * std::sin(timeInSeconds);
             pos.y() = 1000.0f;
 
-            viz::Object spraybottle = viz::Object("spraybottle")
-                                      .position(pos)
-                                      .file("ArmarXObjects", "ArmarXObjects/SecondHands/Spraybottle/Spraybottle.xml");
+            Eigen::AngleAxisf orientation(M_PI_2, Eigen::Vector3f::UnitX());
+
+            viz::Object spraybottle =
+                    viz::Object("spraybottle")
+                    .position(pos)
+                    .orientation(Eigen::Quaternionf(orientation))
+                    .file("PriorKnowledgeData",
+                          "PriorKnowledgeData/objects/Maintenance/spraybottle/spraybottle.wrl");
 
             layer.add(spraybottle);
+            layer.add(viz::Pose("spraybottle pose").pose(pos, orientation.toRotationMatrix()));
         }
     }
 
@@ -362,11 +403,18 @@ namespace armarx
         const Eigen::Vector3f at = {-400, 0, 100};
         const Eigen::Vector3f dir = {-150, 0, 0};
 
-        layer.add(viz::Box("box_always").position(at).size(100).color(simox::Color::azure()));
-        layer.add(viz::Text("text_seconds").position(at + Eigen::Vector3f(0, 0, 100))
+        layer.add(viz::Box("box_always")
+                  .position(at).size(100)
+                  .color(simox::Color::azure())
+                  );
+        layer.add(viz::Text("text_seconds")
+                  .position(at + Eigen::Vector3f(0, 0, 100))
                   .orientation(Eigen::AngleAxisf(float(M_PI), Eigen::Vector3f::UnitZ())
                                * Eigen::Quaternionf::FromTwoVectors(Eigen::Vector3f::UnitZ(), - Eigen::Vector3f::UnitY()))
-                  .text(std::to_string(time % 3)).scale(5).color(simox::Color::black()));
+                  .text(std::to_string(time % 3))
+                  .scale(5)
+                  .color(simox::Color::black())
+                  );
 
         switch (time % 3)
         {
@@ -405,14 +453,17 @@ namespace armarx
                 {
                     std::stringstream ss;
                     ss << "box_" << x << "_" << y << "_" << z;
-                    layer.add(viz::Box(ss.str()).position(at + dist * Eigen::Vector3f(x, y, z))
+                    layer.add(viz::Box(ss.str())
+                              .position(at + dist * Eigen::Vector3f(x, y, z))
                               .orientation(Eigen::AngleAxisf(angle, Eigen::Vector3f::UnitZ()).toRotationMatrix())
-                              .size(size).color(simox::Color(cf * x, cf * y, cf * z)));
+                              .size(size)
+                              .color(simox::Color(cf * x, cf * y, cf * z)));
                 }
             }
         }
     }
 
+
     void fillColorMapsLayer(viz::Layer& layer, double timeInSeconds)
     {
         (void) timeInSeconds;
@@ -430,8 +481,10 @@ namespace armarx
             const simox::color::ColorMap& cmap = pair.second;
 
             Eigen::Vector3f shift(0, 0, - 1.5f * index * size.y());
-            viz::Mesh mesh = viz::Mesh(name + "_mesh").position(at + shift).orientation(ori)
-                             .grid2D(size, num, [&cmap](size_t, size_t, const E::Vector3f & p)
+            viz::Mesh mesh = viz::Mesh(name + "_mesh")
+                    .position(at + shift)
+                    .orientation(ori)
+                    .grid2D(size, num, [&cmap](size_t, size_t, const E::Vector3f & p)
             {
                 return viz::Color(cmap((p.x() + 100.f) / 200.f));
             });
@@ -448,7 +501,7 @@ namespace armarx
     }
 
 
-    void ArVizExample::update()
+    void ArVizExample::run()
     {
         // This example uses the member `arviz` provided by armarx::ArVizComponentPluginUser.
         {
@@ -521,15 +574,8 @@ namespace armarx
         }
     }
 
-    void ArVizExample::onExitComponent()
-    {
 
-    }
+    ARMARX_DECOUPLED_REGISTER_COMPONENT(ArVizExample);
 
-    armarx::PropertyDefinitionsPtr ArVizExample::createPropertyDefinitions()
-    {
-        return armarx::PropertyDefinitionsPtr(new ArVizExamplePropertyDefinitions(
-                getConfigIdentifier()));
-    }
 }
 
diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.h b/source/RobotAPI/components/ArViz/Example/ArVizExample.h
index 09c59505e2ddc1b636cf619d033905e0b8f7769d..252a0c6f2221b95872db648f05dcdbdf7d487c5f 100644
--- a/source/RobotAPI/components/ArViz/Example/ArVizExample.h
+++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.h
@@ -22,8 +22,6 @@
 
 #pragma once
 
-#include <RobotAPI/interface/ArViz.h>
-
 #include <ArmarXCore/core/Component.h>
 
 #include <ArmarXCore/core/services/tasks/RunningTask.h>
@@ -33,53 +31,55 @@
 
 namespace armarx
 {
-    /**
-     * @class ArVizExamplePropertyDefinitions
-     */
-    class ArVizExamplePropertyDefinitions :
-        public armarx::ComponentPropertyDefinitions
-    {
-    public:
-        ArVizExamplePropertyDefinitions(std::string prefix) :
-            armarx::ComponentPropertyDefinitions(prefix)
-        {
-            // In this example, this is automatically done by deriving the component
-            // from armarx::ArVizComponentPluginUser.
-            if (false)
-            {
-                defineOptionalProperty<std::string>("ArVizTopicName", "ArVizTopic", "Layer updates are sent over this topic.");
-            }
-
-
-            defineOptionalProperty<bool>("layers.ManyElements", false,
-                                         "Show a layer with a lot of elements (used for testing, may impact performance).");
-        }
-    };
 
     /**
      * @defgroup Component-ArVizExample ArVizExample
      * @ingroup RobotAPI-Components
-     * A description of the component ArVizExample.
+     *
+     * An example for how to visualize 3D elements via the 3D visualization
+     * framework ArViz.
+     *
+     * The example creates several layers, fills them with visualization
+     * elements, and commits them to ArViz.
+     *
+     * To see the result:
+     * \li Start the component `ArVizStorage`
+     * \li Open the gui plugin `ArViz`
+     * \li Start the component `ArVizExample`
+     *
+     * The scenario `ArVizExample` starts the necessary components,
+     * including the example component.
+     *
+     *
+     * A component which wants to visualize data via ArViz should:
+     * \li `#include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h>`
+     * \li Inherit from the `armarx::ArVizComponentPluginUser`. This adds the
+     *     necessary properties (e.g. the topic name) and provides a
+     *     ready-to-use ArViz client called `arviz`.
+     * \li Use the inherited ArViz client variable `arviz` of type `viz::Client`
+     *     to create layers, add visualization elements to the layers,
+     *     and commit the layers to the ArViz topic.
+     *
+     * \see ArVizExample
+     *
      *
      * @class ArVizExample
      * @ingroup Component-ArVizExample
-     * @brief Brief description of class ArVizExample.
      *
-     * Detailed description of class ArVizExample.
+     * @brief An example for how to use ArViz.
+     *
+     * @see @ref Component-ArVizExample
      */
     class ArVizExample :
         virtual public armarx::Component,
-    // Deriving from armarx::ArVizComponentPluginUser adds necessary properties
-    // and provides a ready-to-use ArViz client.
+        // Deriving from armarx::ArVizComponentPluginUser adds necessary properties
+        // and provides a ready-to-use ArViz client called `arviz`.
         virtual public armarx::ArVizComponentPluginUser
     {
     public:
 
-        /// @see armarx::ManagedIceObject::getDefaultName()
-        std::string getDefaultName() const override
-        {
-            return "ArVizExample";
-        }
+        std::string getDefaultName() const override;
+        armarx::PropertyDefinitionsPtr createPropertyDefinitions() override;
 
         void onInitComponent() override;
         void onConnectComponent() override;
@@ -87,12 +87,21 @@ namespace armarx
         void onDisconnectComponent() override;
         void onExitComponent() override;
 
-        armarx::PropertyDefinitionsPtr createPropertyDefinitions() override;
 
     private:
-        void update();
+
+        void run();
+
 
     private:
+
         RunningTask<ArVizExample>::pointer_type task;
+
+        struct Properties
+        {
+            bool manyLayers = false;
+        };
+        Properties properties;
+
     };
 }
diff --git a/source/RobotAPI/components/armem/addon/LegacyRobotStateMemoryAdapter/CMakeLists.txt b/source/RobotAPI/components/armem/addon/LegacyRobotStateMemoryAdapter/CMakeLists.txt
index 9340296c089e80e1be44039534555519936551ba..7f3ad39c47742664118f7f4de02a32d6d85aa8a2 100644
--- a/source/RobotAPI/components/armem/addon/LegacyRobotStateMemoryAdapter/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/addon/LegacyRobotStateMemoryAdapter/CMakeLists.txt
@@ -9,7 +9,9 @@ armarx_add_component(
     LIBS
         ArmarXCore ArmarXCoreInterfaces  # for DebugObserverInterface
         ArmarXGuiComponentPlugins
-        RobotAPICore RobotAPIInterfaces armem armem_robot_state
+        RobotAPICore RobotAPIInterfaces
+        RobotAPI::armem
+        armem_robot_state
 )
 
 #generate the application
diff --git a/source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt b/source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt
index 667e5d5ad070e08f331d505fa4e742ce61b39df7..b9434aeb6575293b01482473f3467403e969ab86 100644
--- a/source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt
@@ -7,7 +7,9 @@ armarx_build_if(OpenCV_FOUND "OpenCV not available")
 set(COMPONENT_LIBS
     ArmarXCore ArmarXCoreInterfaces  # for DebugObserverInterface
     ArmarXGuiComponentPlugins
-    RobotAPICore RobotAPIInterfaces armem aronopencvconverter aronjsonconverter
+    RobotAPICore RobotAPIInterfaces
+    armem
+    aronopencvconverter aronjsonconverter
 
     ${OpenCV_LIBRARIES}
 )
diff --git a/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp b/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp
index eae52c5054369e599acebfa5378075b7a448d6e5..d5ffd4c911804296d10c756577b3c573b3174235 100644
--- a/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp
+++ b/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp
@@ -597,7 +597,6 @@ namespace armarx
 
         if (tab.queryResult)
         {
-            tab.queryResultGroup = armem::server::MemoryRemoteGui().makeGroupBox(*tab.queryResult);
         }
 
         VBoxLayout root = {tab.queryResultGroup, VSpacer()};
diff --git a/source/RobotAPI/components/armem/server/ExampleMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/ExampleMemory/CMakeLists.txt
index de9b660b2175a34c4cd3aeb90152370f222ceb11..b1a5224421ff0147e3fd990c5c17917334dd61a9 100644
--- a/source/RobotAPI/components/armem/server/ExampleMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/ExampleMemory/CMakeLists.txt
@@ -6,7 +6,8 @@ armarx_build_if(OpenCV_FOUND "OpenCV not available")
 set(COMPONENT_LIBS
     ArmarXCore ArmarXCoreInterfaces  # for DebugObserverInterface
     ArmarXGuiComponentPlugins
-    RobotAPICore RobotAPIInterfaces armem
+    RobotAPICore RobotAPIInterfaces
+    armem_server
 )
 
 set(SOURCES
diff --git a/source/RobotAPI/components/armem/server/GeneralPurposeMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/GeneralPurposeMemory/CMakeLists.txt
index f0521043e0891a4b42b3fd75e612b607b3e421aa..278e9c29a43c0d8d42de5d512b128354481d89b9 100644
--- a/source/RobotAPI/components/armem/server/GeneralPurposeMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/GeneralPurposeMemory/CMakeLists.txt
@@ -4,7 +4,7 @@ armarx_component_set_name("GeneralPurposeMemory")
 set(COMPONENT_LIBS
     ArmarXCore ArmarXCoreInterfaces  # for DebugObserverInterface
     ArmarXGuiComponentPlugins
-    RobotAPICore RobotAPIInterfaces armem
+    RobotAPICore RobotAPIInterfaces armem_server
     # RobotAPIComponentPlugins  # for ArViz and other plugins
 
     ${IVT_LIBRARIES}
diff --git a/source/RobotAPI/components/armem/server/GraspMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/GraspMemory/CMakeLists.txt
index 6cedcafc87fd5cab8449ae1a3f8b57db26b96c1d..daf929f79016eb938ee1d3e26bb36aec90d5d1ba 100644
--- a/source/RobotAPI/components/armem/server/GraspMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/GraspMemory/CMakeLists.txt
@@ -4,7 +4,7 @@ armarx_component_set_name("GraspMemory")
 set(COMPONENT_LIBS
     ArmarXCore ArmarXCoreInterfaces  # for DebugObserverInterface
     ArmarXGuiComponentPlugins
-    RobotAPICore RobotAPIInterfaces armem
+    RobotAPICore RobotAPIInterfaces armem_server
     RobotAPIComponentPlugins  # for ArViz and other plugins
     GraspingUtility
     ${IVT_LIBRARIES}
diff --git a/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt
index 4b9a866f9c3be383e589ba9e0bafbc60368f0f57..2762e4152f4a3711b4d49fd8022ef5f5a90bcbe4 100644
--- a/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt
@@ -7,21 +7,20 @@ armarx_add_component(
         ArmarXGuiComponentPlugins
         RobotAPICore
         RobotAPIInterfaces
-        RobotAPI::ArMem
-        RobotAPI::ArMemMotions
-        RobotAPI::armem_mps
+        RobotAPI::armem_server
+        RobotAPI::armem_motions_server
+        RobotAPI::armem_mps_server
+
     SOURCES
         MotionMemory.cpp
+
     HEADERS
         MotionMemory.h
 )
 
 
 # add unit tests
-add_subdirectory(test)
+# add_subdirectory(test)
 
 #generate the application
 armarx_generate_and_add_component_executable()
-
-
-
diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/ObjectMemory/CMakeLists.txt
index 1c90c244bf872fdc4931e0b9067a92c189d9b694..ac589f21a49e3b86f01d413b023dc3825fbf9f7c 100644
--- a/source/RobotAPI/components/armem/server/ObjectMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/ObjectMemory/CMakeLists.txt
@@ -8,7 +8,9 @@ set(COMPONENT_LIBS
     ArmarXGuiComponentPlugins
     # RobotAPI
     RobotAPI::ComponentPlugins
+    RobotAPI::armem_server
     RobotAPI::armem_objects
+    RobotAPI::armem_objects_server
 
     # This project
     ${PROJECT_NAME}Interfaces
diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt
index f49cb33c231a20857aa30458b4f7f5f14c05acdc..24c6616942f86aa4a6e828675db83f59b14aff72 100644
--- a/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt
@@ -10,8 +10,8 @@ set(COMPONENT_LIBS
     # RobotAPI
     RobotAPICore RobotAPIInterfaces
     RobotAPIComponentPlugins
-    armem
-    armem_robot_state
+    RobotAPI::armem_server
+    RobotAPI::armem_robot_state_server
 )
 
 set(SOURCES
diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp
index 3901a510fdcb5bec61a2b18cc2e64b2cab0ecf64..5128cd755f9f0be41689a446f1b1697db956af8c 100644
--- a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp
+++ b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp
@@ -63,6 +63,9 @@ namespace armarx::armem::server::robot_state
 
         const std::string robotUnitPrefix = robotUnit.sensorValuePrefix;
 
+
+	defs->optional(robotUnit.waitForRobotUnit, "WaitForRobotUnit", "Add the robot unit as dependency to the component. This memory requires a running RobotUnit, therefore we should add it as explicit dependency.");
+
         defs->optional(robotUnit.reader.properties.sensorPrefix, robotUnitPrefix + "SensorValuePrefix",
                        "Prefix of all sensor values.");
         defs->optional(robotUnit.pollFrequency, robotUnitPrefix + "UpdateFrequency",
@@ -115,6 +118,11 @@ namespace armarx::armem::server::robot_state
             std::vector<std::string> projectIncludePaths = simox::alg::split(pathsString, ";,");
             includePaths.insert(includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
         }
+
+	if (robotUnit.waitForRobotUnit)
+	{
+		usingProxy(robotUnit.plugin->getRobotUnitName());
+	}
     }
 
 
diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h
index 6459b2aac44dbea0a64c8b2fe35efed2e69f020c..863c9b5711a1effc010488eb9badf3195a88c8c5 100644
--- a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h
+++ b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h
@@ -124,6 +124,8 @@ namespace armarx::armem::server::robot_state
             // queue
             std::queue<proprioception::RobotUnitData> dataQueue;
             std::mutex dataMutex;
+
+	    bool waitForRobotUnit = false;
         };
         RobotUnit robotUnit;
     };
diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/SkillsMemory/CMakeLists.txt
index eee41fad2917ac3689f98d103f1a927a0715d205..dda3d1f24a956c0d1882af2fea2ef056183abc96 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/CMakeLists.txt
@@ -4,7 +4,7 @@ armarx_component_set_name("SkillsMemory")
 set(COMPONENT_LIBS
     ArmarXCore ArmarXCoreInterfaces
     RobotAPICore RobotAPIInterfaces
-    armem armem_skills
+    armem_server armem_skills
 
     ${IVT_LIBRARIES}
 )
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h
index 418d2e00d379d8d9a91ad4db4268090dc124606a..bf4d338d0e642a870c91fe86772d64371e65f1ce 100755
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h
@@ -51,10 +51,10 @@ namespace armarx
         float p = 1.0f;
         float i = 0.0f;
         float d = 0.0f;
-        float maxVelocity = 500;
-        float maxAcceleration = 400;
+        float maxVelocity = 400;
+        float maxAcceleration = 300;
 
-        float p_rot = 0.7f;
+        float p_rot = 0.8f;
         float i_rot = 0.0f;
         float d_rot = 0.0f;
 
diff --git a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.h b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.h
index ccb06e18a3cfafb185c257e9f6e33da8d07dd508..dc6789843bc3d079051591c6af992f26835084d0 100644
--- a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.h
+++ b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.h
@@ -42,6 +42,7 @@ namespace armarx
      * @brief The ArMemMemoryViewer allows visualizing ...
      * @image html ArMemMemoryViewer.png
      * The user can
+     *
      * API Documentation @ref ArMemMemoryViewerWidgetController
      *
      * @see ArMemMemoryViewerGuiPlugin
diff --git a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/CMakeLists.txt b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/CMakeLists.txt
index 7ccd3c5dfe0ca69fc1dbb4f7b48cf854bdff8fa1..c449d1100f0ed75d7ccabe34e7ab6446b2996a1a 100644
--- a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/CMakeLists.txt
+++ b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/CMakeLists.txt
@@ -22,7 +22,8 @@ set(GUI_UIS
 # Add more libraries you depend on here, e.g. ${QT_LIBRARIES}.
 set(COMPONENT_LIBS
     SimpleConfigDialog
-    armem armem_gui
+    RobotAPI::armem
+    RobotAPI::armem_gui
 )
 
 if(ArmarXGui_FOUND)
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
index 2dd295afccc97080bea8e7d4a7dc222324fb71d5..cd089f6c83760e161f4095aaf4b132093100f78f 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
@@ -51,7 +51,7 @@ namespace armarx
 
 
     /**
-    \page ArmarXGui-GuiPlugins-ArViz ArViz
+    \page RobotAPI-GuiPlugins-ArViz ArViz
     \brief The ArViz allows visualizing ...
 
     \image html ArViz.png
diff --git a/source/RobotAPI/gui-plugins/BoxToGraspCandidates/BoxToGraspCandidatesWidgetController.h b/source/RobotAPI/gui-plugins/BoxToGraspCandidates/BoxToGraspCandidatesWidgetController.h
index be3ae8e5ed07ae535958ad80fd74c8343b29e3f4..4a74933b2dec8300cc88109b760effaee7ded3c6 100644
--- a/source/RobotAPI/gui-plugins/BoxToGraspCandidates/BoxToGraspCandidatesWidgetController.h
+++ b/source/RobotAPI/gui-plugins/BoxToGraspCandidates/BoxToGraspCandidatesWidgetController.h
@@ -38,7 +38,7 @@
 namespace armarx
 {
     /**
-    \page ARCHES-GuiPlugins-BoxToGraspCandidates BoxToGraspCandidates
+    \page RobotAPI-GuiPlugins-BoxToGraspCandidates BoxToGraspCandidates
     \brief The BoxToGraspCandidates allows visualizing ...
 
     \image html BoxToGraspCandidates.png
diff --git a/source/RobotAPI/gui-plugins/DebugDrawerViewer/DebugDrawerViewerWidgetController.h b/source/RobotAPI/gui-plugins/DebugDrawerViewer/DebugDrawerViewerWidgetController.h
index b8c58435fb792f97ef8ae3f88c518bb10fd407c2..ac525eccf6f521bce1b4a5d0554b0fe13661d828 100644
--- a/source/RobotAPI/gui-plugins/DebugDrawerViewer/DebugDrawerViewerWidgetController.h
+++ b/source/RobotAPI/gui-plugins/DebugDrawerViewer/DebugDrawerViewerWidgetController.h
@@ -35,7 +35,7 @@
 namespace armarx
 {
     /**
-    \page ArmarXGui-GuiPlugins-DebugDrawerViewer DebugDrawerViewer
+    \page RobotAPI-GuiPlugins-DebugDrawerViewer DebugDrawerViewer
     \brief The DebugDrawerViewer listens on the DebugDrawer topic and visualizes all incoming data.
     This GUI only displays the DebugDrawer content and nothing else.
     The content is shown in the 3D Viewer Widget.
diff --git a/source/RobotAPI/gui-plugins/GuiHealthClient/GuiHealthClientWidgetController.h b/source/RobotAPI/gui-plugins/GuiHealthClient/GuiHealthClientWidgetController.h
index 38448ece1e1fe342fec02b2b7fc0016c61174109..0fed7c1ae22ad51714624a49388e8fec87a2967d 100644
--- a/source/RobotAPI/gui-plugins/GuiHealthClient/GuiHealthClientWidgetController.h
+++ b/source/RobotAPI/gui-plugins/GuiHealthClient/GuiHealthClientWidgetController.h
@@ -35,7 +35,7 @@
 namespace armarx
 {
     /**
-    \page ArmarXGui-GuiPlugins-GuiHealthClient GuiHealthClient
+    \page RobotAPI-GuiPlugins-GuiHealthClient GuiHealthClient
     \brief The GuiHealthClient allows visualizing ...
 
     \image html GuiHealthClient.png
diff --git a/source/RobotAPI/gui-plugins/HomogeneousMatrixCalculator/HomogeneousMatrixCalculatorWidgetController.h b/source/RobotAPI/gui-plugins/HomogeneousMatrixCalculator/HomogeneousMatrixCalculatorWidgetController.h
index 8c726c50144ee12b5b1b31e2bfeacd77f8cafa20..104d0c89be3ff4f5a95511233efaad942330b1a4 100644
--- a/source/RobotAPI/gui-plugins/HomogeneousMatrixCalculator/HomogeneousMatrixCalculatorWidgetController.h
+++ b/source/RobotAPI/gui-plugins/HomogeneousMatrixCalculator/HomogeneousMatrixCalculatorWidgetController.h
@@ -34,7 +34,7 @@
 namespace armarx
 {
     /**
-    \page ArmarXGui-GuiPlugins-HomogeneousMatrixCalculator HomogeneousMatrixCalculator
+    \page RobotAPI-GuiPlugins-HomogeneousMatrixCalculator HomogeneousMatrixCalculator
     \brief The HomogeneousMatrixCalculator allows visualizing ...
 
     \image html HomogeneousMatrixCalculator.png
diff --git a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h
index 9aca4525b7c91bb801e13f6ec7bca97b8e233561..6d87e4fc65c46a9045e13383bb39b8700d1446d2 100644
--- a/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h
+++ b/source/RobotAPI/gui-plugins/LaserScannerPlugin/LaserScannerPluginWidgetController.h
@@ -36,7 +36,7 @@
 namespace armarx
 {
     /**
-    \page ArmarXGui-GuiPlugins-LaserScannerPlugin LaserScannerPlugin
+    \page RobotAPI-GuiPlugins-LaserScannerPlugin LaserScannerPlugin
     \brief The LaserScannerPlugin allows visualizing the raw sensor data captured from multiple laser scanners.
 
     API Documentation \ref LaserScannerPluginWidgetController
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h
index d1111ffa0913679ff35361e5ca8f5160123f7eff..00cd3a3c99457ca041155765cf9de83cbe3dd583 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h
@@ -56,7 +56,7 @@
 namespace armarx
 {
     /**
-    \page ArmarXGui-GuiPlugins-RobotUnitPlugin RobotUnitPlugin
+    \page RobotAPI-GuiPlugins-RobotUnitPlugin RobotUnitPlugin
     \brief The RobotUnitPlugin allows visualizing ...
 
     \image html RobotUnitPlugin.png
diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 18ddb34929d22aacf507a5a162ab65d30245d585..ba231f670b3342011fd228da611d2e9d1b8d87cc 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -3,26 +3,12 @@ set(LIB_NAME armem)
 armarx_component_set_name("${LIB_NAME}")
 armarx_set_target("Library: ${LIB_NAME}")
 
-SET(INSTALL_SCRIPT_MSG
-    "Please use the installation script in RobotAPI/etc/mongocxx to install libmongocxx and libbsoncxx."
-)
-
-find_package(libmongocxx QUIET)
-armarx_build_if(libmongocxx_FOUND "libmongocxx not available. ${INSTALL_SCRIPT_MSG}")
-find_package(libbsoncxx QUIET)
-armarx_build_if(libbsoncxx_FOUND "libbsoncxx not available. ${INSTALL_SCRIPT_MSG}")
-
 
 set(LIBS
-    ArmarXCoreInterfaces ArmarXCore
+    ArmarXCoreInterfaces
+    ArmarXCore
     RemoteGui
     aron
-
-    # Needed for LTM
-    RobotAPI::aron::converter::json
-    RobotAPI::aron::converter::opencv
-    ${LIBMONGOCXX_LIBRARIES}
-    ${LIBBSONCXX_LIBRARIES}
 )
 
 set(LIB_FILES
@@ -79,74 +65,6 @@ set(LIB_FILES
     client/query/Builder.cpp
     client/query/selectors.cpp
 
-
-    server/MemoryToIceAdapter.cpp
-    server/MemoryRemoteGui.cpp
-    server/RemoteGuiAronDataVisitor.cpp
-
-    server/ltm/base/detail/MemoryItem.cpp
-    server/ltm/base/detail/MemoryBase.cpp
-    server/ltm/base/detail/BufferedMemoryBase.cpp
-    server/ltm/base/detail/LUTMemoryBase.cpp
-    server/ltm/base/detail/CoreSegmentBase.cpp
-    server/ltm/base/detail/ProviderSegmentBase.cpp
-    server/ltm/base/detail/EntityBase.cpp
-    server/ltm/base/detail/EntitySnapshotBase.cpp
-
-    server/ltm/base/filter/Filter.cpp
-    server/ltm/base/filter/frequencyFilter/FrequencyFilter.cpp
-
-    server/ltm/base/extractor/Extractor.cpp
-    server/ltm/base/extractor/imageExtractor/ImageExtractor.cpp
-    server/ltm/base/extractor/noExtractor/NoExtractor.cpp
-
-    server/ltm/base/converter/dict/Converter.cpp
-    server/ltm/base/converter/dict/json/JsonConverter.cpp
-    server/ltm/base/converter/dict/bson/BsonConverter.cpp
-    server/ltm/base/converter/image/Converter.cpp
-    server/ltm/base/converter/image/png/PngConverter.cpp
-
-    server/ltm/base/forgetter/Forgetter.cpp
-    server/ltm/base/forgetter/LRUForgetter/LRUForgetter.cpp
-
-    server/ltm/disk/detail/Data.cpp
-    server/ltm/disk/detail/DiskStorage.cpp
-    server/ltm/disk/Memory.cpp
-    server/ltm/disk/CoreSegment.cpp
-    server/ltm/disk/ProviderSegment.cpp
-    server/ltm/disk/Entity.cpp
-    server/ltm/disk/EntitySnapshot.cpp
-
-    server/wm/memory_definitions.cpp
-    server/wm/ice_conversions.cpp
-    server/wm/detail/MaxHistorySize.cpp
-
-    server/plugins/Plugin.cpp
-    server/plugins/ReadOnlyPluginUser.cpp
-    server/plugins/ReadWritePluginUser.cpp
-
-    server/segment/Segment.cpp
-    server/segment/SpecializedSegment.cpp
-
-    server/query_proc/base/BaseQueryProcessorBase.cpp
-    server/query_proc/base/EntityQueryProcessorBase.cpp
-    server/query_proc/base/ProviderSegmentQueryProcessorBase.cpp
-    server/query_proc/base/CoreSegmentQueryProcessorBase.cpp
-    server/query_proc/base/MemoryQueryProcessorBase.cpp
-
-    server/query_proc/ltm/detail/EntityQueryProcessorBase.cpp
-    server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp
-    server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp
-    server/query_proc/ltm/detail/MemoryQueryProcessorBase.cpp
-    server/query_proc/ltm/disk/ltm.cpp
-
-    server/query_proc/wm/detail/EntityQueryProcessorBase.cpp
-    server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp
-    server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp
-    server/query_proc/wm/detail/MemoryQueryProcessorBase.cpp
-    server/query_proc/wm/wm.cpp
-
-
     mns/MemoryNameSystem.cpp
     mns/Registry.cpp
     mns/plugins/Plugin.cpp
@@ -225,81 +143,7 @@ set(LIB_HEADERS
     client/util/SimpleReaderBase.h
     client/util/SimpleWriterBase.h
 
-
     server.h
-    server/forward_declarations.h
-
-    server/MemoryToIceAdapter.h
-    server/MemoryRemoteGui.h
-    server/RemoteGuiAronDataVisitor.h
-
-    server/ltm/base/detail/MemoryItem.h
-    server/ltm/base/detail/MemoryBase.h
-    server/ltm/base/detail/BufferedMemoryBase.h
-    server/ltm/base/detail/LUTMemoryBase.h
-    server/ltm/base/detail/CoreSegmentBase.h
-    server/ltm/base/detail/ProviderSegmentBase.h
-    server/ltm/base/detail/EntityBase.h
-    server/ltm/base/detail/EntitySnapshotBase.h
-
-    server/ltm/base/filter/Filter.h
-    server/ltm/base/filter/frequencyFilter/FrequencyFilter.h
-
-    server/ltm/base/extractor/Extractor.h
-    server/ltm/base/extractor/imageExtractor/ImageExtractor.h
-    server/ltm/base/extractor/noExtractor/NoExtractor.h
-
-    server/ltm/base/converter/dict/Converter.h
-    server/ltm/base/converter/dict/json/JsonConverter.h
-    server/ltm/base/converter/dict/bson/BsonConverter.h
-    server/ltm/base/converter/image/Converter.h
-    server/ltm/base/converter/image/png/PngConverter.h
-
-
-    server/ltm/base/forgetter/Forgetter.h
-    server/ltm/base/forgetter/LRUForgetter/LRUForgetter.h
-
-    server/ltm/disk/detail/Data.h
-    server/ltm/disk/detail/DiskStorage.h
-    server/ltm/disk/Memory.h
-    server/ltm/disk/CoreSegment.h
-    server/ltm/disk/ProviderSegment.h
-    server/ltm/disk/Entity.h
-    server/ltm/disk/EntitySnapshot.h
-
-    server/wm/memory_definitions.h
-    server/wm/ice_conversions.h
-    server/wm/detail/MaxHistorySize.h
-
-    server/plugins.h
-    server/plugins/Plugin.h
-    server/plugins/ReadOnlyPluginUser.h
-    server/plugins/ReadWritePluginUser.h
-
-    server/segment/Segment.h
-    server/segment/SpecializedSegment.h
-
-    server/query_proc.h
-
-    server/query_proc/base.h
-    server/query_proc/base/BaseQueryProcessorBase.h
-    server/query_proc/base/EntityQueryProcessorBase.h
-    server/query_proc/base/ProviderSegmentQueryProcessorBase.h
-    server/query_proc/base/CoreSegmentQueryProcessorBase.h
-    server/query_proc/base/MemoryQueryProcessorBase.h
-
-    server/query_proc/ltm/detail/EntityQueryProcessorBase.h
-    server/query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h
-    server/query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h
-    server/query_proc/ltm/detail/MemoryQueryProcessorBase.h
-    server/query_proc/ltm/disk/ltm.h
-
-    server/query_proc/wm/detail/EntityQueryProcessorBase.h
-    server/query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h
-    server/query_proc/wm/detail/CoreSegmentQueryProcessorBase.h
-    server/query_proc/wm/detail/MemoryQueryProcessorBase.h
-    server/query_proc/wm/wm.h
-
 
     mns.h
     mns/MemoryNameSystem.h
@@ -327,8 +171,7 @@ armarx_add_library(
 add_library(RobotAPI::armem ALIAS "${LIB_NAME}")
 add_library(RobotAPI::ArMem ALIAS "${LIB_NAME}")
 
-target_include_directories("${LIB_NAME}" PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS})
-target_include_directories("${LIB_NAME}" PUBLIC ${LIBBSONCXX_INCLUDE_DIRS})
-
 # add unit tests
 add_subdirectory(test)
+
+add_subdirectory(server)
diff --git a/source/RobotAPI/libraries/armem/server/CMakeLists.txt b/source/RobotAPI/libraries/armem/server/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..00e51e9e99a1fb0b518f88e5685bfa7069dc8667
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/CMakeLists.txt
@@ -0,0 +1,194 @@
+set(LIB_NAME armem_server)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+SET(INSTALL_SCRIPT_MSG
+    "Please use the installation script in RobotAPI/etc/mongocxx to install libmongocxx and libbsoncxx."
+)
+
+find_package(libmongocxx QUIET)
+armarx_build_if(libmongocxx_FOUND "libmongocxx not available. ${INSTALL_SCRIPT_MSG}")
+find_package(libbsoncxx QUIET)
+armarx_build_if(libbsoncxx_FOUND "libbsoncxx not available. ${INSTALL_SCRIPT_MSG}")
+
+
+set(LIBS
+    ArmarXCoreInterfaces
+    ArmarXCore
+    RemoteGui
+    aron
+    RobotAPI::armem
+
+    # Needed for LTM
+    RobotAPI::aron::converter::json
+    RobotAPI::aron::converter::opencv
+    ${LIBMONGOCXX_LIBRARIES}
+    ${LIBBSONCXX_LIBRARIES}
+)
+
+set(LIB_FILES
+    MemoryToIceAdapter.cpp
+    MemoryRemoteGui.cpp
+    RemoteGuiAronDataVisitor.cpp
+
+    ltm/base/detail/MemoryItem.cpp
+    ltm/base/detail/MemoryBase.cpp
+    ltm/base/detail/BufferedMemoryBase.cpp
+    ltm/base/detail/LUTMemoryBase.cpp
+    ltm/base/detail/CoreSegmentBase.cpp
+    ltm/base/detail/ProviderSegmentBase.cpp
+    ltm/base/detail/EntityBase.cpp
+    ltm/base/detail/EntitySnapshotBase.cpp
+
+    ltm/base/filter/Filter.cpp
+    ltm/base/filter/frequencyFilter/FrequencyFilter.cpp
+
+    ltm/base/extractor/Extractor.cpp
+    ltm/base/extractor/imageExtractor/ImageExtractor.cpp
+    ltm/base/extractor/noExtractor/NoExtractor.cpp
+
+    ltm/base/converter/dict/Converter.cpp
+    ltm/base/converter/dict/json/JsonConverter.cpp
+    ltm/base/converter/dict/bson/BsonConverter.cpp
+    ltm/base/converter/image/Converter.cpp
+    ltm/base/converter/image/png/PngConverter.cpp
+
+    ltm/base/forgetter/Forgetter.cpp
+    ltm/base/forgetter/LRUForgetter/LRUForgetter.cpp
+
+    ltm/disk/detail/Data.cpp
+    ltm/disk/detail/DiskStorage.cpp
+    ltm/disk/Memory.cpp
+    ltm/disk/CoreSegment.cpp
+    ltm/disk/ProviderSegment.cpp
+    ltm/disk/Entity.cpp
+    ltm/disk/EntitySnapshot.cpp
+
+    wm/memory_definitions.cpp
+    wm/ice_conversions.cpp
+    wm/detail/MaxHistorySize.cpp
+
+    plugins/Plugin.cpp
+    plugins/ReadOnlyPluginUser.cpp
+    plugins/ReadWritePluginUser.cpp
+
+    segment/Segment.cpp
+    segment/SpecializedSegment.cpp
+
+    query_proc/base/BaseQueryProcessorBase.cpp
+    query_proc/base/EntityQueryProcessorBase.cpp
+    query_proc/base/ProviderSegmentQueryProcessorBase.cpp
+    query_proc/base/CoreSegmentQueryProcessorBase.cpp
+    query_proc/base/MemoryQueryProcessorBase.cpp
+
+    query_proc/ltm/detail/EntityQueryProcessorBase.cpp
+    query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.cpp
+    query_proc/ltm/detail/CoreSegmentQueryProcessorBase.cpp
+    query_proc/ltm/detail/MemoryQueryProcessorBase.cpp
+    query_proc/ltm/disk/ltm.cpp
+
+    query_proc/wm/detail/EntityQueryProcessorBase.cpp
+    query_proc/wm/detail/ProviderSegmentQueryProcessorBase.cpp
+    query_proc/wm/detail/CoreSegmentQueryProcessorBase.cpp
+    query_proc/wm/detail/MemoryQueryProcessorBase.cpp
+    query_proc/wm/wm.cpp
+)
+
+set(LIB_HEADERS
+    forward_declarations.h
+
+    MemoryToIceAdapter.h
+    MemoryRemoteGui.h
+    RemoteGuiAronDataVisitor.h
+
+    ltm/base/detail/MemoryItem.h
+    ltm/base/detail/MemoryBase.h
+    ltm/base/detail/BufferedMemoryBase.h
+    ltm/base/detail/LUTMemoryBase.h
+    ltm/base/detail/CoreSegmentBase.h
+    ltm/base/detail/ProviderSegmentBase.h
+    ltm/base/detail/EntityBase.h
+    ltm/base/detail/EntitySnapshotBase.h
+
+    ltm/base/filter/Filter.h
+    ltm/base/filter/frequencyFilter/FrequencyFilter.h
+
+    ltm/base/extractor/Extractor.h
+    ltm/base/extractor/imageExtractor/ImageExtractor.h
+    ltm/base/extractor/noExtractor/NoExtractor.h
+
+    ltm/base/converter/dict/Converter.h
+    ltm/base/converter/dict/json/JsonConverter.h
+    ltm/base/converter/dict/bson/BsonConverter.h
+    ltm/base/converter/image/Converter.h
+    ltm/base/converter/image/png/PngConverter.h
+
+
+    ltm/base/forgetter/Forgetter.h
+    ltm/base/forgetter/LRUForgetter/LRUForgetter.h
+
+    ltm/disk/detail/Data.h
+    ltm/disk/detail/DiskStorage.h
+    ltm/disk/Memory.h
+    ltm/disk/CoreSegment.h
+    ltm/disk/ProviderSegment.h
+    ltm/disk/Entity.h
+    ltm/disk/EntitySnapshot.h
+
+    wm/memory_definitions.h
+    wm/ice_conversions.h
+    wm/detail/MaxHistorySize.h
+
+    plugins.h
+    plugins/Plugin.h
+    plugins/ReadOnlyPluginUser.h
+    plugins/ReadWritePluginUser.h
+
+    segment/Segment.h
+    segment/SpecializedSegment.h
+
+    query_proc.h
+
+    query_proc/base.h
+    query_proc/base/BaseQueryProcessorBase.h
+    query_proc/base/EntityQueryProcessorBase.h
+    query_proc/base/ProviderSegmentQueryProcessorBase.h
+    query_proc/base/CoreSegmentQueryProcessorBase.h
+    query_proc/base/MemoryQueryProcessorBase.h
+
+    query_proc/ltm/detail/EntityQueryProcessorBase.h
+    query_proc/ltm/detail/ProviderSegmentQueryProcessorBase.h
+    query_proc/ltm/detail/CoreSegmentQueryProcessorBase.h
+    query_proc/ltm/detail/MemoryQueryProcessorBase.h
+    query_proc/ltm/disk/ltm.h
+
+    query_proc/wm/detail/EntityQueryProcessorBase.h
+    query_proc/wm/detail/ProviderSegmentQueryProcessorBase.h
+    query_proc/wm/detail/CoreSegmentQueryProcessorBase.h
+    query_proc/wm/detail/MemoryQueryProcessorBase.h
+    query_proc/wm/wm.h
+)
+
+# Clear variable set by CMakeLists.txt in parent directory.
+set(ARON_FILES "")
+
+armarx_add_library(
+    LIB_NAME
+        "${LIB_NAME}"
+    SOURCES
+        "${LIB_FILES}"
+    HEADERS
+        "${LIB_HEADERS}"
+    LIBS
+        "${LIBS}"
+)
+
+
+add_library(RobotAPI::armem_server ALIAS "${LIB_NAME}")
+
+target_include_directories("${LIB_NAME}" PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS})
+target_include_directories("${LIB_NAME}" PUBLIC ${LIBBSONCXX_INCLUDE_DIRS})
+
+# add unit tests
+add_subdirectory(test)
diff --git a/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp b/source/RobotAPI/libraries/armem/server/test/ArMemLTMBenchmark.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp
rename to source/RobotAPI/libraries/armem/server/test/ArMemLTMBenchmark.cpp
diff --git a/source/RobotAPI/libraries/armem/test/ArMemLTMTest.cpp b/source/RobotAPI/libraries/armem/server/test/ArMemLTMTest.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/test/ArMemLTMTest.cpp
rename to source/RobotAPI/libraries/armem/server/test/ArMemLTMTest.cpp
diff --git a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp b/source/RobotAPI/libraries/armem/server/test/ArMemMemoryTest.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
rename to source/RobotAPI/libraries/armem/server/test/ArMemMemoryTest.cpp
diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/server/test/ArMemQueryTest.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
rename to source/RobotAPI/libraries/armem/server/test/ArMemQueryTest.cpp
diff --git a/source/RobotAPI/libraries/armem/server/test/CMakeLists.txt b/source/RobotAPI/libraries/armem/server/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c8f646815ccd1838019cc74e2d2358451d8ec4c1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/test/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+# Libs required for the tests
+SET(LIBS ${LIBS} ArmarXCore ${LIB_NAME})
+
+armarx_add_test(ArMemLTMTest ArMemLTMTest.cpp "${LIBS}")
+armarx_add_test(ArMemLTMBenchmark ArMemLTMBenchmark.cpp "${LIBS}")
+armarx_add_test(ArMemMemoryTest ArMemMemoryTest.cpp "${LIBS}")
+armarx_add_test(ArMemQueryTest ArMemQueryTest.cpp "${LIBS}")
diff --git a/source/RobotAPI/libraries/armem/test/CMakeLists.txt b/source/RobotAPI/libraries/armem/test/CMakeLists.txt
index a80618cee37da7a0ab0e3198d8f9eda431964bfb..592b9aef3105bd7fc780c92348cae11e60f65a6d 100644
--- a/source/RobotAPI/libraries/armem/test/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/test/CMakeLists.txt
@@ -5,9 +5,5 @@ SET(LIBS ${LIBS} ArmarXCore ${LIB_NAME})
 armarx_add_test(ArMemForEachTest ArMemForEachTest.cpp "${LIBS}")
 armarx_add_test(ArMemGetFindTest ArMemGetFindTest.cpp "${LIBS}")
 armarx_add_test(ArMemIceConversionsTest ArMemIceConversionsTest.cpp "${LIBS}")
-armarx_add_test(ArMemLTMTest ArMemLTMTest.cpp "${LIBS}")
-armarx_add_test(ArMemLTMBenchmark ArMemLTMBenchmark.cpp "${LIBS}")
-armarx_add_test(ArMemMemoryTest ArMemMemoryTest.cpp "${LIBS}")
 armarx_add_test(ArMemMemoryIDTest ArMemMemoryIDTest.cpp "${LIBS}")
 armarx_add_test(ArMemQueryBuilderTest ArMemQueryBuilderTest.cpp "${LIBS}")
-armarx_add_test(ArMemQueryTest ArMemQueryTest.cpp "${LIBS}")
diff --git a/source/RobotAPI/libraries/armem_gui/CMakeLists.txt b/source/RobotAPI/libraries/armem_gui/CMakeLists.txt
index 2a781dd3989d5731393e1b5d9304b06f467611a4..b75fa106e2c89434d1032ba3a0173421fa7e1bc6 100644
--- a/source/RobotAPI/libraries/armem_gui/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem_gui/CMakeLists.txt
@@ -10,7 +10,10 @@ set(LIBRARIES
     # ArmarXGui
     SimpleConfigDialog
     # RobotAPI
-    aroneigenconverter armem
+    aroncommon
+    aroneigenconverter
+    armem
+    armem_server  # for disk LTM
 )
 
 set(SOURCES
@@ -41,6 +44,7 @@ set(SOURCES
     instance/tree_visitors/TreeDataVisitorBase.cpp
     instance/tree_visitors/TreeDataVisitor.cpp
     instance/tree_visitors/TreeTypedDataVisitor.cpp
+    instance/tree_visitors/TreeTypedJSONConverter.cpp
 
     memory/GroupBox.cpp
     memory/TreeWidget.cpp
@@ -81,6 +85,7 @@ set(HEADERS
     instance/tree_visitors/TreeDataVisitorBase.h
     instance/tree_visitors/TreeDataVisitor.h
     instance/tree_visitors/TreeTypedDataVisitor.h
+    instance/tree_visitors/TreeTypedJSONConverter.h
 
     memory/GroupBox.h
     memory/TreeWidget.h
@@ -93,5 +98,9 @@ set(HEADERS
 armarx_gui_library("${LIB_NAME}" "${SOURCES}" "${GUI_MOC_HDRS}" "${GUI_UIS}" "" "${LIBRARIES}")
 
 
+add_library(${PROJECT_NAME}::armem_gui ALIAS armem_gui)
+
+
 # add unit tests
 add_subdirectory(test)
+
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
index 3f4f2cf444028946646e433dae5d85a1b80144d0..a0e0a29743686bb3a6f34f0b759f88ec2ebb5ec8 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
@@ -89,8 +89,6 @@ namespace armarx::armem::gui
         }
 
         // Connections
-        //connect(this, &This::connected, this, &This::updateMemory);
-
         connect(diskControl, &armem::gui::disk::ControlWidget::requestedStoreOnDisk, this, &This::storeOnDisk);
         connect(diskControl, &armem::gui::disk::ControlWidget::requestedLoadFromDisk, this, &This::loadFromDisk);
 
@@ -233,7 +231,7 @@ namespace armarx::armem::gui
 
     void MemoryViewer::startQueries()
     {
-        //memoryReaders = mns.getAllReaders(true);
+        memoryReaders = mns.getAllReaders(true);
         startDueQueries(runningQueries, memoryReaders);
     }
 
diff --git a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
index b1f347c46cc32a391212d1cd89c88255f7703aa8..8a61ecd6de4053dac87894685e2b011aec824245 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
+++ b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
@@ -1,4 +1,5 @@
 #include "InstanceView.h"
+#include <new>
 
 #include <QAction>
 #include <QApplication>
@@ -20,7 +21,6 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
 #include <RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h>
 #include <RobotAPI/libraries/aron/core/type/variant/container/Object.h>
 
@@ -33,6 +33,7 @@
 #include <RobotAPI/libraries/armem_gui/instance/serialize_path.h>
 #include <RobotAPI/libraries/armem_gui/instance/tree_builders/DataTreeBuilder.h>
 #include <RobotAPI/libraries/armem_gui/instance/tree_builders/TypedDataTreeBuilder.h>
+#include <RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.h>
 
 #include "MemoryIDTreeWidgetItem.h"
 #include "WidgetsWithToolbar.h"
@@ -260,6 +261,14 @@ namespace armarx::armem::gui::instance
                 menu.addAction(action);
             }
         }
+        else if (item == this->treeItemData && currentInstance.has_value())
+        {
+            QAction* action = makeActionCopyDataToClipboard();
+            if (action)
+            {
+                menu.addAction(action);
+            }
+        }
         else if (item->parent() == nullptr)
         {
             return;  // Other top level item => no context menu.
@@ -329,7 +338,11 @@ namespace armarx::armem::gui::instance
         const std::optional<aron::Path> elementPath = getElementPath(item);
         if (elementPath)
         {
-            menu.addAction(makeActionCopyDataToClipboard(elementPath.value()));
+            QAction* action = makeActionCopyDataToClipboard(elementPath.value());
+            if (action)
+            {
+                menu.addAction(action);
+            }
         }
 
         if (menu.actions().size() > 0)
@@ -420,19 +433,39 @@ namespace armarx::armem::gui::instance
         return action;
     }
 
+    QAction* InstanceView::makeActionCopyDataToClipboard()
+    {
+        return makeCopyAction(currentInstance->data());
+    }
+
     QAction* InstanceView::makeActionCopyDataToClipboard(const aron::Path& path)
     {
-        QAction* action = new QAction("Copy data to clipboard as JSON");
+        try
+        {
+            aron::data::VariantPtr element = currentInstance->data()->navigateAbsolute(path);
+            return makeCopyAction(element);
+        }
+        catch (const aron::error::AronException& e)
+        {
+            ARMARX_WARNING << "Could not convert Aron data to JSON: " << e.getReason();
+        }
+        return nullptr;
+    }
 
-        connect(action, &QAction::triggered, [this, path]()
+    QAction* InstanceView::makeCopyAction(const aron::data::VariantPtr& element)
+    {
+        QAction* action = new QAction("Copy data to clipboard as JSON");
+        connect(action, &QAction::triggered, [this, element]()
         {
             try
             {
-                aron::data::VariantPtr element = currentInstance->data()->navigateAbsolute(path);
-                nlohmann::json json =
-                    aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(element);
+                TreeTypedJSONConverter conv;
+                // TODO(phesch): Type hierarchy doesn't match data hierarchy
+                armarx::aron::data::visitRecursive(conv, currentInstance->data(), currentAronType);
+                //nlohmann::json json =
+                //   aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(element);
                 QClipboard* clipboard = QApplication::clipboard();
-                clipboard->setText(QString::fromStdString(json.dump(2)));
+                clipboard->setText(QString::fromStdString(conv.getJSON().dump(2)));
                 QApplication::processEvents();
             }
             catch (const aron::error::AronException& e)
@@ -444,7 +477,6 @@ namespace armarx::armem::gui::instance
         return action;
     }
 
-
     void InstanceView::showImageView(const aron::Path& elementPath)
     {
         if (not currentInstance)
diff --git a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h
index 1dc2ce13ec8fadad24072d9301817ceca7779a64..75e41ab9cb4c61f6267e74454d261dff48488ac9 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h
+++ b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h
@@ -79,7 +79,9 @@ namespace armarx::armem::gui::instance
 
         QAction* makeActionResolveMemoryID(const MemoryID& id);
         QAction* makeActionCopyMemoryID(const MemoryID& id);
+        QAction* makeActionCopyDataToClipboard();
         QAction* makeActionCopyDataToClipboard(const aron::Path& path);
+        QAction* makeCopyAction(const aron::data::VariantPtr& element);
 
 
     private:
diff --git a/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.cpp b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b7d157c746d3b4c5dfc99f7bc91fddefe5405af9
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.cpp
@@ -0,0 +1,288 @@
+#include "TreeTypedJSONConverter.h"
+
+#include <SimoxUtility/json/eigen_conversion.h>
+
+#include <ArmarXCore/core/logging/Logging.h>
+
+#include "RobotAPI/libraries/aron/core/Exception.h"
+#include <RobotAPI/libraries/armem/core/Time.h>
+#include <RobotAPI/libraries/aron/converter/eigen/EigenConverter.h>
+
+namespace armarx::armem::gui::instance
+{
+    TreeTypedJSONConverter::TreeTypedJSONConverter()
+    {
+        jsonStack.push({"", nlohmann::json()});
+    }
+
+    const nlohmann::json&
+    TreeTypedJSONConverter::getJSON()
+    {
+        nlohmann::json& obj = jsonStack.top().second;
+        if (obj.front().is_object())
+        {
+            return obj.front();
+        }
+        return obj;
+    }
+
+    void
+    TreeTypedJSONConverter::visitObjectOnEnter(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        std::string key = "";
+        try
+        {
+            key = elementData->getPath().getLastElement();
+        }
+        catch (const aron::error::AronException& e)
+        {
+            // This happens when we start at the top-level object.
+        }
+        jsonStack.push({key, nlohmann::json(nlohmann::json::value_t::object)});
+    }
+
+    void
+    TreeTypedJSONConverter::visitObjectOnExit(DataInput& /*elementData*/,
+                                              TypeInput& /*elementType*/)
+    {
+        auto obj = jsonStack.top();
+        jsonStack.pop();
+        insertIntoJSON(obj.first, obj.second);
+    }
+
+    void
+    TreeTypedJSONConverter::visitDictOnEnter(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitObjectOnEnter(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitDictOnExit(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitObjectOnExit(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitPairOnEnter(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitListOnEnter(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitPairOnExit(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitListOnExit(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitTupleOnEnter(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitListOnEnter(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitTupleOnExit(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitListOnExit(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitListOnEnter(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        jsonStack.push({key, nlohmann::json(nlohmann::json::value_t::array)});
+    }
+
+    void
+    TreeTypedJSONConverter::visitListOnExit(DataInput& /*elementData*/, TypeInput& /*elementType*/)
+    {
+        auto list = jsonStack.top();
+        jsonStack.pop();
+        insertIntoJSON(list.first, list.second);
+    }
+
+    void
+    TreeTypedJSONConverter::visitMatrix(DataInput& elementData, TypeInput& elementType)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        auto t = *aron::type::Matrix::DynamicCastAndCheck(elementType);
+        nlohmann::json obj;
+        if (nd.getType() == "float")
+        {
+            Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>> m(
+                reinterpret_cast<float*>(nd.getData()), t.getRows(), t.getCols());
+            Eigen::to_json(obj, m);
+        }
+        else if (nd.getType() == "double")
+        {
+            Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> m(
+                reinterpret_cast<double*>(nd.getData()), t.getRows(), t.getCols());
+            Eigen::to_json(obj, m);
+        }
+        else
+        {
+            obj = handleGenericNDArray(nd);
+        }
+        insertIntoJSON(key, obj);
+    }
+
+    void
+    TreeTypedJSONConverter::visitNDArray(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, handleGenericNDArray(nd));
+    }
+
+    void
+    TreeTypedJSONConverter::visitQuaternion(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        nlohmann::json obj;
+        Eigen::to_json(obj, aron::converter::AronEigenConverter::ConvertToQuaternionf(nd));
+        insertIntoJSON(key, obj);
+    }
+
+    void
+    TreeTypedJSONConverter::visitOrientation(DataInput& elementData, TypeInput& elementType)
+    {
+        this->visitQuaternion(elementData, elementType);
+    }
+
+    void
+    TreeTypedJSONConverter::visitPosition(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        nlohmann::json obj;
+        Eigen::to_json(obj, aron::converter::AronEigenConverter::ConvertToVector3f(nd));
+        insertIntoJSON(key, obj);
+    }
+
+    void
+    TreeTypedJSONConverter::visitPose(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        nlohmann::json obj;
+        Eigen::to_json(obj, aron::converter::AronEigenConverter::ConvertToMatrix4f(nd));
+        insertIntoJSON(key, obj);
+    }
+
+    void
+    TreeTypedJSONConverter::visitImage(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, handleGenericNDArray(nd));
+    }
+
+    void
+    TreeTypedJSONConverter::visitPointCloud(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        auto nd = *aron::data::NDArray::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, handleGenericNDArray(nd));
+    }
+
+    void
+    TreeTypedJSONConverter::visitIntEnum(DataInput& elementData, TypeInput& elementType)
+    {
+        /* Not handled by the TreeTypedDataVisitor either */
+    }
+
+    void
+    TreeTypedJSONConverter::visitInt(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        int i = *aron::data::Int::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, i);
+    }
+
+    void
+    TreeTypedJSONConverter::visitLong(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        int64_t l = *aron::data::Long::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, l);
+    }
+
+    void
+    TreeTypedJSONConverter::visitFloat(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        float f = *aron::data::Float::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, f);
+    }
+
+    void
+    TreeTypedJSONConverter::visitDouble(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        double d = *aron::data::Double::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, d);
+    }
+
+    void
+    TreeTypedJSONConverter::visitBool(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        bool b = *aron::data::Bool::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, b);
+    }
+
+    void
+    TreeTypedJSONConverter::visitString(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        std::string s = *aron::data::String::DynamicCastAndCheck(elementData);
+        insertIntoJSON(key, s);
+    }
+
+    void
+    TreeTypedJSONConverter::visitTime(DataInput& elementData, TypeInput& /*elementType*/)
+    {
+        const std::string key = elementData->getPath().getLastElement();
+        int64_t l = *aron::data::Long::DynamicCastAndCheck(elementData);
+        armem::Time time = armem::Time::microSeconds(l);
+        insertIntoJSON(key, l);
+        if (!jsonStack.top().second.is_array())
+        {
+            insertIntoJSON(key + "_hr", armem::toDateTimeMilliSeconds(time));
+        }
+    }
+
+    template <typename ElementType>
+    void
+    TreeTypedJSONConverter::insertIntoJSON(const std::string& key, const ElementType& data)
+    {
+        if (jsonStack.top().second.is_object())
+        {
+            jsonStack.top().second[key] = nlohmann::json(data);
+        }
+        else
+        {
+            jsonStack.top().second.emplace_back(data);
+        }
+    }
+
+    nlohmann::json
+    TreeTypedJSONConverter::handleGenericNDArray(const aron::data::NDArray& nd)
+    {
+        nlohmann::json ndobj;
+        std::vector<int> shape = nd.getShape();
+        ndobj["dimensions"] = shape;
+        ndobj["type"] = nd.getType();
+
+        int elements =
+            shape.empty()
+                ? 0
+                : std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>());
+        std::vector<unsigned char> d = std::vector<unsigned char>(elements);
+        memcpy(d.data(), nd.getData(), elements);
+        ndobj["data"] = d;
+        return ndobj;
+    }
+} // namespace armarx::armem::gui::instance
diff --git a/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.h b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a112979e7baa9e01460cc98d00c3d74a0d846e5
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedJSONConverter.h
@@ -0,0 +1,56 @@
+#pragma once
+
+#include <stack>
+#include <utility>
+
+#include <SimoxUtility/json/json.hpp>
+
+#include <RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h>
+
+namespace armarx::armem::gui::instance
+{
+    class TreeTypedJSONConverter : public aron::data::RecursiveConstTypedVariantVisitor
+    {
+    public:
+        TreeTypedJSONConverter();
+        ~TreeTypedJSONConverter() override = default;
+
+        const nlohmann::json& getJSON();
+
+        void visitObjectOnEnter(DataInput& elementData, TypeInput& elementType) override;
+        void visitObjectOnExit(DataInput& elementData, TypeInput& elementType) override;
+        void visitDictOnEnter(DataInput& elementData, TypeInput& elementType) override;
+        void visitDictOnExit(DataInput& elementData, TypeInput& elementType) override;
+        void visitPairOnEnter(DataInput& elementData, TypeInput& elementType) override;
+        void visitPairOnExit(DataInput& elementData, TypeInput& elementType) override;
+        void visitTupleOnEnter(DataInput& elementData, TypeInput& elementType) override;
+        void visitTupleOnExit(DataInput& elementData, TypeInput& elementType) override;
+        void visitListOnEnter(DataInput& elementData, TypeInput& elementType) override;
+        void visitListOnExit(DataInput& elementData, TypeInput& elementType) override;
+
+        void visitMatrix(DataInput& elementData, TypeInput& elementType) override;
+        void visitNDArray(DataInput& elementData, TypeInput& elementType) override;
+        void visitQuaternion(DataInput& elementData, TypeInput& elementType) override;
+        void visitOrientation(DataInput& elementData, TypeInput& elementType) override;
+        void visitPosition(DataInput& elementData, TypeInput& elementType) override;
+        void visitPose(DataInput& elementData, TypeInput& elementType) override;
+        void visitImage(DataInput& elementData, TypeInput& elementType) override;
+        void visitPointCloud(DataInput& elementData, TypeInput& elementType) override;
+        void visitIntEnum(DataInput& elementData, TypeInput& elementType) override;
+        void visitInt(DataInput& elementData, TypeInput& elementType) override;
+        void visitLong(DataInput& elementData, TypeInput& elementType) override;
+        void visitFloat(DataInput& elementData, TypeInput& elementType) override;
+        void visitDouble(DataInput& elementData, TypeInput& elementType) override;
+        void visitBool(DataInput& elementData, TypeInput& elementType) override;
+        void visitString(DataInput& elementData, TypeInput& elementType) override;
+        void visitTime(DataInput& elementData, TypeInput& elementType) override;
+
+    private:
+        std::stack<std::pair<std::string, nlohmann::json>> jsonStack;
+
+        template <typename ElementType>
+        void insertIntoJSON(const std::string& key, const ElementType& data);
+
+        static nlohmann::json handleGenericNDArray(const aron::data::NDArray& nd);
+    };
+} // namespace armarx::armem::gui::instance
diff --git a/source/RobotAPI/libraries/armem_gui/server/CMakeLists.txt b/source/RobotAPI/libraries/armem_gui/server/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..46fce90ac352efc0ed0870d4988fb1eea80dfa0e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_gui/server/CMakeLists.txt
@@ -0,0 +1,99 @@
+set(LIB_NAME       armem_gui)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+
+set(LIBRARIES
+    # ArmarXCore
+    ArmarXCoreInterfaces ArmarXCore
+    # ArmarXGui
+    SimpleConfigDialog
+    # RobotAPI
+    aroneigenconverter armem
+)
+
+set(SOURCES
+
+    gui_utils.cpp
+    lifecycle.cpp
+
+    MemoryViewer.cpp
+    PeriodicUpdateWidget.cpp
+
+    disk/ControlWidget.cpp
+
+    instance/GroupBox.cpp
+    instance/ImageView.cpp
+    instance/InstanceView.cpp
+    instance/MemoryIDTreeWidgetItem.cpp
+    instance/WidgetsWithToolbar.cpp
+    instance/sanitize_typename.cpp
+    instance/serialize_path.cpp
+
+    instance/display_visitors/DataDisplayVisitor.cpp
+    instance/display_visitors/TypedDataDisplayVisitor.cpp
+
+    instance/tree_builders/DataTreeBuilder.cpp
+    instance/tree_builders/DataTreeBuilderBase.cpp
+    instance/tree_builders/TypedDataTreeBuilder.cpp
+
+    instance/tree_visitors/TreeDataVisitorBase.cpp
+    instance/tree_visitors/TreeDataVisitor.cpp
+    instance/tree_visitors/TreeTypedDataVisitor.cpp
+    instance/tree_visitors/TreeTypedJSONConverter.cpp
+
+    memory/GroupBox.cpp
+    memory/TreeWidget.cpp
+
+    query_widgets/QueryWidget.cpp
+    query_widgets/SnapshotForm.cpp
+    query_widgets/SnapshotSelectorWidget.cpp
+)
+set(HEADERS
+
+    gui_utils.h
+    lifecycle.h
+
+    MemoryViewer.h
+    PeriodicUpdateWidget.h
+    TreeWidgetBuilder.h
+
+    PeriodicUpdateWidget.h
+    TreeWidgetBuilder.h
+
+    disk/ControlWidget.h
+
+    instance/GroupBox.h
+    instance/ImageView.h
+    instance/InstanceView.h
+    instance/MemoryIDTreeWidgetItem.h
+    instance/WidgetsWithToolbar.h
+    instance/sanitize_typename.h
+    instance/serialize_path.h
+
+    instance/display_visitors/DataDisplayVisitor.h
+    instance/display_visitors/TypedDataDisplayVisitor.h
+
+    instance/tree_builders/DataTreeBuilder.h
+    instance/tree_builders/DataTreeBuilderBase.h
+    instance/tree_builders/TypedDataTreeBuilder.h
+
+    instance/tree_visitors/TreeDataVisitorBase.h
+    instance/tree_visitors/TreeDataVisitor.h
+    instance/tree_visitors/TreeTypedDataVisitor.h
+    instance/tree_visitors/TreeTypedJSONConverter.h
+
+    memory/GroupBox.h
+    memory/TreeWidget.h
+
+    query_widgets/QueryWidget.h
+    query_widgets/SnapshotForm.h
+    query_widgets/SnapshotSelectorWidget.h
+)
+
+armarx_gui_library("${LIB_NAME}" "${SOURCES}" "${GUI_MOC_HDRS}" "${GUI_UIS}" "" "${LIBRARIES}")
+
+
+# add unit tests
+add_subdirectory(test)
diff --git a/source/RobotAPI/libraries/armem_motions/CMakeLists.txt b/source/RobotAPI/libraries/armem_motions/CMakeLists.txt
index bf222bcec14b760e988327bd0d038322fce32b97..d82a0952ee75f711fc0c9c067d5ed860d68b25f1 100644
--- a/source/RobotAPI/libraries/armem_motions/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem_motions/CMakeLists.txt
@@ -14,15 +14,15 @@ armarx_add_library(
         RobotAPI::PriorKnowledge::Motions
         
     SOURCES
-        ./server/mdb_conversions.cpp
-        ./server/MotionSegment.cpp
+        armem_motions.cpp
     HEADERS
-        ./server/mdb_conversions.h
-        ./server/MotionSegment.h
+        armem_motions.h
     ARON_FILES
-        ./aron/MDBReference.xml
+        aron/MDBReference.xml
 )
 
 
 add_library(RobotAPI::ArMemMotions ALIAS armem_motions)
 add_library(RobotAPI::armem_motions ALIAS armem_motions)
+
+add_subdirectory(server)
diff --git a/source/RobotAPI/libraries/armem_motions/armem_motions.cpp b/source/RobotAPI/libraries/armem_motions/armem_motions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a675039efc6efeb0220ea11ee11f61cc60ed24e1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_motions/armem_motions.cpp
@@ -0,0 +1,6 @@
+#include "armem_motions.h"
+
+namespace armarx::armem::motions::mdb
+{
+
+}
diff --git a/source/RobotAPI/libraries/armem_motions/armem_motions.h b/source/RobotAPI/libraries/armem_motions/armem_motions.h
new file mode 100644
index 0000000000000000000000000000000000000000..f9dca33dd7b46131ee27c6d52c2cf7e4e579f9c4
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_motions/armem_motions.h
@@ -0,0 +1,7 @@
+#pragma once
+
+
+namespace armarx::armem::motions::mdb
+{
+
+}
diff --git a/source/RobotAPI/libraries/armem_motions/server/CMakeLists.txt b/source/RobotAPI/libraries/armem_motions/server/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5aaac747df0903aab354366f97d950adce1f1dc1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_motions/server/CMakeLists.txt
@@ -0,0 +1,31 @@
+set(ARMARX_LIB_NAME "" )
+set(ARON_FILES "")
+
+set(LIB_NAME       armem_motions_server)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+armarx_add_library(
+    LIBS
+        ArmarXCoreInterfaces
+        ArmarXCore
+        ArmarXCoreObservers
+
+        RobotAPI::Core
+        RobotAPI::armem_server
+        RobotAPI::PriorKnowledge::Motions
+        RobotAPI::armem_motions
+        
+    SOURCES
+        mdb_conversions.cpp
+        MotionSegment.cpp
+
+    HEADERS
+        mdb_conversions.h
+        MotionSegment.h
+)
+
+
+add_library(RobotAPI::ArMemMotions_server ALIAS armem_motions_server)
+add_library(RobotAPI::armem_motions_server ALIAS armem_motions_server)
diff --git a/source/RobotAPI/libraries/armem_mps/CMakeLists.txt b/source/RobotAPI/libraries/armem_mps/CMakeLists.txt
index 68cc66e6bb96278954f919b379d15bb03dcf8902..b436f3168cd2f75f8e9e8cc7cae9a04d11f4b6e1 100644
--- a/source/RobotAPI/libraries/armem_mps/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem_mps/CMakeLists.txt
@@ -2,7 +2,6 @@ set(LIB_NAME       armem_mps)
 
 armarx_component_set_name("${LIB_NAME}")
 armarx_set_target("Library: ${LIB_NAME}")
-find_package(DMP QUIET) # needs to be changed to new MP package
 
 armarx_build_if(DMP_FOUND "DMP not available")
 
@@ -11,31 +10,28 @@ armarx_add_library(
         ArmarXCoreInterfaces
         ArmarXCore
         ArmarXCoreObservers
-        ${DMP_LIBRARIES}
+
         RobotAPI::Core
         RobotAPI::armem
         RobotAPI::PriorKnowledge::Motions
         RobotAPI::armem_motions
+
         VirtualRobot
+        ${DMP_LIBRARIES}
+
     SOURCES  
-        ./aron_conversions.cpp
-        #./traj_conversions.cpp
-        ./server/MotionPrimitives/motionprimitives.cpp
-        ./server/MotionPrimitives/Segment.cpp
-    HEADERS  
-        ./aron_conversions.h
-        #./traj_conversions.h
-        ./server/MotionPrimitives/motionprimitives.h
-        ./server/MotionPrimitives/Segment.h
-)
+        aron_conversions.cpp
+        #traj_conversions.cpp
 
+    HEADERS  
+        aron_conversions.h
+        #traj_conversions.h
 
-armarx_enable_aron_file_generation_for_target(
-    TARGET_NAME
-    "${LIB_NAME}"
     ARON_FILES
-    aron/Trajectory.xml
+        aron/Trajectory.xml
 )
 
 
 add_library(RobotAPI::armem_mps ALIAS armem_mps)
+
+add_subdirectory(server)
diff --git a/source/RobotAPI/libraries/armem_mps/server/CMakeLists.txt b/source/RobotAPI/libraries/armem_mps/server/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c4a5854ce895a7415a6ba21cdd06b8b4b03eb6c8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_mps/server/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(ARMARX_LIB_NAME "" )
+set(ARON_FILES "")
+
+set(LIB_NAME       armem_mps_server)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+armarx_build_if(DMP_FOUND "DMP not available")
+
+armarx_add_library(
+    LIBS     
+        ArmarXCoreInterfaces
+        ArmarXCore
+        ArmarXCoreObservers
+
+        RobotAPI::Core
+        RobotAPI::armem_server
+        RobotAPI::PriorKnowledge::Motions
+        RobotAPI::armem_motions
+        RobotAPI::armem_mps
+
+        VirtualRobot
+        ${DMP_LIBRARIES}
+
+    SOURCES  
+        MotionPrimitives/motionprimitives.cpp
+        MotionPrimitives/Segment.cpp
+
+    HEADERS  
+        MotionPrimitives/motionprimitives.h
+        MotionPrimitives/Segment.h
+)
+
+
+add_library(RobotAPI::armem_mps_server ALIAS armem_mps_server)
diff --git a/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.cpp b/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.cpp
index 598cb580af72e4b3e9f40d0e86cb785d7e14c7d5..074f28c76d129a66eeea1b854941583bdb0809c0 100644
--- a/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.cpp
+++ b/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.cpp
@@ -1,50 +1,61 @@
 #include "motionprimitives.h"
 
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+// #include <iostream>
+// #include <fstream>
 
 #include <SimoxUtility/algorithm/string.h>
 
-#include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
-
-#include <RobotAPI/libraries/armem_mps/aron/Trajectory.aron.generated.h>
+#include <VirtualRobot/MathTools.h>
 
 #include <dmp/representation/trajectory.h>
-#include <ArmarXCore/core/system/ArmarXDataPath.h>
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/core/logging/Logging.h>
-#include <VirtualRobot/MathTools.h>
+#include <ArmarXCore/core/system/ArmarXDataPath.h>
 
-namespace armarx::armem::mps
-{
+#include <RobotAPI/libraries/armem/core/error.h>
+#include <RobotAPI/libraries/armem_mps/aron/Trajectory.aron.generated.h>
 
-std::optional<arondto::Trajectory> createFromFile(const std::filesystem::__cxx11::path &pathToInfoJson, bool taskspace)
+
+namespace armarx::armem::mps
 {
 
-    if (std::filesystem::exists(pathToInfoJson) && std::filesystem::is_regular_file(pathToInfoJson))
+    std::optional<arondto::Trajectory>
+    createFromFile(
+            const std::filesystem::path &pathToInfoJson,
+            bool taskspace)
     {
-        DMP::Vec<DMP::SampledTrajectoryV2 > trajs;
-        DMP::SampledTrajectoryV2 traj;
-        std::string absPath;
-        ArmarXDataPath::getAbsolutePath(pathToInfoJson, absPath);
-        traj.readFromCSVFile(absPath);
-        //traj = DMP::SampledTrajectoryV2::normalizeTimestamps(traj, 0, 1);
-        std::map<double, DMP::DVec> currentTraj = traj.getPositionData();//todo
-        trajs.push_back(traj);
-        arondto::Trajectory trajectory;
-        std::string name = pathToInfoJson.filename();
-        std::string toErase = "taskspace-trajectory-";
-        size_t pos = name.find(toErase);
-        if (pos != std::string::npos)
+        if (std::filesystem::exists(pathToInfoJson) && std::filesystem::is_regular_file(pathToInfoJson))
         {
-            name.erase(pos, toErase.length());
-        }
-        trajectory.name = name;
-        std::map<std::string, std::vector<float>> mapJointSpace;
-        for(DMP::SampledTrajectoryV2 traj: trajs){
-            std::map<double, DMP::DVec> currentTraj = traj.getPositionData(); // todo: add config making data structure clear
+            DMP::Vec<DMP::SampledTrajectoryV2 > trajs;
+            DMP::SampledTrajectoryV2 traj;
+            std::string absPath;
+            ArmarXDataPath::getAbsolutePath(pathToInfoJson, absPath);
+            traj.readFromCSVFile(absPath);
+
+            //traj = DMP::SampledTrajectoryV2::normalizeTimestamps(traj, 0, 1);
+            std::map<double, DMP::DVec> currentTraj = traj.getPositionData();  //todo
+            trajs.push_back(traj);
+
+            arondto::Trajectory trajectory;
+            std::string name = pathToInfoJson.filename();
+            std::string toErase = "taskspace-trajectory-";
+            size_t pos = name.find(toErase);
+            if (pos != std::string::npos)
+            {
+                name.erase(pos, toErase.length());
+            }
+            trajectory.name = name;
 
-            if(taskspace){
-                    for(std::pair<double, DMP::DVec> element: currentTraj){
+            std::map<std::string, std::vector<float>> mapJointSpace;
+            for (const DMP::SampledTrajectoryV2& traj: trajs)
+            {
+                std::map<double, DMP::DVec> currentTraj = traj.getPositionData(); // todo: add config making data structure clear
+
+                if (taskspace)
+                {
+                    for (std::pair<double, DMP::DVec> element: currentTraj)
+                    {
                         Eigen::Vector3f vec(element.second.at(0), element.second.at(1), element.second.at(2));
                         Eigen::Matrix<float, 4, 4> poseMatrix = VirtualRobot::MathTools::quat2eigen4f(element.second.at(4), element.second.at(5), element.second.at(6), element.second.at(3));
                         poseMatrix.block<3, 1>(0, 3) = vec;
@@ -52,33 +63,31 @@ std::optional<arondto::Trajectory> createFromFile(const std::filesystem::__cxx11
                         tselement.timestep = element.first;
                         tselement.pose = poseMatrix;
                         trajectory.taskSpace.steps.push_back(tselement);
-
                     }
-
-
-            }else{
-                for(std::pair<double, DMP::DVec> element: currentTraj){
-                    std::vector<float> configvec;
-                    for(double el: element.second){
-                        configvec.push_back(float(el));
+                }
+                else
+                {
+                    for (auto& [time, pos] : currentTraj)
+                    {
+                        std::vector<float> configvec;
+                        for (double el: pos)
+                        {
+                            configvec.push_back(float(el));
+                        }
+                        arondto::JSElement jselement;
+                        jselement.timestep = time;
+                        jselement.jointValues = configvec;
+                        trajectory.jointSpace.steps.push_back(jselement);
                     }
-                    arondto::JSElement jselement;
-                    jselement.timestep = element.first;
-                    jselement.jointValues = configvec;
-                    trajectory.jointSpace.steps.push_back(jselement);
                 }
             }
 
+            return trajectory;
+        }
+        else
+        {
+            return std::nullopt;
         }
-
-        return trajectory;
-    }
-    else
-    {
-        return std::nullopt;
     }
-}
-
-
 
 }
diff --git a/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.h b/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.h
index be5b41fab7c04bcc526e9642fd118e7fe8186b1c..dfe9916bbf256b838cf99bb3a2dfe4972a47be55 100644
--- a/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.h
+++ b/source/RobotAPI/libraries/armem_mps/server/MotionPrimitives/motionprimitives.h
@@ -1,19 +1,16 @@
-#ifndef MOTIONPRIMITIVES_H
-#define MOTIONPRIMITIVES_H
+#pragma once
 
 #include <filesystem>
-#include <iostream>
-#include <fstream>
 #include <optional>
 
 // ArmarX
-#include <RobotAPI/libraries/armem_motions/aron/MDBReference.aron.generated.h>
+// #include <RobotAPI/libraries/armem_motions/aron/MDBReference.aron.generated.h>
 #include <RobotAPI/libraries/armem_mps/aron/Trajectory.aron.generated.h>
 
+
 namespace armarx::armem::mps
 {
 
     std::optional<arondto::Trajectory> createFromFile(const std::filesystem::path& pathToInfoJson, bool taskspace);
 
 }
-#endif // MOTIONPRIMITIVES_H
diff --git a/source/RobotAPI/libraries/armem_objects/CMakeLists.txt b/source/RobotAPI/libraries/armem_objects/CMakeLists.txt
index ab26b1f8a38b5e18b16dc49a498c9369d6d918db..88fd8cf80f190ee13489c8180e4c4a53f652caff 100644
--- a/source/RobotAPI/libraries/armem_objects/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem_objects/CMakeLists.txt
@@ -50,18 +50,6 @@ armarx_add_library(
 
         SceneSnapshot.cpp
 
-        server/class/FloorVis.cpp
-        server/class/Segment.cpp
-
-        server/instance/Segment.cpp
-        server/instance/SegmentAdapter.cpp
-        server/instance/Decay.cpp
-        server/instance/RobotHeadMovement.cpp
-        server/instance/Visu.cpp
-        server/instance/ArticulatedObjectVisu.cpp
-
-        server/attachments/Segment.cpp
-
         client/articulated_object/Reader.cpp
         client/articulated_object/Writer.cpp
         client/articulated_object/ArticulatedObjectReader.cpp
@@ -71,13 +59,6 @@ armarx_add_library(
         client/attachment/Reader.cpp
         client/attachment/Writer.cpp
 
-)
-
-
-
-armarx_enable_aron_file_generation_for_target(
-    TARGET_NAME
-        "${LIB_NAME}"
     ARON_FILES
         aron/ObjectClass.xml
         aron/ObjectInstance.xml
@@ -86,7 +67,7 @@ armarx_enable_aron_file_generation_for_target(
         # aron/Constraint.xml
 )
 
+
 add_library(${PROJECT_NAME}::armem_objects ALIAS armem_objects)
 
-# add unit tests
-# add_subdirectory(test)
+add_subdirectory(server)
diff --git a/source/RobotAPI/libraries/armem_objects/server/CMakeLists.txt b/source/RobotAPI/libraries/armem_objects/server/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cf92773305aac9c8d4c1ce69abbf86bd3b6789ea
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_objects/server/CMakeLists.txt
@@ -0,0 +1,54 @@
+set(ARMARX_LIB_NAME "" )
+set(ARON_FILES "")
+
+set(LIB_NAME    armem_objects_server)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+
+armarx_add_library(
+    LIBS
+        # ArmarXCore
+        ArmarXCore
+        # ArmarXGui
+        ArmarXGuiComponentPlugins
+        # RobotAPI
+        RobotAPI::ArViz
+        RobotAPI::ComponentPlugins
+        RobotAPI::Core
+        RobotAPI::armem_server
+        RobotAPI::armem_robot
+        RobotAPI::armem_objects
+
+    HEADERS
+
+        class/FloorVis.h
+        class/Segment.h
+
+        instance/Segment.h
+        instance/SegmentAdapter.h
+        instance/Decay.h
+        instance/RobotHeadMovement.h
+        instance/Visu.h
+        instance/ArticulatedObjectVisu.h
+
+        attachments/Segment.h
+
+    SOURCES
+        class/FloorVis.cpp
+        class/Segment.cpp
+
+        instance/Segment.cpp
+        instance/SegmentAdapter.cpp
+        instance/Decay.cpp
+        instance/RobotHeadMovement.cpp
+        instance/Visu.cpp
+        instance/ArticulatedObjectVisu.cpp
+
+        attachments/Segment.cpp
+)
+
+
+add_library(${PROJECT_NAME}::armem_objects_server ALIAS armem_objects_server)
+
diff --git a/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt b/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt
index c86ed671ef17fcd287c05a7083abf3803b852e99..2c46fab4e7f811e979609b96b62ca5a02cb65b15 100644
--- a/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt
@@ -3,7 +3,6 @@ set(LIB_NAME armem_robot_state)
 armarx_component_set_name("${LIB_NAME}")
 armarx_set_target("Library: ${LIB_NAME}")
 
-find_package(Eigen3 QUIET)
 armarx_build_if(Eigen3_FOUND "Eigen3 not available")
 
 
@@ -36,26 +35,6 @@ armarx_add_library(
         client/localization/TransformReader.h
         client/localization/TransformWriter.h
 
-        server/forward_declarations.h
-
-        server/common/Visu.h
-        server/common/combine.h
-
-        server/localization/Segment.h
-
-        server/proprioception/Segment.h
-        server/proprioception/aron_conversions.h
-        server/proprioception/RobotStateWriter.h
-        server/proprioception/RobotUnitData.h
-        server/proprioception/RobotUnitReader.h
-
-        server/proprioception/converters/Armar6Converter.h
-        server/proprioception/converters/ConverterTools.h
-        server/proprioception/converters/ConverterRegistry.h
-        server/proprioception/converters/ConverterInterface.h
-
-        server/description/Segment.h
-
         aron_conversions.h
         utils.h
 
@@ -68,24 +47,6 @@ armarx_add_library(
         client/localization/TransformReader.cpp
         client/localization/TransformWriter.cpp
 
-        server/common/Visu.cpp
-        server/common/combine.cpp
-
-        server/localization/Segment.cpp
-
-        server/proprioception/Segment.cpp
-        server/proprioception/aron_conversions.cpp
-        server/proprioception/RobotStateWriter.cpp
-        server/proprioception/RobotUnitData.cpp
-        server/proprioception/RobotUnitReader.cpp
-
-        server/proprioception/converters/Armar6Converter.cpp
-        server/proprioception/converters/ConverterTools.cpp
-        server/proprioception/converters/ConverterRegistry.cpp
-        server/proprioception/converters/ConverterInterface.cpp
-
-        server/description/Segment.cpp
-
         aron_conversions.cpp
         utils.cpp
 )
@@ -104,3 +65,5 @@ armarx_enable_aron_file_generation_for_target(
 
 
 add_library(RobotAPI::armem_robot_state ALIAS armem_robot_state)
+
+add_subdirectory(server)
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp
index 92c5039cadbc9015af4a2488500869ed197b0362..4428f3d967085e9d1f1a8e1951c5524d1097b2e7 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp
@@ -3,19 +3,19 @@
 #include <mutex>
 #include <optional>
 
-#include "ArmarXCore/core/exceptions/local/ExpressionException.h"
-#include "RobotAPI/libraries/armem_robot/types.h"
+#include <ArmarXCore/core/PackagePath.h>
 #include <ArmarXCore/core/exceptions/LocalException.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 #include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/PackagePath.h>
 
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
-#include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/Time.h>
+#include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot/aron_conversions.h>
 #include <RobotAPI/libraries/armem_robot/robot_conversions.h>
-#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h>
+#include <RobotAPI/libraries/armem_robot/types.h>
 #include <RobotAPI/libraries/armem_robot_state/aron/JointState.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot_state/aron_conversions.h>
@@ -54,7 +54,8 @@ namespace armarx::armem::robot_state
         try
         {
             memoryReader = memoryNameSystem.useReader(properties.memoryName);
-            ARMARX_IMPORTANT << "RobotReader: Connected to memory '" << properties.memoryName << "'";
+            ARMARX_IMPORTANT << "RobotReader: Connected to memory '" << properties.memoryName
+                             << "'";
         }
         catch (const armem::error::CouldNotResolveMemoryServer& e)
         {
@@ -81,9 +82,9 @@ namespace armarx::armem::robot_state
     RobotReader::get(const robot::RobotDescription& description, const armem::Time& timestamp)
     {
         robot::Robot robot{.description = description,
-                           .instance    = "", // TODO(fabian.reister):
-                           .config      = {}, // will be populated by synchronize
-                           .timestamp   = timestamp};
+                           .instance = "", // TODO(fabian.reister):
+                           .config = {}, // will be populated by synchronize
+                           .timestamp = timestamp};
 
         synchronize(robot, timestamp);
 
@@ -300,11 +301,12 @@ namespace armarx::armem::robot_state
         // clang-format on
 
         const armem::wm::EntityInstance* instance = nullptr;
-        providerSegment.forEachInstance([&instance](const wm::EntityInstance & i)
-        {
-            instance = &i;
-            return false;  // break
-        });
+        providerSegment.forEachInstance(
+            [&instance](const wm::EntityInstance& i)
+            {
+                instance = &i;
+                return false; // break
+            });
         if (!instance)
         {
             ARMARX_WARNING << "No entity snapshots found";
@@ -320,7 +322,8 @@ namespace armarx::armem::robot_state
     std::optional<AronClass>
     tryCast(const wm::EntityInstance& item)
     {
-        static_assert(std::is_base_of<armarx::aron::codegenerator::cpp::AronCppClass, AronClass>::value);
+        static_assert(
+            std::is_base_of<armarx::aron::codegenerator::cpp::AronCppClass, AronClass>::value);
 
         try
         {
@@ -344,27 +347,29 @@ namespace armarx::armem::robot_state
                 .getCoreSegment(properties.proprioceptionCoreSegment);
         // clang-format on
 
-        coreSegment.forEachEntity([&jointMap](const wm::Entity & entity)
-        {
-            const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
+        coreSegment.forEachEntity(
+            [&jointMap](const wm::Entity& entity)
+            {
+                const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
 
-            const auto proprioception = tryCast<::armarx::armem::arondto::Proprioception>(entityInstance);
-            ARMARX_CHECK(proprioception.has_value());
+                const auto proprioception =
+                    tryCast<::armarx::armem::arondto::Proprioception>(entityInstance);
+                ARMARX_CHECK(proprioception.has_value());
 
                 const armarx::armem::prop::arondto::Joints& joints = proprioception->joints;
 
 
-            // const auto jointState = tryCast<::armarx::armem::arondto::JointState>(entityInstance);
-            // if (not jointState)
-            // {
-            //     ARMARX_WARNING << "Could not convert entity instance to 'JointState'";
-            //     return;
-            // }
+                // const auto jointState = tryCast<::armarx::armem::arondto::JointState>(entityInstance);
+                // if (not jointState)
+                // {
+                //     ARMARX_WARNING << "Could not convert entity instance to 'JointState'";
+                //     return;
+                // }
 
-            jointMap = joints.position;
+                jointMap = joints.position;
 
-            // jointMap.emplace(jointState->name, jointState->position);
-        });
+                // jointMap.emplace(jointState->name, jointState->position);
+            });
 
         if (jointMap.empty())
         {
@@ -569,11 +574,9 @@ namespace armarx::armem::robot_state
                 .getCoreSegment(properties.proprioceptionCoreSegment);
         // clang-format on
 
-        coreSegment.forEachEntity(
-            [&forceTorques](const wm::Entity& entity)
+        coreSegment.forEachInstance(
+            [&forceTorques](const wm::EntityInstance& entityInstance)
             {
-                const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
-
                 const auto proprioception =
                     tryCast<::armarx::armem::arondto::Proprioception>(entityInstance);
                 ARMARX_CHECK(proprioception.has_value());
diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp
index 1c0152a463d5c38abb3b1c81f1014e1f74ef4d77..0907cb70b01220686d2b6b30a2d5577c1e6838c3 100644
--- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.cpp
@@ -77,7 +77,7 @@ namespace armarx::armem::robot_state
             const armem::Time& timestamp,
             const VirtualRobot::RobotIO::RobotDescription& loadMode)
     {
-        auto robot = getRobot(name, timestamp);
+        auto robot = getRobot(name, timestamp, loadMode);
 
         synchronizeRobot(*robot, timestamp);
 
diff --git a/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt b/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..848efe75e0b615f367f5602c9cdfdfb3cdbbd7ea
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt
@@ -0,0 +1,73 @@
+set(ARMARX_LIB_NAME "" )
+set(ARON_FILES "")
+
+set(LIB_NAME armem_robot_state_server)
+
+armarx_component_set_name("${LIB_NAME}")
+armarx_set_target("Library: ${LIB_NAME}")
+
+armarx_build_if(Eigen3_FOUND "Eigen3 not available")
+
+
+armarx_add_library(
+    LIBS 
+        # ArmarX
+        ArmarXCore 
+        ArmarXCoreInterfaces
+        DebugObserverHelper
+        # ArmarXGui
+        ArmarXGuiComponentPlugins
+        # This package
+        RobotAPICore 
+        RobotAPIInterfaces 
+        RobotAPI::armem_server
+        RobotAPI::armem_robot
+        RobotAPI::armem_robot_state
+        aroncommon
+
+        # System / External
+        Eigen3::Eigen
+
+    HEADERS
+        forward_declarations.h
+
+        common/Visu.h
+        common/combine.h
+
+        localization/Segment.h
+
+        proprioception/Segment.h
+        proprioception/aron_conversions.h
+        proprioception/RobotStateWriter.h
+        proprioception/RobotUnitData.h
+        proprioception/RobotUnitReader.h
+
+        proprioception/converters/Armar6Converter.h
+        proprioception/converters/ConverterTools.h
+        proprioception/converters/ConverterRegistry.h
+        proprioception/converters/ConverterInterface.h
+
+        description/Segment.h
+
+    SOURCES
+        common/Visu.cpp
+        common/combine.cpp
+
+        localization/Segment.cpp
+
+        proprioception/Segment.cpp
+        proprioception/aron_conversions.cpp
+        proprioception/RobotStateWriter.cpp
+        proprioception/RobotUnitData.cpp
+        proprioception/RobotUnitReader.cpp
+
+        proprioception/converters/Armar6Converter.cpp
+        proprioception/converters/ConverterTools.cpp
+        proprioception/converters/ConverterRegistry.cpp
+        proprioception/converters/ConverterInterface.cpp
+
+        description/Segment.cpp
+)
+
+
+add_library(RobotAPI::armem_robot_state_server ALIAS armem_robot_state_server)
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Pose.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Pose.cpp
index d7292d0e05e46931f2d43ea937d9eda0b6def9fb..b377dde0f39916daa25e80d4b74a7bc665c316c0 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Pose.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Pose.cpp
@@ -86,7 +86,9 @@ namespace armarx::aron::codegenerator::cpp::generator
     CppBlockPtr Pose::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
         CppBlockPtr block_if_data = std::make_shared<CppBlock>();
-        block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))");
+        std::string other_instance_resolved_accessor = this->resolveMaybeAccessor(otherInstanceAccessor);
+
+        block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + other_instance_resolved_accessor + ")))");
         block_if_data->addLineAsBlock("return false;");
         return resolveMaybeEqualsBlock(block_if_data, accessor, otherInstanceAccessor);
     }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
index 2cb8658dba91ffb333f91d62ef318af7e5387955..13bb05bab2971bb2f0fae684c30b26e987b533f5 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
@@ -128,9 +128,9 @@ namespace armarx::aron::data
             case type::Descriptor::eDict:
             {
                     v.visitDictOnEnter(o, t);
-                    for (auto& [key, value, acceptedType] : v.getDictElements(o, t))
+                    for (auto& [key, pair] : v.getDictElements(o, t))
                     {
-                        visitRecursive(v, value, acceptedType);
+                        visitRecursive(v, pair.first, pair.second);
                     }
                     v.visitDictOnExit(o, t);
                     return;
@@ -138,9 +138,9 @@ namespace armarx::aron::data
             case type::Descriptor::eObject:
             {
                 v.visitObjectOnEnter(o, t);
-                for (auto& [key, value, acceptedType] : v.getObjectElements(o, t))
+                for (auto& [key, pair] : v.getObjectElements(o, t))
                 {
-                    visitRecursive(v, value, acceptedType);
+                    visitRecursive(v, pair.first, pair.second);
                 }
                 v.visitObjectOnExit(o, t);
                 return;
diff --git a/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt
index 37aa8186e10627afbae5ccb8fff0bb52cf818617..e53a050be032a57a5557dddbedd7ba7714ba2c69 100644
--- a/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt
@@ -22,7 +22,7 @@ armarx_add_test(
     TEST_FILE
         aronOperatorTest.cpp
     LIBS
-        Simox::SimoxUtility
+        SimoxUtility  # Simox::SimoxUtility
         ArmarXCore
         RobotAPI::aron
     INCLUDE_DIRECTORIES
@@ -38,7 +38,7 @@ armarx_add_test(
     TEST_FILE
         aronCodeGenerationTest.cpp
     LIBS
-        Simox::SimoxUtility
+        SimoxUtility  # Simox::SimoxUtility
         ArmarXCore
         RobotAPI::aron
     ARON_FILES
@@ -76,7 +76,7 @@ armarx_add_test(
     TEST_FILE
         aronNavigateTest.cpp
     LIBS
-        Simox::SimoxUtility
+        SimoxUtility  # Simox::SimoxUtility
         ArmarXCore
         RobotAPI::aron
     ARON_FILES
@@ -94,7 +94,7 @@ armarx_add_test(
     TEST_FILE
         aronExtendsTest.cpp
     LIBS
-        Simox::SimoxUtility
+        SimoxUtility  # Simox::SimoxUtility
         ArmarXCore
         RobotAPI::aron
     ARON_FILES
@@ -113,7 +113,7 @@ armarx_add_test(
     TEST_FILE
         aronRandomizedTest.cpp
     LIBS
-        Simox::SimoxUtility
+        SimoxUtility  # Simox::SimoxUtility
         ArmarXCore
         RobotAPI::aron
         ivt
diff --git a/source/RobotAPI/libraries/aron/core/test/aron/OptionalTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/OptionalTest.xml
index 332e9b13e489cb6426cb9a0a88aa238d8aaea9d3..2b0d2d39810d2d1c05d4c40bba55ee36fc29615a 100644
--- a/source/RobotAPI/libraries/aron/core/test/aron/OptionalTest.xml
+++ b/source/RobotAPI/libraries/aron/core/test/aron/OptionalTest.xml
@@ -61,7 +61,9 @@
                 </List>
             </ObjectChild>
 
-
+            <ObjectChild key="an_optional_pose">
+                <Pose />
+            </ObjectChild>
 
         </Object>
     </GenerateTypes>