diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
index 098fe6f1d3de321048b9a942b7ce0c7cca2814fe..6c86b6afa76fe043b4dea16affb609f7db049caf 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
@@ -30,6 +30,7 @@
 
 #include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
 
 #include <RobotAPI/libraries/armem_skills/aron_conversions.h>
@@ -70,7 +71,7 @@ namespace armarx
         workingMemory.name() = p.memoryName;
 
         {
-            armarx::armem::wm::CoreSegment& c = workingMemory.addCoreSegment(p.statechartCoreSegmentName, armarx::armem::arondto::Statechart::Transition::toAronType());
+            armarx::armem::server::wm::CoreSegment& c = workingMemory.addCoreSegment(p.statechartCoreSegmentName, armarx::armem::arondto::Statechart::Transition::toAronType());
             c.addProviderSegment("Transitions", armarx::armem::arondto::Statechart::Transition::toAronType());
         }
     }
diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index e63616934d2e5e5f40ed4a3d864bd87131cfd070..2998875d1623e13bcf44f16187a969e224152589 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -33,7 +33,6 @@ set(LIB_FILES
     core/json_conversions.cpp
 
     core/base/detail/MemoryItem.cpp
-    core/base/detail/MaxHistorySize.cpp
     core/base/detail/MemoryContainerBase.cpp
     core/base/detail/EntityContainerBase.cpp
     core/base/detail/AronTyped.cpp
@@ -46,10 +45,10 @@ set(LIB_FILES
     core/base/EntitySnapshotBase.cpp
     # core/base/MemoryBase.cpp
     # core/base/ProviderSegmentBase.cpp
+    core/base/ice_conversions.cpp
 
     core/wm/memory_definitions.cpp
     core/wm/ice_conversions.cpp
-    core/wm/ice_conversions.cpp
     core/wm/aron_conversions.cpp
     core/wm/visitor/Visitor.cpp
     core/wm/visitor/FunctionalVisitor.cpp
@@ -84,6 +83,10 @@ set(LIB_FILES
     server/MemoryRemoteGui.cpp
     server/RemoteGuiAronDataVisitor.cpp
 
+    server/wm/memory_definitions.cpp
+    server/wm/ice_conversions.cpp
+    server/wm/detail/MaxHistorySize.cpp
+
     server/segment/Segment.cpp
     server/segment/SpecializedSegment.cpp
 
@@ -93,23 +96,9 @@ set(LIB_FILES
     server/query_proc/base/CoreSegmentQueryProcessorBase.cpp
     server/query_proc/base/MemoryQueryProcessorBase.cpp
 
-    server/query_proc/workingmemory/BaseQueryProcessor.cpp
-    server/query_proc/workingmemory/EntityQueryProcessor.cpp
-    server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp
-    server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp
-    server/query_proc/workingmemory/MemoryQueryProcessor.cpp
-
-    server/query_proc/longtermmemory/BaseQueryProcessor.cpp
-    server/query_proc/longtermmemory/EntityQueryProcessor.cpp
-    server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp
-    server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp
-    server/query_proc/longtermmemory/MemoryQueryProcessor.cpp
-
-    server/query_proc/diskmemory/BaseQueryProcessor.cpp
-    server/query_proc/diskmemory/EntityQueryProcessor.cpp
-    server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp
-    server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp
-    server/query_proc/diskmemory/MemoryQueryProcessor.cpp
+    server/query_proc/diskmemory.cpp
+    server/query_proc/ltm.cpp
+    server/query_proc/wm.cpp
 
     mns/MemoryNameSystem.cpp
     mns/ComponentPlugin.cpp
@@ -119,6 +108,8 @@ set(LIB_FILES
 
 set(LIB_HEADERS
     core.h
+    core/forward_declarations.h
+
     core/Commit.h
     core/DataMode.h
     core/MemoryID.h
@@ -137,7 +128,6 @@ set(LIB_HEADERS
     core/error/mns.h
 
     core/base/detail/MemoryItem.h
-    core/base/detail/MaxHistorySize.h
     core/base/detail/MemoryContainerBase.h
     core/base/detail/EntityContainerBase.h
     core/base/detail/AronTyped.h
@@ -150,6 +140,7 @@ set(LIB_HEADERS
     core/base/EntitySnapshotBase.h
     core/base/MemoryBase.h
     core/base/ProviderSegmentBase.h
+    core/base/ice_conversions.h
 
     core/wm.h
     core/wm/memory_definitions.h
@@ -164,9 +155,6 @@ set(LIB_HEADERS
     core/ltm/mongodb/MemoryManager.h
     core/ltm/mongodb/ConnectionManager.h
 
-    core/ice_conversions_templates.h
-    core/ice_conversions.h
-
     client.h
     client/ComponentPlugin.h
     client/MemoryNameSystem.h
@@ -189,45 +177,38 @@ set(LIB_HEADERS
     client/util/SimpleWriterBase.h
 
     server.h
+    server/forward_declarations.h
+
     server/ComponentPlugin.h
     server/MemoryToIceAdapter.h
     server/MemoryRemoteGui.h
     server/RemoteGuiAronDataVisitor.h
 
+    server/wm/memory_definitions.h
+    server/wm/ice_conversions.h
+    server/wm/detail/MaxHistorySize.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/workingmemory/BaseQueryProcessor.h
-    server/query_proc/workingmemory/EntityQueryProcessor.h
-    server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h
-    server/query_proc/workingmemory/CoreSegmentQueryProcessor.h
-    server/query_proc/workingmemory/MemoryQueryProcessor.h
-
-    server/query_proc/longtermmemory/BaseQueryProcessor.h
-    server/query_proc/longtermmemory/EntityQueryProcessor.h
-    server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h
-    server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h
-    server/query_proc/longtermmemory/MemoryQueryProcessor.h
-
-    server/query_proc/diskmemory/BaseQueryProcessor.h
-    server/query_proc/diskmemory/EntityQueryProcessor.h
-    server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h
-    server/query_proc/diskmemory/CoreSegmentQueryProcessor.h
-    server/query_proc/diskmemory/MemoryQueryProcessor.h
+    server/query_proc/diskmemory.h
+    server/query_proc/ltm.h
+    server/query_proc/wm.h
 
     mns.h
     mns/MemoryNameSystem.h
     mns/ComponentPlugin.h
 
     util/util.h
-
 )
 
 armarx_add_library(
diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
index 03e3835fad49a951ded49f990358ff3b87c06ce4..0de79cccd0af6a85dd396b8891e91c572ee24fb2 100644
--- a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
@@ -6,7 +6,6 @@
 #include "ProviderSegmentBase.h"
 #include "detail/AronTyped.h"
 #include "detail/EntityContainerBase.h"
-#include "detail/MaxHistorySize.h"
 #include "detail/iteration_mixins.h"
 
 
@@ -19,7 +18,6 @@ namespace armarx::armem::base
     template <class _ProviderSegmentT, class _Derived>
     class CoreSegmentBase :
         public detail::EntityContainerBase<_ProviderSegmentT, typename _ProviderSegmentT::EntityT, _Derived>,
-        public detail::MaxHistorySize,
         public detail::AronTyped,
         public detail::ForEachEntityInstanceMixin<_Derived>,
         public detail::ForEachEntitySnapshotMixin<_Derived>,
@@ -97,6 +95,11 @@ namespace armarx::armem::base
             return this->_container.count(name) > 0;
         }
 
+        std::vector<std::string> getProviderSegmentNames() const
+        {
+            return simox::alg::get_keys(this->_container);
+        }
+
         ProviderSegmentT& getProviderSegment(const std::string& name)
         {
             return const_cast<ProviderSegmentT&>(const_cast<const CoreSegmentBase*>(this)->getProviderSegment(name));
@@ -276,27 +279,10 @@ namespace armarx::armem::base
 
             auto it = this->_container.emplace(providerSegment.name(), std::move(providerSegment)).first;
             it->second.id().setCoreSegmentID(this->id());
-            it->second.setMaxHistorySize(_maxHistorySize);
             return it->second;
         }
 
 
-        /**
-         * @brief Sets the maximum history size of entities in this segment.
-         * This affects all current entities as well as new ones.
-         * @see Entity::setMaxHistorySize()
-         */
-        void setMaxHistorySize(long maxSize)
-        {
-            MaxHistorySize::setMaxHistorySize(maxSize);
-            this->forEachChild([maxSize](auto & child)
-            {
-                child.setMaxHistorySize(maxSize);
-                return true;
-            });
-        }
-
-
         // MISC
 
         bool equalsDeep(const DerivedT& other) const
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp b/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp
index 36fe5f8a87877f0f75fffcb387368ca9aeac7486..d3038a357bdad823f04e8d154a569a7eebaf90d5 100644
--- a/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp
+++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp
@@ -1,9 +1,2 @@
 #include "EntityBase.h"
 
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-
-void armarx::armem::base::detail::checkLessEqual(size_t historySize, size_t maxHistorySize)
-{
-    ARMARX_CHECK_LESS_EQUAL(historySize, maxHistorySize);
-}
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.h b/source/RobotAPI/libraries/armem/core/base/EntityBase.h
index 1a02d65c7f5e79c26cb087fcf70c26387863f312..05cbf780d1e95611d629d320581122b59c5f358c 100644
--- a/source/RobotAPI/libraries/armem/core/base/EntityBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.h
@@ -9,16 +9,11 @@
 #include <RobotAPI/libraries/armem/core/Time.h>
 
 #include "EntitySnapshotBase.h"
-#include "detail/MaxHistorySize.h"
 #include "detail/MemoryContainerBase.h"
 #include "detail/iteration_mixins.h"
 #include "detail/negative_index_semantics.h"
 
 
-namespace armarx::armem::base::detail
-{
-    void checkLessEqual(size_t historySize, size_t maxHistorySize);
-}
 namespace armarx::armem::base
 {
 
@@ -44,7 +39,6 @@ namespace armarx::armem::base
     template <class _EntitySnapshotT, class _Derived>
     class EntityBase :
         public detail::MemoryContainerBase<std::map<Time, _EntitySnapshotT>, _Derived>,
-        public detail::MaxHistorySize,
         public detail::ForEachEntityInstanceMixin<_Derived>
     {
         using Base = detail::MemoryContainerBase<std::map<Time, _EntitySnapshotT>, _Derived>;
@@ -312,7 +306,7 @@ namespace armarx::armem::base
                 {
                     break;
                 }
-                if (not func(snapshot))
+                if (not call(func, snapshot))
                 {
                     break;
                 }
@@ -347,7 +341,10 @@ namespace armarx::armem::base
 
             for (auto it = begin; it != end && it != this->_container.end(); ++it)
             {
-                func(it->second);
+                if (not call(func, it->second))
+                {
+                    break;
+                }
             }
         }
 
@@ -380,7 +377,10 @@ namespace armarx::armem::base
                 size_t num = last_ - first_ + 1;  // +1 to make last inclusive
                 for (size_t i = 0; i < num; ++i, ++it)
                 {
-                    func(it->second);
+                    if (not call(func, it->second))
+                    {
+                        break;
+                    }
                 }
             }
         }
@@ -417,7 +417,7 @@ namespace armarx::armem::base
             {
                 // Insert into history.
                 snapshot = &addSnapshot(update.timeCreated);
-                ret.removedSnapshots = truncate();
+                // ret.removedSnapshots = this->truncate();
                 ret.entityUpdateType = UpdateType::InsertedNew;
             }
             else
@@ -475,17 +475,6 @@ namespace armarx::armem::base
         }
 
 
-        /**
-         * @brief Sets the maximum history size.
-         *
-         * The current history is truncated if necessary.
-         */
-        void setMaxHistorySize(long maxSize)
-        {
-            MaxHistorySize::setMaxHistorySize(maxSize);
-            truncate();
-        }
-
 
         // MISC
 
@@ -522,22 +511,6 @@ namespace armarx::armem::base
 
     protected:
 
-        /// If maximum size is set, ensure `history`'s is not higher.
-        std::vector<EntitySnapshotT> truncate()
-        {
-            std::vector<EntitySnapshotT> removedElements;
-            if (_maxHistorySize >= 0)
-            {
-                while (this->_container.size() > size_t(_maxHistorySize))
-                {
-                    removedElements.push_back(std::move(this->_container.begin()->second));
-                    this->_container.erase(this->_container.begin());
-                }
-                detail::checkLessEqual(this->_container.size(), _maxHistorySize);
-            }
-            return removedElements;
-        }
-
         /**
          * @brief Return the snapshot with the most recent timestamp.
          * @return The latest snapshot.
diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
index a02beda13e3859386a9eed7c3722c987386cd7e7..80b57801d0031c3b66a7e6b72573290ed8c05a5a 100644
--- a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
@@ -94,6 +94,11 @@ namespace armarx::armem::base
             return this->_container.count(name) > 0;
         }
 
+        std::vector<std::string> getCoreSegmentNames() const
+        {
+            return simox::alg::get_keys(this->_container);
+        }
+
         CoreSegmentT& getCoreSegment(const std::string& name)
         {
             return const_cast<CoreSegmentT&>(const_cast<const MemoryBase*>(this)->getCoreSegment(name));
@@ -210,26 +215,20 @@ namespace armarx::armem::base
          * @param coreSegmentType The core segment type (optional).
          * @return The added core segment.
          */
-        CoreSegmentT& addCoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType = nullptr)
+        CoreSegmentT& addCoreSegment(
+            const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType = nullptr)
         {
-            return addCoreSegment(CoreSegmentT(name, this->id(), coreSegmentType));
+            return _addCoreSegment(name, name, this->id(), coreSegmentType);
         }
         /// Copy and insert a core segment.
         CoreSegmentT& addCoreSegment(const CoreSegmentT& coreSegment)
         {
-            return addCoreSegment(CoreSegmentT(coreSegment));
+            return _addCoreSegment(coreSegment.name(), CoreSegmentT(coreSegment));
         }
         /// Move and insert a core segment.
         CoreSegmentT& addCoreSegment(CoreSegmentT&& coreSegment)
         {
-            if (this->_container.count(coreSegment.name()) > 0)
-            {
-                throw armem::error::ContainerEntryAlreadyExists(CoreSegmentT::getLevelName(), coreSegment.name(),
-                        this->getLevelName(), this->name());
-            }
-            auto it = this->_container.emplace(coreSegment.name(), std::move(coreSegment)).first;
-            it->second.id().setMemoryID(this->id());
-            return it->second;
+            return _addCoreSegment(coreSegment.name(), coreSegment);
         }
 
         /**
@@ -393,6 +392,32 @@ namespace armarx::armem::base
         }
 
 
+    private:
+
+        /**
+         * This function allows to emplace a CoreSegment directly in the
+         * container from its constructor arguments, instead of constructing
+         * it outside and moving it.
+         * This is necessary if CoreSegmentT is not movable.
+         */
+        template <class ...Args>
+        CoreSegmentT& _addCoreSegment(const std::string& name, Args... args)
+        {
+            auto [it, existed] = this->_container.try_emplace(name, args...);
+            if (existed)
+            {
+                throw armem::error::ContainerEntryAlreadyExists(
+                    CoreSegmentT::getLevelName(), name, DerivedT::getLevelName(), this->name());
+            }
+            else
+            {
+                it->second.id().setMemoryID(this->id());
+                it->second.id().coreSegmentName = name;
+                return it->second;
+            }
+        }
+
+
     public:
 
         bool _addMissingCoreSegmentDuringUpdate = false;
diff --git a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h
index 0c54ae2b202cf485bcb0cdf52ac53622475c917b..e5163241738a0e8dbba5edbd35f8e5a568060746 100644
--- a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h
@@ -6,7 +6,6 @@
 #include "EntityBase.h"
 #include "detail/AronTyped.h"
 #include "detail/EntityContainerBase.h"
-#include "detail/MaxHistorySize.h"
 #include "detail/iteration_mixins.h"
 
 
@@ -19,7 +18,6 @@ namespace armarx::armem::base
     template <class _EntityT, class _Derived>
     class ProviderSegmentBase :
         public detail::EntityContainerBase<_EntityT, _EntityT, _Derived>,
-        public detail::MaxHistorySize,
         public detail::AronTyped,
         public detail::ForEachEntityInstanceMixin<_Derived>,
         public detail::ForEachEntitySnapshotMixin<_Derived>
@@ -93,6 +91,11 @@ namespace armarx::armem::base
             return this->_container.count(name) > 0;
         }
 
+        std::vector<std::string> getEntityNames() const
+        {
+            return simox::alg::get_keys(this->_container);
+        }
+
         using Base::getEntity;
         const EntityT& getEntity(const MemoryID& id) const
         {
@@ -189,7 +192,6 @@ namespace armarx::armem::base
             {
                 // Add entity entry.
                 entity = &addEntity(update.entityID.entityName);
-                entity->setMaxHistorySize(_maxHistorySize);
                 updateType = UpdateType::InsertedNew;
             }
             else
@@ -238,22 +240,6 @@ namespace armarx::armem::base
         }
 
 
-        /**
-         * @brief Sets the maximum history size of container in this segment.
-         * This affects all current container as well as new ones.
-         * @see Entity::setMaxHistorySize()
-         */
-        void setMaxHistorySize(long maxSize)
-        {
-            MaxHistorySize::setMaxHistorySize(maxSize);
-            this->forEachChild([maxSize](auto & child)
-            {
-                child.setMaxHistorySize(maxSize);
-                return true;
-            });
-        }
-
-
         // MISC
 
         bool equalsDeep(const DerivedT& other) const
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h b/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h
deleted file mode 100644
index c46fde11fb83d4580863aaf70aaafab4ba7f60e6..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-
-
-namespace armarx::armem::base::detail
-{
-    // TODO: Replace by ConstrainedHistorySize (not only max entries, e.g. delete oldest / delete least accessed / ...)
-    class MaxHistorySize
-    {
-    public:
-
-        /**
-         * @brief Sets the maximum history size of entities in this segment.
-         * This affects all current entities as well as new ones.
-         * @see Entity::setMaxHistorySize()
-         */
-        void setMaxHistorySize(long maxSize);
-        long getMaxHistorySize() const;
-
-
-    protected:
-
-        /**
-         * @brief Maximum size of entity histories.
-         *
-         * If negative, the size of `history` is not limited.
-         *
-         * @see Entity::maxHstorySize
-         */
-        long _maxHistorySize = -1;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h
index a53e661a83610f1fcc0e8edabe12e9f8cd6c5c83..c923a857e1d016b06b313f7e860ab57ec438a9d4 100644
--- a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h
+++ b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.h
@@ -8,6 +8,25 @@ namespace armarx::armem::base::detail
 
     // Helper functions to implement the forEach*() method at the current level.
 
+    // Handle functions with different return type.
+    template <class FunctionT, class ChildT>
+    bool call(FunctionT&& func, ChildT&& child)
+    {
+        if constexpr(std::is_same_v<decltype(func(child)), bool>)
+        {
+            if (!func(child))
+            {
+                return false;
+            }
+            return true;
+        }
+        else
+        {
+            func(child);
+            return true;
+        }
+    }
+
 
     // Single-valued containers.
     template <class ContainerT, class FunctionT>
@@ -15,16 +34,9 @@ namespace armarx::armem::base::detail
     {
         for (auto& child : container)
         {
-            if constexpr(std::is_same_v<decltype(func(child)), bool>)
+            if (not call(func, child))
             {
-                if (!func(child))
-                {
-                    return false;
-                }
-            }
-            else
-            {
-                func(child);
+                return false;
             }
         }
         return true;
@@ -37,16 +49,9 @@ namespace armarx::armem::base::detail
     {
         for (auto& [_, child] : container)
         {
-            if constexpr(std::is_same_v<decltype(func(child)), bool>)
-            {
-                if (!func(child))
-                {
-                    return false;
-                }
-            }
-            else
+            if (not call(func, child))
             {
-                func(child);
+                return false;
             }
         }
         return true;
diff --git a/source/RobotAPI/libraries/armem/core/base/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/base/ice_conversions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..48c084154c41b26b174504d2565fe57d3a49d55a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/ice_conversions.cpp
@@ -0,0 +1,78 @@
+#include "ice_conversions.h"
+
+#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
+#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
+
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/ice_conversions_templates.h>
+
+
+namespace armarx::armem::base
+{
+
+    void detail::toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item)
+    {
+        toIce(ice.id, item.id());
+    }
+    void detail::fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item)
+    {
+        fromIce(ice.id, item.id());
+    }
+
+
+    void detail::toIce(aron::data::AronDictPtr& ice, const aron::datanavigator::DictNavigatorPtr& data)
+    {
+        ice = data ? data->toAronDictPtr() : nullptr;
+    }
+    void detail::fromIce(const aron::data::AronDictPtr& ice, aron::datanavigator::DictNavigatorPtr& data)
+    {
+        if (ice)
+        {
+            data = aron::datanavigator::DictNavigator::FromAronDictPtr(ice);
+        }
+        else
+        {
+            data = nullptr;
+        };
+    }
+
+    void detail::toIce(aron::type::AronTypePtr& ice, const aron::typenavigator::ObjectNavigatorPtr& bo)
+    {
+        ice = bo ? bo->toAronPtr() : nullptr;
+    }
+    void detail::fromIce(const aron::type::AronTypePtr& ice, aron::typenavigator::ObjectNavigatorPtr& bo)
+    {
+        bo = ice
+             ? aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice))
+             : nullptr;
+    }
+
+}
+namespace armarx::armem
+{
+    void base::toIce(data::EntityInstanceMetadata& ice, const EntityInstanceMetadata& metadata)
+    {
+        ice.confidence = metadata.confidence;
+        toIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
+        toIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
+        toIce(ice.timeSentMicroSeconds, metadata.timeSent);
+    }
+    void base::fromIce(const data::EntityInstanceMetadata& ice, EntityInstanceMetadata& metadata)
+    {
+        metadata.confidence = ice.confidence;
+        fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
+        fromIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
+        fromIce(ice.timeSentMicroSeconds, metadata.timeSent);
+    }
+
+
+    void base::toIce(data::EntityInstanceMetadataPtr& ice, const EntityInstanceMetadata& metadata)
+    {
+        armem::toIce<data::EntityInstanceMetadata>(ice, metadata);
+    }
+    void base::fromIce(const data::EntityInstanceMetadataPtr& ice, EntityInstanceMetadata& metadata)
+    {
+        armem::fromIce<data::EntityInstanceMetadata>(ice, metadata);
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/ice_conversions.h b/source/RobotAPI/libraries/armem/core/base/ice_conversions.h
new file mode 100644
index 0000000000000000000000000000000000000000..646754cc4cbfc3d61c0ce0b1e19c333ee2d7f92b
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/ice_conversions.h
@@ -0,0 +1,195 @@
+#pragma once
+
+#include "EntityInstanceBase.h"
+#include "EntitySnapshotBase.h"
+#include "EntityBase.h"
+#include "ProviderSegmentBase.h"
+#include "CoreSegmentBase.h"
+#include "MemoryBase.h"
+
+#include <RobotAPI/libraries/armem/core/ice_conversions_templates.h>
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+
+#include <RobotAPI/libraries/aron/core/navigator/type/forward_declarations.h>
+
+#include <RobotAPI/interface/armem/memory.h>
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+
+namespace armarx::armem::base::detail
+{
+    void toIceItem(data::detail::MemoryItem& ice, const MemoryItem& item);
+    void fromIceItem(const data::detail::MemoryItem& ice, MemoryItem& item);
+
+    void toIce(aron::data::AronDictPtr& ice, const aron::datanavigator::DictNavigatorPtr& bo);
+    void fromIce(const aron::data::AronDictPtr& ice, aron::datanavigator::DictNavigatorPtr& bo);
+
+    void toIce(aron::type::AronTypePtr& ice, const aron::typenavigator::ObjectNavigatorPtr& bo);
+    void fromIce(const aron::type::AronTypePtr& ice, aron::typenavigator::ObjectNavigatorPtr& bo);
+}
+namespace armarx::armem::base
+{
+    void toIce(data::EntityInstanceMetadata& ice, const EntityInstanceMetadata& metadata);
+    void fromIce(const data::EntityInstanceMetadata& ice, EntityInstanceMetadata& metadata);
+
+    void toIce(data::EntityInstanceMetadataPtr& ice, const EntityInstanceMetadata& metadata);
+    void fromIce(const data::EntityInstanceMetadataPtr& ice, EntityInstanceMetadata& metadata);
+
+
+    template <class ...Args>
+    void toIce(data::EntityInstance& ice, const EntityInstanceBase<Args...>& data)
+    {
+        detail::toIceItem(ice, data);
+
+        // detail::toIce(std::ref(ice.data).get(), data.data());
+        detail::toIce(ice.data, data.data());
+        toIce(ice.metadata, data.metadata());
+    }
+    template <class ...Args>
+    void fromIce(const data::EntityInstance& ice, EntityInstanceBase<Args...>& data)
+    {
+        detail::fromIceItem(ice, data);
+
+        detail::fromIce(ice.data, data.data());
+        fromIce(ice.metadata, data.metadata());
+    }
+
+    template <class ...Args>
+    void toIce(data::EntitySnapshot& ice, const EntitySnapshotBase<Args...>& snapshot)
+    {
+        detail::toIceItem(ice, snapshot);
+
+        ice.instances.clear();
+        snapshot.forEachInstance([&ice](const auto & instance)
+        {
+            armem::toIce(ice.instances.emplace_back(), instance);
+        });
+    }
+    template <class ...Args>
+    void fromIce(const data::EntitySnapshot& ice, EntitySnapshotBase<Args...>& snapshot)
+    {
+        detail::fromIceItem(ice, snapshot);
+
+        snapshot.clear();
+        for (const data::EntityInstancePtr& iceInstance : ice.instances)
+        {
+            snapshot.addInstance(armem::fromIce<typename EntitySnapshotBase<Args...>::EntityInstanceT>(iceInstance));
+        }
+    }
+
+    template <class ...Args>
+    void toIce(data::Entity& ice, const EntityBase<Args...>& entity)
+    {
+        detail::toIceItem(ice, entity);
+
+        ice.history.clear();
+        entity.forEachSnapshot([&ice](const auto & snapshot)
+        {
+            armem::toIce(ice.history[armem::toIce<long>(snapshot.time())], snapshot);
+        });
+    }
+    template <class ...Args>
+    void fromIce(const data::Entity& ice, EntityBase<Args...>& entity)
+    {
+        detail::fromIceItem(ice, entity);
+
+        entity.clear();
+        for (const auto& [key, snapshot] : ice.history)
+        {
+            entity.addSnapshot(armem::fromIce<typename EntityBase<Args...>::EntitySnapshotT>(snapshot));
+        }
+    }
+
+
+    template <class ...Args>
+    void toIce(data::ProviderSegment& ice, const ProviderSegmentBase<Args...>& providerSegment)
+    {
+        detail::toIceItem(ice, providerSegment);
+
+        detail::toIce(ice.aronType, providerSegment.aronType());
+        ARMARX_CHECK(!providerSegment.aronType() || ice.aronType);
+
+        // toIce(ice.entities, providerSegment.entities());
+        ice.entities.clear();
+        providerSegment.forEachEntity([&ice](const auto & entity)
+        {
+            armem::toIce(ice.entities[entity.name()], entity);
+        });
+    }
+    template <class ...Args>
+    void fromIce(const data::ProviderSegment& ice, ProviderSegmentBase<Args...>& providerSegment)
+    {
+        detail::fromIceItem(ice, providerSegment);
+
+        detail::fromIce(ice.aronType, providerSegment.aronType());
+        ARMARX_CHECK(!providerSegment.aronType() || ice.aronType);
+
+        // fromIce(ice.entities, providerSegment.entities());
+        providerSegment.clear();
+        for (const auto& [key, entity] : ice.entities)
+        {
+            providerSegment.addEntity(
+                armem::fromIce<typename ProviderSegmentBase<Args...>::EntityT>(entity));
+        }
+    }
+
+    template <class ...Args>
+    void toIce(data::CoreSegment& ice, const CoreSegmentBase<Args...>& coreSegment)
+    {
+        detail::toIceItem(ice, coreSegment);
+
+        detail::toIce(ice.aronType, coreSegment.aronType());
+        ARMARX_CHECK(!coreSegment.aronType() || ice.aronType);
+
+        // toIce(ice.providerSegments, coreSegment.providerSegments());
+        ice.providerSegments.clear();
+        coreSegment.forEachProviderSegment([&ice](const auto & providerSegment)
+        {
+            armem::toIce(ice.providerSegments[providerSegment.name()], providerSegment);
+            return true;
+        });
+    }
+    template <class ...Args>
+    void fromIce(const data::CoreSegment& ice, CoreSegmentBase<Args...>& coreSegment)
+    {
+        detail::fromIceItem(ice, coreSegment);
+
+        detail::fromIce(ice.aronType, coreSegment.aronType());
+        ARMARX_CHECK(!coreSegment.aronType() || ice.aronType);
+
+        // fromIce(ice.providerSegments, coreSegment.providerSegments());
+        coreSegment.clear();
+        for (const auto& [key, providerSegment] : ice.providerSegments)
+        {
+            coreSegment.addProviderSegment(
+                armem::fromIce<typename CoreSegmentBase<Args...>::ProviderSegmentT>(providerSegment));
+        }
+    }
+
+    template <class ...Args>
+    void toIce(data::Memory& ice, const MemoryBase<Args...>& memory)
+    {
+        base::detail::toIceItem(ice, memory);
+
+        ice.coreSegments.clear();
+        memory.forEachCoreSegment([&ice](const auto & coreSegment)
+        {
+            armem::toIce(ice.coreSegments[coreSegment.name()], coreSegment);
+            return true;
+        });
+    }
+    template <class ...Args>
+    void fromIce(const data::Memory& ice, MemoryBase<Args...>& memory)
+    {
+        base::detail::fromIceItem(ice, memory);
+
+        memory.clear();
+        for (const auto& [key, coreSegment] : ice.coreSegments)
+        {
+            // We can avoid using CoreSegment's copy constructor this way:
+            armem::fromIce(coreSegment, memory.addCoreSegment(coreSegment->id.coreSegmentName));
+        }
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/forward_declarations.h b/source/RobotAPI/libraries/armem/core/forward_declarations.h
new file mode 100644
index 0000000000000000000000000000000000000000..761a8513111d55de8b81ade1af62a60ee18f1f3c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/forward_declarations.h
@@ -0,0 +1,52 @@
+#pragma once
+
+
+namespace armarx::armem
+{
+    // class Time;  // Cannot be forward declared (it's a typedef)
+
+    class MemoryID;
+    class Commit;
+    class EntityUpdate;
+    class CommitResult;
+    class EntityUpdateResult;
+}
+
+namespace armarx::armem::base
+{
+    struct NoData;
+    struct EntityInstanceMetadata;
+
+    template <class _DataT, class _MetadataT>
+    class EntityInstanceBase;
+    template <class _EntityInstanceT, class _Derived>
+    class EntitySnapshotBase;
+    template <class _EntitySnapshotT, class _Derived>
+    class EntityBase;
+    template <class _EntityT, class _Derived>
+    class ProviderSegmentBase;
+    template <class _ProviderSegmentT, class _Derived>
+    class CoreSegmentBase;
+    template <class _CoreSegmentT, class _Derived>
+    class MemoryBase;
+}
+
+namespace armarx::armem::wm
+{
+    class EntityInstance;
+    class EntitySnapshot;
+    class Entity;
+    class ProviderSegment;
+    class CoreSegment;
+    class Memory;
+}
+
+namespace armarx::armem::server::wm
+{
+    using EntityInstance = armem::wm::EntityInstance;
+    using EntitySnapshot = armem::wm::EntitySnapshot;
+    class Entity;
+    class ProviderSegment;
+    class CoreSegment;
+    class Memory;
+}
diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/ice_conversions.cpp
index 88ed8fd29ca61af76cf035c3a0be77a10df444a5..cca45a3b2cf04f26ec76d158e9cf1e711bbfecb2 100644
--- a/source/RobotAPI/libraries/armem/core/ice_conversions.cpp
+++ b/source/RobotAPI/libraries/armem/core/ice_conversions.cpp
@@ -3,20 +3,18 @@
 #include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
 
 
-namespace armarx
+void IceUtil::toIce(long& ice, const IceUtil::Time& time)
 {
+    ice = time.toMicroSeconds();
+}
 
-    /*
-        void armem::fromIce(long ice, Time& time)
-        {
-            time = Time::microSeconds(ice);
-        }
+void IceUtil::fromIce(const long& ice, IceUtil::Time& time)
+{
+    time = Time::microSeconds(ice);
+}
 
-        void armem::toIce(long& ice, const Time& time)
-        {
-            ice = time.toMicroSeconds();
-        }
-    */
+namespace armarx
+{
 
     void armem::toIce(data::MemoryID& ice, const MemoryID& id)
     {
@@ -146,14 +144,5 @@ namespace armarx
         update.timeArrived = timeArrived;
     }
 
-
-    void armem::detail::toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item)
-    {
-        toIce(ice.id, item.id());
-    }
-
-    void armem::detail::fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item)
-    {
-        fromIce(ice.id, item.id());
-    }
 }
+
diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions.h b/source/RobotAPI/libraries/armem/core/ice_conversions.h
index 874684cac2a6a52b8742c36dcc2bdea8346e1586..e8f104fe04ebcb721b0ffbf4b70b18ada0af234c 100644
--- a/source/RobotAPI/libraries/armem/core/ice_conversions.h
+++ b/source/RobotAPI/libraries/armem/core/ice_conversions.h
@@ -6,29 +6,21 @@
 #include "ice_conversions_templates.h"
 
 #include "Commit.h"
-#include "base/detail/MemoryItem.h"
+#include "MemoryID.h"
+#include "Time.h"
 
 
 namespace IceUtil
 {
     // Define in original namespace to allow ADL.
-    inline void toIce(long& ice, const Time& time)
-    {
-        ice = time.toMicroSeconds();
-    }
-    inline void fromIce(const long& ice, Time& time)
-    {
-        time = Time::microSeconds(ice);
-    }
+    void toIce(long& ice, const Time& time);
+    void fromIce(const long& ice, Time& time);
 }
 
 
 namespace armarx::armem
 {
 
-    // void fromIce(long ice, Time& time);
-    // void toIce(long& ice, const Time& time);
-
     void fromIce(const data::MemoryID& ice, MemoryID& id);
     void toIce(data::MemoryID& ice, const MemoryID& id);
 
@@ -51,12 +43,5 @@ namespace armarx::armem
     void fromIce(const data::Commit& ice, Commit& commit, Time timeArrived);
     void fromIce(const data::EntityUpdate& ice, EntityUpdate& update, Time timeArrived);
 
-
-    namespace detail
-    {
-        void toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item);
-        void fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item);
-    }
-
 }
 
diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h b/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h
index e0c71faac37cd899d85d174c33196499a29df770..8060e22a0782e23c6bb989fe900fcce99c7ff7c6 100644
--- a/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h
+++ b/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h
@@ -1,9 +1,12 @@
 #pragma once
 
-#include <memory>
-
 #include "Commit.h"
 
+#include <Ice/Handle.h>
+
+#include <map>
+#include <memory>
+#include <vector>
 
 
 namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp
index c8c4be11ac2c047753f3197209fdaebc2b3ae919..6604c26e935cb4619fc7439d8e9a1f318a14ff63 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp
@@ -30,11 +30,6 @@ namespace armarx::armem::ltm
         int i = 0;
         for (auto doc : cursor)
         {
-            if (i > MAX_HISTORY_SIZE)
-            {
-                // TODO: Add logic for most queried data?
-                break;
-            }
             nlohmann::json json = nlohmann::json::parse(bsoncxx::to_json(doc));
 
             auto k = armem::Time::microSeconds(json.at("timestamp"));
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h
index e3feb413c11d5fd8d89176ccea2ea40ddafc7510..99bc3a736f0abe803ec101a81f4b1ac75b87d92e 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h
@@ -37,11 +37,6 @@ namespace armarx::armem::ltm
 
         using Base::EntityBase;
 
-        Entity()
-        {
-            // the history of snapshots is just a cache of frequently used elements
-            setMaxHistorySize(MAX_HISTORY_SIZE);
-        }
 
         // Conversion
         wm::Entity convert() const;
@@ -63,8 +58,6 @@ namespace armarx::armem::ltm
     public:
         MongoDBConnectionManager::MongoDBSettings dbsettings;
 
-    private:
-        const static constexpr int MAX_HISTORY_SIZE = 200;
     };
 
 }
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp
index 8d7addcd6262d20242cf5868207572e554769687..8cbe688125a7571a3e8f0a19031b25722bb79bbf 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp
@@ -21,7 +21,6 @@ namespace armarx::armem::ltm
         mongocxx::collection coll = db[id().getEntityID().str()];
 
         auto res = coll.find_one(document{} << "id" << id().getEntitySnapshotID().str() << finalize);
-
         if (!res)
         {
             throw error::ArMemError("Could not load an instance from the memory '" + id().getEntityID().str() + "'. Tried to access: " + id().getEntitySnapshotID().str());
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
index 50aee46722c2e7c7f153feed0853e4f8a1226724..ab4cb5d13ec0a30c0e8dc04125b61bd4b031df99 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
@@ -89,10 +89,11 @@ namespace armarx::armem::ltm
 
     wm::Memory Memory::convert() const
     {
+        wm::Memory m(id());
+
         std::lock_guard l(mongoDBMutex);
         if (!checkConnection())
         {
-            wm::Memory m(id());
             return m;
         }
 
@@ -100,7 +101,6 @@ namespace armarx::armem::ltm
 
         TIMING_START(LTM_Convert);
 
-        wm::Memory m(id());
         for (const auto& [_, s] : _container)
         {
             m.addCoreSegment(s.convert());
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
index 870bc0a7a7b668c7afb9f9766f4a4ec4c66faee7..41e82bce38b50f9e122e34056c2b5fd74cec4bac 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
@@ -8,6 +8,8 @@
 
 #include <ArmarXCore/core/application/properties/forward_declarations.h>
 
+#include <mutex>
+
 
 namespace armarx::armem::ltm
 {
diff --git a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp
index a1fc88f19643bf5befa8c741cf6846d3f1a8f76f..70a905a931fd331a6ecdfbc2c278924b0da9144a 100644
--- a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp
+++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp
@@ -1,186 +1,64 @@
 #include "ice_conversions.h"
 
-#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
+#include <RobotAPI/libraries/armem/core/base/ice_conversions.h>
 
 
 namespace armarx::armem
 {
-    void toIce(data::EntityInstanceMetadata& ice, const wm::EntityInstanceMetadata& metadata)
-    {
-        ice.confidence = metadata.confidence;
-        toIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
-        toIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
-        toIce(ice.timeSentMicroSeconds, metadata.timeSent);
-    }
-    void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata)
-    {
-        metadata.confidence = ice.confidence;
-        fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
-        fromIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
-        fromIce(ice.timeSentMicroSeconds, metadata.timeSent);
-    }
 
-    void toIce(data::EntityInstance& ice, const wm::EntityInstance& data)
+    void wm::toIce(data::EntityInstance& ice, const EntityInstance& data)
     {
-        detail::toIceItem(ice, data);
-
-        if (data.data())
-        {
-            ice.data = data.data()->toAronDictPtr();
-        }
-        toIce(ice.metadata, data.metadata());
+        base::toIce(ice, data);
     }
-    void fromIce(const data::EntityInstance& ice, wm::EntityInstance& data)
+    void wm::fromIce(const data::EntityInstance& ice, EntityInstance& data)
     {
-        detail::fromIceItem(ice, data);
-
-        if (ice.data)
-        {
-            data.data() = aron::datanavigator::DictNavigator::FromAronDictPtr(ice.data);
-        }
-        fromIce(ice.metadata, data.metadata());
+        base::fromIce(ice, data);
     }
 
 
-    void toIce(data::EntitySnapshot& ice, const wm::EntitySnapshot& snapshot)
+    void wm::toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot)
     {
-        detail::toIceItem(ice, snapshot);
-
-        ice.instances.clear();
-        snapshot.forEachInstance([&ice](const wm::EntityInstance & instance)
-        {
-            toIce(ice.instances.emplace_back(), instance);
-            return true;
-        });
+        base::toIce(ice, snapshot);
     }
-    void fromIce(const data::EntitySnapshot& ice, wm::EntitySnapshot& snapshot)
+    void wm::fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot)
     {
-        detail::fromIceItem(ice, snapshot);
-
-        snapshot.clear();
-        for (const data::EntityInstancePtr& instance : ice.instances)
-        {
-            snapshot.addInstance(fromIce<wm::EntityInstance>(instance));
-        }
+        base::fromIce(ice, snapshot);
     }
 
-    void toIce(data::Entity& ice, const wm::Entity& entity)
+    void wm::toIce(data::Entity& ice, const Entity& entity)
     {
-        detail::toIceItem(ice, entity);
-
-        ice.history.clear();
-        entity.forEachSnapshot([&ice](const wm::EntitySnapshot & snapshot)
-        {
-            toIce(ice.history[toIce<long>(snapshot.time())], snapshot);
-            return true;
-        });
+        base::toIce(ice, entity);
     }
-    void fromIce(const data::Entity& ice, wm::Entity& entity)
+    void wm::fromIce(const data::Entity& ice, Entity& entity)
     {
-        detail::fromIceItem(ice, entity);
-
-        entity.clear();
-        for (const auto& [key, snapshot] : ice.history)
-        {
-            entity.addSnapshot(fromIce<wm::EntitySnapshot>(snapshot));
-        }
+        base::fromIce(ice, entity);
     }
 
-    void toIce(data::ProviderSegment& ice, const wm::ProviderSegment& providerSegment)
+    void wm::toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment)
     {
-        detail::toIceItem(ice, providerSegment);
-
-        if (providerSegment.hasAronType())
-        {
-            ice.aronType = providerSegment.aronType()->toAronPtr();
-        }
-        ARMARX_CHECK(!providerSegment.aronType() || ice.aronType);
-
-        // toIce(ice.entities, providerSegment.entities());
-        ice.entities.clear();
-        providerSegment.forEachEntity([&ice](const wm::Entity & entity)
-        {
-            toIce(ice.entities[entity.name()], entity);
-            return true;
-        });
+        base::toIce(ice, providerSegment);
     }
-    void fromIce(const data::ProviderSegment& ice, wm::ProviderSegment& providerSegment)
+    void wm::fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment)
     {
-        detail::fromIceItem(ice, providerSegment);
-
-        if (ice.aronType)
-        {
-            providerSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice.aronType));
-        }
-        ARMARX_CHECK(!providerSegment.aronType() || ice.aronType);
-
-        // fromIce(ice.entities, providerSegment.entities());
-        providerSegment.clear();
-        for (const auto& [key, entity] : ice.entities)
-        {
-            providerSegment.addEntity(fromIce<wm::Entity>(entity));
-        }
+        base::fromIce(ice, providerSegment);
     }
 
-    void toIce(data::CoreSegment& ice, const wm::CoreSegment& coreSegment)
+    void wm::toIce(data::CoreSegment& ice, const CoreSegment& coreSegment)
     {
-        detail::toIceItem(ice, coreSegment);
-
-        if (coreSegment.hasAronType())
-        {
-            ice.aronType = coreSegment.aronType()->toAronPtr();
-        }
-        ARMARX_CHECK(!coreSegment.aronType() || ice.aronType);
-
-        // toIce(ice.providerSegments, coreSegment.providerSegments());
-        ice.providerSegments.clear();
-        coreSegment.forEachProviderSegment([&ice](const wm::ProviderSegment & providerSegment)
-        {
-            toIce(ice.providerSegments[providerSegment.name()], providerSegment);
-            return true;
-        });
+        base::toIce(ice, coreSegment);
     }
-    void fromIce(const data::CoreSegment& ice, wm::CoreSegment& coreSegment)
+    void wm::fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment)
     {
-        detail::fromIceItem(ice, coreSegment);
-
-        if (ice.aronType)
-        {
-            coreSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice.aronType));
-        }
-        ARMARX_CHECK(!coreSegment.aronType() || ice.aronType);
-
-        // fromIce(ice.providerSegments, coreSegment.providerSegments());
-        coreSegment.clear();
-        for (const auto& [key, providerSegment] : ice.providerSegments)
-        {
-            coreSegment.addProviderSegment(fromIce<wm::ProviderSegment>(providerSegment));
-        }
+        base::fromIce(ice, coreSegment);
     }
 
-    void toIce(data::Memory& ice, const wm::Memory& memory)
+    void wm::toIce(data::Memory& ice, const Memory& memory)
     {
-        detail::toIceItem(ice, memory);
-
-        // toIce(ice.coreSegments, memory.coreSegments());
-        ice.coreSegments.clear();
-        memory.forEachCoreSegment([&ice](const wm::CoreSegment & coreSegment)
-        {
-            toIce(ice.coreSegments[coreSegment.name()], coreSegment);
-            return true;
-        });
+        base::toIce(ice, memory);
     }
-    void fromIce(const data::Memory& ice, wm::Memory& memory)
+    void wm::fromIce(const data::Memory& ice, Memory& memory)
     {
-        detail::fromIceItem(ice, memory);
-
-        // fromIce(ice.coreSegments, memory.coreSegments());
-        memory.clear();
-        for (const auto& [key, coreSegment] : ice.coreSegments)
-        {
-            memory.addCoreSegment(fromIce<wm::CoreSegment>(coreSegment));
-        }
+        base::fromIce(ice, memory);
     }
 
 }
diff --git a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h
index d2f7ef01f46361734f3092ef6fba1d1cb8df395c..4a58f16aaa6eef4c6f6685a86ed66298c1407454 100644
--- a/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h
+++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h
@@ -6,31 +6,29 @@
 #include "memory_definitions.h"
 
 
-namespace armarx::armem
+namespace armarx::armem::wm
 {
-    void toIce(data::EntityInstanceMetadata& ice, const wm::EntityInstanceMetadata& metadata);
-    void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata);
 
-    void toIce(data::EntityInstance& ice, const wm::EntityInstance& data);
-    void fromIce(const data::EntityInstance& ice, wm::EntityInstance& data);
+    void toIce(data::EntityInstance& ice, const EntityInstance& data);
+    void fromIce(const data::EntityInstance& ice, EntityInstance& data);
 
 
-    void toIce(data::EntitySnapshot& ice, const wm::EntitySnapshot& snapshot);
-    void fromIce(const data::EntitySnapshot& ice, wm::EntitySnapshot& snapshot);
+    void toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot);
+    void fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot);
 
-    void toIce(data::Entity& ice, const wm::Entity& entity);
-    void fromIce(const data::Entity& ice, wm::Entity& entity);
+    void toIce(data::Entity& ice, const Entity& entity);
+    void fromIce(const data::Entity& ice, Entity& entity);
 
 
-    void toIce(data::ProviderSegment& ice, const wm::ProviderSegment& providerSegment);
-    void fromIce(const data::ProviderSegment& ice, wm::ProviderSegment& providerSegment);
+    void toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment);
+    void fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment);
 
-    void toIce(data::CoreSegment& ice, const wm::CoreSegment& coreSegment);
-    void fromIce(const data::CoreSegment& ice, wm::CoreSegment& coreSegment);
+    void toIce(data::CoreSegment& ice, const CoreSegment& coreSegment);
+    void fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment);
 
-    void toIce(data::Memory& ice, const wm::Memory& memory);
-    void fromIce(const data::Memory& ice, wm::Memory& memory);
+    void toIce(data::Memory& ice, const Memory& memory);
+    void fromIce(const data::Memory& ice, Memory& memory);
 }
 
 // Must be included after the prototypes. Otherwise the compiler cannot find the correct methods in ice_coversion_templates.h
-#include "../ice_conversions.h"
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
diff --git a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp
index c200e6f68176363a9fb7b1344b2cc8dcf1025fc2..c9516fc3b74ce05797d7d8c39b12f83b0bdf740d 100644
--- a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp
+++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp
@@ -42,42 +42,6 @@ namespace armarx::armem::wm
     }
 
 
-    CoreSegment::CoreSegment(const CoreSegment& other) :
-        CoreSegment::Base(other),
-        _mutex()
-    {
-        // Do not copy _mutex.
-    }
-
-
-    CoreSegment::CoreSegment(CoreSegment&& other) :
-        CoreSegment::Base(std::move(other))
-    {
-        // Do not move _mutex.
-    }
-
-
-    CoreSegment& CoreSegment::operator=(const CoreSegment& other)
-    {
-        Base::operator=(other);
-        // Don't copy _mutex.
-        return *this;
-    }
-
-
-    CoreSegment& CoreSegment::operator=(CoreSegment&& other)
-    {
-        Base::operator=(std::move(other));
-        // Don't move _mutex.
-        return *this;
-    }
-
-
-    std::mutex& CoreSegment::mutex() const
-    {
-        return _mutex;
-    }
-
 
     std::optional<wm::EntitySnapshot> CoreSegment::getLatestEntitySnapshot(const MemoryID& entityID) const
     {
@@ -125,90 +89,4 @@ namespace armarx::armem::wm
     }
 
 
-    std::optional<wm::EntitySnapshot>
-    CoreSegment::getLatestEntitySnapshotLocking(const MemoryID& entityID) const
-    {
-        std::scoped_lock lock(_mutex);
-        return getLatestEntitySnapshot(entityID);
-    }
-
-    std::optional<wm::EntityInstance>
-    CoreSegment::getLatestEntityInstanceLocking(const MemoryID& entityID, int instanceIndex) const
-    {
-        std::scoped_lock lock(_mutex);
-        return getLatestEntityInstance(entityID, instanceIndex);
-    }
-
-    armarx::aron::datanavigator::DictNavigatorPtr
-    CoreSegment::getLatestEntityInstanceDataLocking(const MemoryID& entityID, int instanceIndex) const
-    {
-        std::scoped_lock lock(_mutex);
-        return getLatestEntityInstanceData(entityID, instanceIndex);
-    }
-
-
-    // TODO: add core segment if param is set
-    std::vector<Memory::Base::UpdateResult>
-    Memory::updateLocking(const Commit& commit)
-    {
-        // Group updates by core segment, then update each core segment in a batch to only lock it once.
-        std::map<std::string, std::vector<const EntityUpdate*>> updatesPerCoreSegment;
-        for (const EntityUpdate& update : commit.updates)
-        {
-            updatesPerCoreSegment[update.entityID.coreSegmentName].push_back(&update);
-        }
-
-        std::vector<Memory::Base::UpdateResult> result;
-        // To throw an exception after the commit if a core segment is missing and the memory should not create new ones
-        std::vector<std::string> missingCoreSegmentNames;
-        for (const auto& [coreSegmentName, updates] : updatesPerCoreSegment)
-        {
-            auto it = this->_container.find(coreSegmentName);
-            if (it != this->_container.end())
-            {
-                CoreSegment& coreSegment = it->second;
-
-                // Lock the core segment for the whole batch.
-                std::scoped_lock lock(coreSegment.mutex());
-
-                for (const EntityUpdate* update : updates)
-                {
-                    auto r = coreSegment.update(*update);
-                    Base::UpdateResult ret { r };
-                    ret.memoryUpdateType = UpdateType::UpdatedExisting;
-                    result.push_back(ret);
-                }
-            }
-            else
-            {
-                // Perform the other updates first, then throw afterwards.
-                missingCoreSegmentNames.push_back(coreSegmentName);
-            }
-        }
-        // Throw an exception if something went wrong.
-        if (not missingCoreSegmentNames.empty())
-        {
-            // Just throw an exception for the first entry. We can extend this exception in the future.
-            throw armem::error::MissingEntry::create<CoreSegment>(missingCoreSegmentNames.front(), *this);
-        }
-        return result;
-    }
-
-
-    // TODO: Add core segment if param is set
-    Memory::Base::UpdateResult
-    Memory::updateLocking(const EntityUpdate& update)
-    {
-        this->_checkContainerName(update.entityID.memoryName, this->name());
-
-        CoreSegment& segment = getCoreSegment(update.entityID.coreSegmentName);
-        Base::UpdateResult result;
-        {
-            std::scoped_lock lock(segment.mutex());
-            result = segment.update(update);
-        }
-        result.memoryUpdateType = UpdateType::UpdatedExisting;
-        return result;
-    }
-
 }
diff --git a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h
index 85b320e319259da6f009680e75a44a5cfd5945e0..679153b47809682fec38adb5baea609dd99c5c28 100644
--- a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h
+++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h
@@ -7,7 +7,6 @@
 #include <RobotAPI/libraries/armem/core/base/CoreSegmentBase.h>
 #include <RobotAPI/libraries/armem/core/base/MemoryBase.h>
 
-#include <mutex>
 #include <optional>
 
 
@@ -19,9 +18,7 @@ namespace armarx::armem::wm
     using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr;
 
 
-    /**
-     * @brief Data of a single entity instance.
-     */
+    /// @see base::EntityInstanceBase
     class EntityInstance :
         public base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>
     {
@@ -45,9 +42,7 @@ namespace armarx::armem::wm
 
 
 
-    /**
-     * @brief Data of an entity at one point in time.
-     */
+    /// @see base::EntitySnapshotBase
     class EntitySnapshot :
         public base::EntitySnapshotBase<EntityInstance, EntitySnapshot>
     {
@@ -58,26 +53,7 @@ namespace armarx::armem::wm
     };
 
 
-
-    /**
-     * @brief An entity over a period of time.
-     *
-     * An entity should be a physical thing or abstract concept existing
-     * (and potentially evolving) over some time.
-     *
-     * Examples are:
-     * - objects (the green box)
-     * - agents (robot, human)
-     * - locations (frige, sink)
-     * - grasp affordances (general, or for a specific object)
-     * - images
-     * - point clouds
-     * - other sensory values
-     *
-     * At each point in time (`EntitySnapshot`), the entity can have a
-     * (potentially variable) number of instances (`EntityInstance`),
-     * each containing a single `AronData` object of a specific `AronType`.
-     */
+    /// @see base::EntityBase
     class Entity :
         public base::EntityBase<EntitySnapshot, Entity>
     {
@@ -89,9 +65,7 @@ namespace armarx::armem::wm
 
 
 
-    /**
-     * @brief Data of a provider segment containing multiple entities.
-     */
+    /// @see base::ProviderSegmentBase
     class ProviderSegment :
         public base::ProviderSegmentBase<Entity, ProviderSegment>
     {
@@ -103,9 +77,7 @@ namespace armarx::armem::wm
 
 
 
-    /**
-     * @brief Data of a core segment containing multiple provider segments.
-     */
+    /// @see base::CoreSegmentBase
     class CoreSegment :
         public base::CoreSegmentBase<ProviderSegment, CoreSegment>
     {
@@ -115,14 +87,6 @@ namespace armarx::armem::wm
 
         using Base::CoreSegmentBase;
 
-        CoreSegment(const CoreSegment& other);
-        CoreSegment(CoreSegment&& other);
-        CoreSegment& operator=(const CoreSegment& other);
-        CoreSegment& operator=(CoreSegment&& other);
-
-
-        std::mutex& mutex() const;
-
 
         // Non-locking interface
 
@@ -151,51 +115,11 @@ namespace armarx::armem::wm
             }
         }
 
-
-        // Locking interface
-
-        std::optional<wm::EntitySnapshot> getLatestEntitySnapshotLocking(
-            const MemoryID& entityID) const;
-        std::optional<wm::EntityInstance> getLatestEntityInstanceLocking(
-            const MemoryID& entityID, int instanceIndex = 0) const;
-        armarx::aron::datanavigator::DictNavigatorPtr getLatestEntityInstanceDataLocking(
-            const MemoryID& entityID, int instanceIndex = 0) const;
-
-
-        template <class AronDtoT>
-        std::optional<AronDtoT> getLatestEntityInstanceDataLockingAs(
-            const MemoryID& entityID, int instanceIndex = 0) const
-        {
-            // Keep lock to a minimum.
-            wm::EntityInstanceDataPtr data = nullptr;
-            {
-                std::scoped_lock lock(_mutex);
-                data = getLatestEntityInstanceData(entityID, instanceIndex);
-            }
-            if (data)
-            {
-                AronDtoT aron;
-                aron.fromAron(data);
-                return aron;
-            }
-            else
-            {
-                return std::nullopt;
-            }
-        }
-
-
-    protected:
-
-        mutable std::mutex _mutex;
-
     };
 
 
 
-    /**
-     * @brief Data of a memory consisting of multiple core segments.
-     */
+    /// @see base::MemoryBase
     class Memory :
         public base::MemoryBase<CoreSegment, Memory>
     {
@@ -205,20 +129,6 @@ namespace armarx::armem::wm
 
         using Base::MemoryBase;
 
-
-        /**
-         * @brief Perform the commit, locking the core segments.
-         *
-         * Groups the commits by core segment, and updates each core segment
-         * in a batch, locking the core segment.
-         */
-        std::vector<Base::UpdateResult> updateLocking(const Commit& commit);
-
-        /**
-         * @brief Update the memory, locking the updated core segment.
-         */
-        Base::UpdateResult updateLocking(const EntityUpdate& update);
-
     };
 
 }
diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
index 8c814a160b49b0367cece67d407b986ac4d372e5..ae847a803dc64e68b53c432b222cb6ddbe2fcd86 100644
--- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
@@ -1,13 +1,11 @@
 #include "ComponentPlugin.h"
 
-#include <ArmarXCore/core/Component.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include "MemoryToIceAdapter.h"
 
 #include <RobotAPI/libraries/armem/core/error.h>
 
-#include "MemoryToIceAdapter.h"
-
-//#include <RobotAPI/libraries/armem/core/io/diskWriter/NlohmannJSON/NlohmannJSONDiskWriter.h>
+#include <ArmarXCore/core/Component.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
 
 namespace armarx::armem::server::plugins
diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
index 50951ab829b11971420a47d680b07e5ce7e4e115..0b2b872c1ff4686eecefd8ae8508bcfc45600d5f 100644
--- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
+++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
@@ -98,7 +98,7 @@ namespace armarx::armem::server
     public:
 
         /// The actual memory.
-        wm::Memory workingMemory;
+        server::wm::Memory workingMemory;
         // [[deprecated ("The global working memory mutex is deprecated. Use the core segment mutexes instead.")]]
         // std::mutex workingMemoryMutex;
 
diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
index 2207233b2abb5f1a73595bc32f5d60d86fd06a6d..6664288a0fa5f86da4df906819cba3be385cbcb9 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
@@ -1,19 +1,22 @@
 #include "MemoryRemoteGui.h"
 
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include "RemoteGuiAronDataVisitor.h"
 
 #include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
 #include <RobotAPI/libraries/aron/core/navigator/visitors/DataVisitor.h>
 
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
 #include <SimoxUtility/meta/type_name.h>
 
-#include "RemoteGuiAronDataVisitor.h"
+#include <mutex>
 
 
 namespace armarx::armem::server
 {
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::Memory& memory) const
+    template <class ...Args>
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::MemoryBase<Args...>& memory) const
     {
         GroupBox group;
         group.setLabel(makeGroupLabel("Memory", memory.name(), memory.size()));
@@ -22,19 +25,16 @@ namespace armarx::armem::server
         {
             group.addChild(Label(makeNoItemsMessage("core segments")));
         }
-        memory.forEachCoreSegment([this, &group](const wm::CoreSegment & coreSegment)
+        memory.forEachCoreSegment([this, &group](const auto & coreSegment)
         {
-            group.addChild(makeGroupBox(coreSegment));
-            return true;
+            group.addChild(this->makeGroupBox(coreSegment));
         });
         return group;
     }
 
-
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::CoreSegment& coreSegment) const
+    template <class ...Args>
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::CoreSegmentBase<Args...>& coreSegment) const
     {
-        std::scoped_lock lock(coreSegment.mutex());
-
         GroupBox group;
         group.setLabel(makeGroupLabel("Core Segment", coreSegment.name(), coreSegment.size()));
 
@@ -42,16 +42,15 @@ namespace armarx::armem::server
         {
             group.addChild(Label(makeNoItemsMessage("provider segments")));
         }
-        coreSegment.forEachProviderSegment([this, &group](const wm::ProviderSegment & providerSegment)
+        coreSegment.forEachProviderSegment([this, &group](const auto & providerSegment)
         {
-            group.addChild(makeGroupBox(providerSegment));
-            return true;
+            group.addChild(this->makeGroupBox(providerSegment));
         });
         return group;
     }
 
-
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::ProviderSegment& providerSegment) const
+    template <class ...Args>
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::ProviderSegmentBase<Args...>& providerSegment) const
     {
         GroupBox group;
         group.setLabel(makeGroupLabel("Provider Segment", providerSegment.name(), providerSegment.size()));
@@ -60,16 +59,15 @@ namespace armarx::armem::server
         {
             group.addChild(Label(makeNoItemsMessage("entities")));
         }
-        providerSegment.forEachEntity([this, &group](const wm::Entity & entity)
+        providerSegment.forEachEntity([this, &group](const auto & entity)
         {
-            group.addChild(makeGroupBox(entity));
-            return true;
+            group.addChild(this->makeGroupBox(entity));
         });
         return group;
     }
 
-
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::Entity& entity) const
+    template <class ...Args>
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::_makeGroupBox(const armem::base::EntityBase<Args...>& entity) const
     {
         GroupBox group;
         group.setLabel(makeGroupLabel("Entity", entity.name(), entity.size()));
@@ -79,10 +77,9 @@ namespace armarx::armem::server
             group.addChild(Label(makeNoItemsMessage("snapshots")));
         }
 
-        auto addChild = [this, &group](const wm::EntitySnapshot & snapshot)
+        auto addChild = [this, &group](const armem::wm::EntitySnapshot & snapshot)
         {
             group.addChild(makeGroupBox(snapshot));
-            return true;
         };
 
         if (int(entity.size()) <= maxHistorySize)
@@ -101,7 +98,55 @@ namespace armarx::armem::server
     }
 
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::EntitySnapshot& snapshot) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::Memory& memory) const
+    {
+        return this->_makeGroupBox(memory);
+    }
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::Memory& memory) const
+    {
+        return this->_makeGroupBox(memory);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::CoreSegment& coreSegment) const
+    {
+        std::scoped_lock lock(coreSegment.mutex());
+        return this->_makeGroupBox(coreSegment);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::CoreSegment& coreSegment) const
+    {
+        return this->_makeGroupBox(coreSegment);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::ProviderSegment& providerSegment) const
+    {
+        return this->_makeGroupBox(providerSegment);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::ProviderSegment& providerSegment) const
+    {
+        return this->_makeGroupBox(providerSegment);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::Entity& entity) const
+    {
+        return this->_makeGroupBox(entity);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::server::wm::Entity& entity) const
+    {
+        return this->_makeGroupBox(entity);
+    }
+
+
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::EntitySnapshot& snapshot) const
     {
         GroupBox group;
         group.setLabel(makeGroupLabel("t", armem::toDateTimeMilliSeconds(snapshot.time()),
@@ -111,7 +156,7 @@ namespace armarx::armem::server
         {
             group.addChild(Label(makeNoItemsMessage("instances")));
         }
-        snapshot.forEachInstance([this, &group](const wm::EntityInstance & instance)
+        snapshot.forEachInstance([this, &group](const armem::wm::EntityInstance & instance)
         {
             group.addChild(makeGroupBox(instance));
             return true;
@@ -122,7 +167,7 @@ namespace armarx::armem::server
     }
 
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::EntityInstance& instance) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const armem::wm::EntityInstance& instance) const
     {
         GroupBox group;
 
diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h
index 0c363e0758ca5caf75fa04d45ca35c879bbabe55..c6aef5c51546ac203c50d38f80696b89f3b6f3b9 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h
+++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h
@@ -2,7 +2,7 @@
 
 #include <ArmarXGui/libraries/RemoteGui/Client/Widgets.h>
 
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 
 
 namespace armarx::armem::server
@@ -17,12 +17,18 @@ namespace armarx::armem::server
         using GroupBox = armarx::RemoteGui::Client::GroupBox;
         using Label = armarx::RemoteGui::Client::Label;
 
-        GroupBox makeGroupBox(const wm::Memory& memory) const;
-        GroupBox makeGroupBox(const wm::CoreSegment& coreSegment) const;
-        GroupBox makeGroupBox(const wm::ProviderSegment& providerSegment) const;
-        GroupBox makeGroupBox(const wm::Entity& entity) const;
-        GroupBox makeGroupBox(const wm::EntitySnapshot& entitySnapshot) const;
-        GroupBox makeGroupBox(const wm::EntityInstance& instance) const;
+
+        GroupBox makeGroupBox(const armem::wm::Memory& memory) const;
+        GroupBox makeGroupBox(const armem::wm::CoreSegment& coreSegment) const;
+        GroupBox makeGroupBox(const armem::wm::ProviderSegment& providerSegment) const;
+        GroupBox makeGroupBox(const armem::wm::Entity& entity) const;
+        GroupBox makeGroupBox(const armem::wm::EntitySnapshot& entitySnapshot) const;
+        GroupBox makeGroupBox(const armem::wm::EntityInstance& instance) const;
+
+        GroupBox makeGroupBox(const armem::server::wm::Memory& memory) const;
+        GroupBox makeGroupBox(const armem::server::wm::CoreSegment& coreSegment) const;
+        GroupBox makeGroupBox(const armem::server::wm::ProviderSegment& providerSegment) const;
+        GroupBox makeGroupBox(const armem::server::wm::Entity& entity) const;
 
 
         std::string makeGroupLabel(const std::string& term, const std::string& name, size_t size,
@@ -33,6 +39,17 @@ namespace armarx::armem::server
 
         int maxHistorySize = 10;
 
+    private:
+
+        template <class ...Args>
+        MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::MemoryBase<Args...>& memory) const;
+        template <class ...Args>
+        MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::CoreSegmentBase<Args...>& coreSegment) const;
+        template <class ...Args>
+        MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::ProviderSegmentBase<Args...>& providerSegment) const;
+        template <class ...Args>
+        MemoryRemoteGui::GroupBox _makeGroupBox(const armem::base::EntityBase<Args...>& entity) const;
+
     };
 
 
diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
index 9fd9d5ccf68640468ea18235ce2a7afe316d7d3d..52fb496592390a1f7df893d0709c73937da55ae5 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
@@ -1,11 +1,13 @@
 #include "MemoryToIceAdapter.h"
 
+#include "query_proc/wm.h"
+#include "query_proc/ltm.h"
 
-#include "query_proc/workingmemory/MemoryQueryProcessor.h"
-#include "query_proc/longtermmemory/MemoryQueryProcessor.h"
+#include <RobotAPI/libraries/armem/server/wm/ice_conversions.h>
 
 #include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
+
 #include <RobotAPI/libraries/aron/core/Exception.h>
 
 #include <ArmarXCore/core/logging/Logging.h>
@@ -36,7 +38,7 @@ namespace armarx::armem::server
 
         data::AddSegmentResult output;
 
-        armem::wm::CoreSegment* coreSegment = nullptr;
+        server::wm::CoreSegment* coreSegment = nullptr;
         try
         {
             coreSegment = &workingMemory->getCoreSegment(input.coreSegmentName);
@@ -68,7 +70,7 @@ namespace armarx::armem::server
                 // This is ok.
                 if (input.clearWhenExists)
                 {
-                    wm::ProviderSegment& provider = coreSegment->getProviderSegment(input.providerSegmentName);
+                    server::wm::ProviderSegment& provider = coreSegment->getProviderSegment(input.providerSegmentName);
                     provider.clear();
                 }
             }
@@ -227,11 +229,11 @@ namespace armarx::armem::server
         ARMARX_CHECK_NOT_NULL(workingMemory);
 
         // Core segment processors will aquire the core segment locks.
-        armem::wm::query_proc::MemoryQueryProcessor wmProcessor(
+        query_proc::wm_server::MemoryQueryProcessor wmServerProcessor(
             input.withData ? armem::DataMode::WithData : armem::DataMode::NoData);
-        wm::Memory wmResult = wmProcessor.process(input, *workingMemory);
+        armem::wm::Memory wmResult = wmServerProcessor.process(input.memoryQueries, *workingMemory);
 
-        armem::ltm::query_proc::MemoryQueryProcessor ltmProcessor;
+        query_proc::ltm::MemoryQueryProcessor ltmProcessor;
         ltm::Memory ltmResult = ltmProcessor.process(input, *longtermMemory);
 
         armem::query::data::Result result;
@@ -244,7 +246,7 @@ namespace armarx::armem::server
             // This may also affect the data returned by the current query.
             // However, this is expected behavior, since we copy the data in the processor (copyEmpty) we can safely return the copy and
             // remove the original memory reference from WM here.
-            wm::Memory ltmConverted = ltmResult.convert();
+            armem::wm::Memory ltmConverted = ltmResult.convert();
             if (ltmConverted.empty())
             {
                 ARMARX_ERROR << "A converted memory contains no data although the original memory contained data. This indicates that something is wrong.";
@@ -260,7 +262,9 @@ namespace armarx::armem::server
             auto queryInput = armem::client::QueryInput::fromIce(input);
             queryInput.replaceQueryTarget(query::data::QueryTarget::LTM, query::data::QueryTarget::WM);
 
-            wm::Memory merged_result = wmProcessor.process(queryInput.toIce(), wmResult);
+            query_proc::wm::MemoryQueryProcessor wm2wmProcessor(
+                input.withData ? armem::DataMode::WithData : armem::DataMode::NoData);
+            armem::wm::Memory merged_result = wm2wmProcessor.process(queryInput.toIce(), wmResult);
             if (merged_result.empty())
             {
                 ARMARX_ERROR << "A merged and postprocessed Memory has no data although at least the LTM result contains data. This indicates that something is wrong.";
@@ -326,7 +330,7 @@ namespace armarx::armem::server
 
         if (queryResult.success)
         {
-            wm::Memory m;
+            armem::wm::Memory m;
             fromIce(queryResult.memory, m);
             longtermMemory->append(m);
         }
diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h
index cc665745970fad337c3e7af8adcdd1b9f713abc8..6aa68b5714ad369e3b2bbad08d7c1ca06ab04bb8 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h
@@ -6,12 +6,12 @@
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
 #include <RobotAPI/libraries/armem/client/Query.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 
 
 namespace armarx::armem::server
 {
 
-
     /**
      * @brief Helps connecting a Memory server to the Ice interface.
      *
@@ -23,7 +23,8 @@ namespace armarx::armem::server
     public:
 
         /// Construct an MemoryToIceAdapter from an existing Memory.
-        MemoryToIceAdapter(wm::Memory* workingMemory = nullptr, ltm::Memory* longtermMemory = nullptr);
+        MemoryToIceAdapter(server::wm::Memory* workingMemory = nullptr,
+                           ltm::Memory* longtermMemory = nullptr);
 
         void setMemoryListener(client::MemoryListenerInterfacePrx memoryListenerTopic);
 
@@ -54,7 +55,7 @@ namespace armarx::armem::server
 
     public:
 
-        wm::Memory* workingMemory;
+        server::wm::Memory* workingMemory;
         ltm::Memory* longtermMemory;
 
         client::MemoryListenerInterfacePrx memoryListenerTopic;
diff --git a/source/RobotAPI/libraries/armem/server/forward_declarations.h b/source/RobotAPI/libraries/armem/server/forward_declarations.h
new file mode 100644
index 0000000000000000000000000000000000000000..6872e2584352195ca8e587043e275acfbffb3739
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/forward_declarations.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/forward_declarations.h>
+
+
+namespace armarx::armem::server
+{
+    class MemoryToIceAdapter;
+}
+namespace armarx::armem::server::wm
+{
+    using EntityInstance = armem::wm::EntityInstance;
+    using EntitySnapshot = armem::wm::EntitySnapshot;
+    class Entity;
+    class ProviderSegment;
+    class CoreSegment;
+    class Memory;
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base.h b/source/RobotAPI/libraries/armem/server/query_proc/base.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d826798cecac7371882ce0783ddc05414a4f237
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h>
+#include <RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h>
+#include <RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h>
+#include <RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h>
+
+
+namespace armarx::armem::server::query_proc::base
+{
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp
index 34e2abd99c889d65723065c8b4726b2ea0aa9bd1..a3dfb4eb4102e21ee0cc97d7a9919b55c7c83f35 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp
@@ -1,2 +1,21 @@
 #include "BaseQueryProcessorBase.h"
 
+#include <ArmarXCore/core/logging/Logging.h>
+
+
+namespace armarx::armem::server::query_proc::base
+{
+
+    std::set<query::data::QueryTarget>
+    detail::getTargets(const std::vector<query::data::QueryTarget>& _targets)
+    {
+        std::set<query::data::QueryTarget> targets(_targets.begin(), _targets.end());
+        if (targets.empty())
+        {
+            ARMARX_DEBUG << "Query has no targets - using WM as default.";
+            targets.insert(query::data::QueryTarget::WM);
+        }
+        return targets;
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h
index 5e2ba4235154d81950f73fc218b302c41c382ffa..73c662e04ebd734cbe79c3b19f676f684223a88c 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h
@@ -1,88 +1,91 @@
 #pragma once
 
-#include <ArmarXCore/core/logging/Logging.h>
 #include <RobotAPI/interface/armem/query.h>
 
+#include <Ice/Handle.h>
 
-namespace armarx::armem::base::query_proc
+#include <set>
+#include <vector>
+
+
+namespace armarx::armem::server::query_proc::base::detail
 {
+    // If empty, e.g. when receiving queries from python, we use WM as default.
+    // We do it here as (Sl)ice does not support default values for vectors.
+    std::set<query::data::QueryTarget> getTargets(const std::vector<query::data::QueryTarget>& _targets);
+}
+namespace armarx::armem::server::query_proc::base
+{
+
+    using QueryTarget = query::data::QueryTarget;
+
 
     /**
      * @brief Base class for memory query processors.
      */
-    template <class DataT, class QueryT>
+    template <QueryTarget queryTarget, class DataT, class ResultT, class QueryT>
     class BaseQueryProcessorBase
     {
     public:
+
         using QueryPtrT = ::IceInternal::Handle<QueryT>;
         using QuerySeqT = std::vector<QueryPtrT>;
 
+
     public:
 
         virtual ~BaseQueryProcessorBase() = default;
 
 
-        DataT process(const QueryT& query, const DataT& data) const
+        ResultT process(const QueryT& query, const DataT& data) const
         {
-            DataT result { data.id() };
-            if (getTargets(query.targets).count(getTargetType()))
+            ResultT result { data.id() };
+            if (detail::getTargets(query.targets).count(queryTarget))
             {
                 this->process(result, query, data);
             }
             return result;
         }
 
-        DataT process(const QueryPtrT& query, const DataT& data) const
+        ResultT process(const QueryPtrT& query, const DataT& data) const
         {
             return this->process(*query, *data);
         }
 
-        DataT process(const QuerySeqT& queries, const DataT& data) const
+        ResultT process(const QuerySeqT& queries, const DataT& data) const
         {
-            DataT result { data.id() };
+            ResultT result { data.id() };
             this->process(result, queries, data);
             return result;
         }
 
-        void process(DataT& result, const QuerySeqT& queries, const DataT& data) const
+        void process(ResultT& result, const QuerySeqT& queries, const DataT& data) const
         {
             if (queries.empty())
             {
-                ARMARX_DEBUG << "There are no queries to process.";
                 return;
             }
 
             for (const auto& query : queries)
             {
-                if (getTargets(query->targets).count(getTargetType()))
+                if (detail::getTargets(query->targets).count(queryTarget))
                 {
                     this->process(result, *query, data);
                 }
             }
         }
 
-        virtual void process(DataT& result, const QueryT& query, const DataT& data) const = 0;
-
 
-    protected:
+        /**
+         * @brief Process the query and populate `result`.
+         *
+         * @param result The result container.
+         * @param query The query.
+         * @param data The source container.
+         */
+        virtual void process(ResultT& result, const QueryT& query, const DataT& data) const = 0;
 
-        virtual query::data::QueryTarget getTargetType() const = 0;
-
-
-    private:
+    };
 
-        /// If empty, e.g. when receiving queries from python, we use WM as default.
-        /// We do it here as (Sl)ice does not support default values for vectors.
-        static std::set<query::data::QueryTarget> getTargets(const std::vector<query::data::QueryTarget>& _targets)
-        {
-            std::set<query::data::QueryTarget> targets(_targets.begin(), _targets.end());
-            if (targets.empty())
-            {
-                ARMARX_DEBUG << "Query has no targets - using WM as default.";
-                targets.insert(query::data::QueryTarget::WM);
-            }
-            return targets;
-        }
 
-    };
 }
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h
index bb0c5072ebab28eb03cdb15fa3eab9ef315b783c..3050e6e4e91a90bfbfa97feff7f3afc6cb804f41 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h
@@ -9,31 +9,46 @@
 #include <RobotAPI/libraries/armem/core/error.h>
 
 #include "BaseQueryProcessorBase.h"
-#include "ProviderSegmentQueryProcessorBase.h"
 
 
-namespace armarx::armem::base::query_proc
+namespace armarx::armem::server::query_proc::base
 {
 
     /**
      * @brief Handles memory queries.
      */
-    template <class _CoreSegmentT>
+    template <QueryTarget queryTarget, class _CoreSegmentT, class _ResultCoreSegmentT, class _ChildProcessorT>
     class CoreSegmentQueryProcessorBase :
-        virtual public BaseQueryProcessorBase<_CoreSegmentT, armem::query::data::CoreSegmentQuery>
+        public BaseQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, armem::query::data::CoreSegmentQuery>
     {
-        using Base = BaseQueryProcessorBase<_CoreSegmentT, armem::query::data::CoreSegmentQuery>;
+        using Base = BaseQueryProcessorBase<queryTarget, _CoreSegmentT, _ResultCoreSegmentT, armem::query::data::CoreSegmentQuery>;
 
     public:
+
         using CoreSegmentT = _CoreSegmentT;
-        using ProviderSegmentT = typename _CoreSegmentT::ProviderSegmentT;
-        using EntityT = typename ProviderSegmentT::EntityT;
-        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+        using ProviderSegmentT = typename CoreSegmentT::ProviderSegmentT;
+
+        using ResultCoreSegmentT = _ResultCoreSegmentT;
+        using ResultProviderSegmentT = typename ResultCoreSegmentT::ProviderSegmentT;
+
+        using ChildProcessorT = _ChildProcessorT;
+
+
+    public:
+
+        CoreSegmentQueryProcessorBase()
+        {
+        }
+        CoreSegmentQueryProcessorBase(ChildProcessorT&& childProcessor) :
+            childProcessor(childProcessor)
+        {
+        }
+
 
         using Base::process;
-        virtual void process(_CoreSegmentT& result,
+        virtual void process(ResultCoreSegmentT& result,
                              const armem::query::data::CoreSegmentQuery& query,
-                             const _CoreSegmentT& coreSegment) const override
+                             const CoreSegmentT& coreSegment) const override
         {
             if (auto q = dynamic_cast<const armem::query::data::core::All*>(&query))
             {
@@ -53,25 +68,24 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        void process(_CoreSegmentT& result,
+        void process(ResultCoreSegmentT& result,
                      const armem::query::data::core::All& query,
-                     const _CoreSegmentT& coreSegment) const
+                     const CoreSegmentT& coreSegment) const
         {
             coreSegment.forEachProviderSegment([this, &query, &result](const ProviderSegmentT & providerSegment)
             {
-                result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment));
-                return true;
+                childProcessor.process(result.addProviderSegment(providerSegment.name()), query.providerSegmentQueries, providerSegment);
             });
         }
 
-        void process(_CoreSegmentT& result,
+        void process(ResultCoreSegmentT& result,
                      const armem::query::data::core::Single& query,
-                     const _CoreSegmentT& coreSegment) const
+                     const CoreSegmentT& coreSegment) const
         {
             try
             {
                 const ProviderSegmentT& providerSegment = coreSegment.getProviderSegment(query.providerSegmentName);
-                result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment));
+                childProcessor.process(result.addProviderSegment(providerSegment.name()), query.providerSegmentQueries, providerSegment);
             }
             catch (const error::MissingEntry&)
             {
@@ -79,9 +93,9 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        void process(_CoreSegmentT& result,
+        void process(ResultCoreSegmentT& result,
                      const armem::query::data::core::Regex& query,
-                     const _CoreSegmentT& coreSegment) const
+                     const CoreSegmentT& coreSegment) const
         {
             std::regex regex(query.providerSegmentNameRegex);
             coreSegment.forEachProviderSegment(
@@ -89,13 +103,15 @@ namespace armarx::armem::base::query_proc
             {
                 if (std::regex_search(providerSegment.name(), regex))
                 {
-                    result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment));
+                    childProcessor.process(result.addProviderSegment(providerSegment.name()), query.providerSegmentQueries, providerSegment);
                 }
-                return true;
             });
         }
 
+
     protected:
-        virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& a, const ProviderSegmentT& o) const = 0;
+
+        ChildProcessorT childProcessor;
+
     };
 }
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
index 6713a3e69a62cca8d9c083513b520c951c005984..0c4a842fa2772ae18b475b9e28ad3b13077bb49d 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
@@ -1,41 +1,42 @@
 #pragma once
 
-#include <cstdint>
-#include <iterator>
+#include "BaseQueryProcessorBase.h"
+
+#include <RobotAPI/libraries/armem/core/Time.h>
+#include <RobotAPI/libraries/armem/core/error.h>
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
 
 #include <RobotAPI/interface/armem/query.h>
 
-#include <ArmarXCore/core/exceptions/LocalException.h>
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <ArmarXCore/core/logging/Logging.h>
 
-#include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
-#include "BaseQueryProcessorBase.h"
-#include "RobotAPI/libraries/armem/core/Time.h"
+#include <cstdint>
+#include <iterator>
 
 
-namespace armarx::armem::base::query_proc
+namespace armarx::armem::server::query_proc::base
 {
 
-    /**
-     * @brief Handles memory queries.
-     */
-    template <class _EntityT>
+    template <QueryTarget queryTarget, class _EntityT, class _ResultEntityT>
     class EntityQueryProcessorBase :
-        virtual public BaseQueryProcessorBase<_EntityT, armem::query::data::EntityQuery>
+        public BaseQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT, armem::query::data::EntityQuery>
     {
-        using Base = BaseQueryProcessorBase<_EntityT, armem::query::data::EntityQuery>;
+        using Base = BaseQueryProcessorBase<queryTarget, _EntityT, _ResultEntityT, armem::query::data::EntityQuery>;
 
     public:
+
         using EntityT = _EntityT;
         using EntitySnapshotT = typename EntityT::EntitySnapshotT;
 
+        using ResultEntityT = _ResultEntityT;
+        using ResultSnapshotT = typename ResultEntityT::EntitySnapshotT;
+
+
         using Base::process;
-        void process(_EntityT& result,
-                     const armem::query::data::EntityQuery& query,
-                     const _EntityT& entity) const override
+        virtual void process(ResultEntityT& result,
+                             const armem::query::data::EntityQuery& query,
+                             const EntityT& entity) const override
         {
             if (auto q = dynamic_cast<const armem::query::data::entity::All*>(&query))
             {
@@ -71,9 +72,10 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        void process(_EntityT& result,
+
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::All& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             (void) query;
             // Copy this entitiy and its contents.
@@ -81,13 +83,13 @@ namespace armarx::armem::base::query_proc
             entity.forEachSnapshot([this, &result](const EntitySnapshotT & snapshot)
             {
                 addResultSnapshot(result, snapshot);
-                return true;
             });
         }
 
-        void process(_EntityT& result,
+
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::Single& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             if (query.timestamp < 0)
             {
@@ -132,9 +134,10 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        void process(_EntityT& result,
+
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::TimeRange& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             if (query.minTimestamp <= query.maxTimestamp || query.minTimestamp < 0 || query.maxTimestamp < 0)
             {
@@ -144,9 +147,10 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        void process(_EntityT& result,
+
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::IndexRange& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             entity.forEachSnapshotInIndexRange(
                 query.first, query.last,
@@ -156,10 +160,11 @@ namespace armarx::armem::base::query_proc
             });
         }
 
-        void process(_EntityT& result,
+
+        void process(ResultEntityT& result,
                      const Time& min,
                      const Time& max,
-                     const _EntityT& entity,
+                     const EntityT& entity,
                      const armem::query::data::EntityQuery& query) const
         {
             (void) query;
@@ -172,9 +177,9 @@ namespace armarx::armem::base::query_proc
         }
 
 
-        void process(_EntityT& result,
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::BeforeOrAtTime& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             const auto referenceTimestamp = fromIce<Time>(query.timestamp);
             ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp is negative!";
@@ -191,51 +196,40 @@ namespace armarx::armem::base::query_proc
         }
 
 
-        void process(_EntityT& result,
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::BeforeTime& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             const armem::Time referenceTimestamp = fromIce<Time>(query.timestamp);
             ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp must be non-negative.";
 
-#if 0
-            try
+            std::vector<const EntitySnapshotT*> befores;
+            entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s)
             {
-#endif
-                std::vector<const EntitySnapshotT*> befores;
-                entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s)
-                {
-                    befores.push_back(&s);
-                    return true;
-                });
-
-                size_t num = 0;
-                if (query.maxEntries < 0)
-                {
-                    num = befores.size();
-                }
-                else
-                {
-                    num = std::min(befores.size(), static_cast<size_t>(query.maxEntries));
-                }
+                befores.push_back(&s);
+            });
 
-                for (size_t r = 0; r < num; ++r)
-                {
-                    size_t i = befores.size() - 1 - r;
-                    addResultSnapshot(result, *befores[i]);
-                }
-#if 0
+            size_t num = 0;
+            if (query.maxEntries < 0)
+            {
+                num = befores.size();
             }
-            catch (const  error::MissingEntry&)
+            else
             {
-                // Leave empty.
+                num = std::min(befores.size(), static_cast<size_t>(query.maxEntries));
+            }
+
+            for (size_t r = 0; r < num; ++r)
+            {
+                size_t i = befores.size() - 1 - r;
+                addResultSnapshot(result, *befores[i]);
             }
-#endif
         }
 
-        void process(_EntityT& result,
+
+        void process(ResultEntityT& result,
                      const armem::query::data::entity::TimeApprox& query,
-                     const _EntityT& entity) const
+                     const EntityT& entity) const
         {
             const auto referenceTimestamp = fromIce<Time>(query.timestamp);
             ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp is negative!";
@@ -281,14 +275,16 @@ namespace armarx::armem::base::query_proc
             }
             catch (const armem::error::MissingEntry&)
             {
-
             }
         }
 
 
     protected:
-        virtual void addResultSnapshot(_EntityT& result, typename _EntityT::ContainerT::const_iterator it) const = 0;
-        virtual void addResultSnapshot(_EntityT& result, const typename _EntityT::EntitySnapshotT& snapshot) const = 0;
+
+        void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const
+        {
+            result.addSnapshot(snapshot);
+        }
 
     };
 }
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
index 66c2a8042b740ec72c6be3ca653f6ed72fc8c35b..df71683c29f2cb17db976e8be971725934b03348 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
@@ -1,47 +1,56 @@
 #pragma once
 
-#include <regex>
-
-#include <RobotAPI/interface/armem/query.h>
-
 #include "BaseQueryProcessorBase.h"
-#include "CoreSegmentQueryProcessorBase.h"
 
+#include <RobotAPI/libraries/armem/core/error.h>
+#include <RobotAPI/interface/armem/query.h>
 
 #include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include <RobotAPI/libraries/armem/core/error.h>
+#include <regex>
 
 
-namespace armarx::armem::base::query_proc
+namespace armarx::armem::server::query_proc::base
 {
-    /**
-     * @brief Handles memory queries.
-     */
-    template <class _MemoryT>
+
+    template <QueryTarget queryTarget, class _MemoryT, class _ResultMemoryT, class _ChildProcessorT>
     class MemoryQueryProcessorBase :
-        virtual public BaseQueryProcessorBase<_MemoryT, armem::query::data::MemoryQuery>
+        public BaseQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, armem::query::data::MemoryQuery>
     {
-        using Base = BaseQueryProcessorBase<_MemoryT, armem::query::data::MemoryQuery>;
+        using Base = BaseQueryProcessorBase<queryTarget, _MemoryT, _ResultMemoryT, armem::query::data::MemoryQuery>;
 
     public:
+
         using MemoryT = _MemoryT;
         using CoreSegmentT = typename MemoryT::CoreSegmentT;
-        using ProviderSegmentT = typename CoreSegmentT::ProviderSegmentT;
-        using EntityT = typename ProviderSegmentT::EntityT;
-        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+
+        using ResultMemoryT = _ResultMemoryT;
+        using ResultCoreSegmentT = typename ResultMemoryT::CoreSegmentT;
+
+        using ChildProcessorT = _ChildProcessorT;
+
+
+    public:
+
+        MemoryQueryProcessorBase()
+        {
+        }
+        MemoryQueryProcessorBase(ChildProcessorT&& childProcessor) :
+            childProcessor(childProcessor)
+        {
+        }
 
 
         using Base::process;
-        _MemoryT process(const armem::query::data::Input& input, const _MemoryT& memory) const
+        ResultMemoryT process(const armem::query::data::Input& input, const MemoryT& memory) const
         {
             return this->process(input.memoryQueries, memory);
         }
 
-        void process(_MemoryT& result,
-                     const armem::query::data::MemoryQuery& query,
-                     const _MemoryT& memory) const override
+        virtual void process(ResultMemoryT& result,
+                             const armem::query::data::MemoryQuery& query,
+                             const MemoryT& memory) const override
         {
             if (auto q = dynamic_cast<const armem::query::data::memory::All*>(&query))
             {
@@ -57,51 +66,52 @@ namespace armarx::armem::base::query_proc
             }
             else
             {
-                throw armem::error::UnknownQueryType("memory segment", query);
+                throw armem::error::UnknownQueryType(MemoryT::getLevelName(), query);
             }
         }
 
-        void process(_MemoryT& result,
+        void process(ResultMemoryT& result,
                      const armem::query::data::memory::All& query,
-                     const _MemoryT& memory) const
+                     const MemoryT& memory) const
         {
             memory.forEachCoreSegment([this, &result, &query](const CoreSegmentT & coreSegment)
             {
-                result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
-                return true;
+                childProcessor.process(result.addCoreSegment(coreSegment.name()), query.coreSegmentQueries, coreSegment);
             });
         }
 
-        void process(_MemoryT& result,
+        void process(ResultMemoryT& result,
                      const armem::query::data::memory::Single& query,
-                     const _MemoryT& memory) const
+                     const MemoryT& memory) const
         {
             try
             {
                 const CoreSegmentT& coreSegment = memory.getCoreSegment(query.coreSegmentName);
-                result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
+                childProcessor.process(result.addCoreSegment(coreSegment.name()), query.coreSegmentQueries, coreSegment);
             }
             catch (const error::MissingEntry&)
             {
             }
         }
 
-        void process(_MemoryT& result,
+        void process(ResultMemoryT& result,
                      const armem::query::data::memory::Regex& query,
-                     const _MemoryT& memory) const
+                     const MemoryT& memory) const
         {
             const std::regex regex(query.coreSegmentNameRegex);
             memory.forEachCoreSegment([this, &result, &query, &regex](const CoreSegmentT & coreSegment)
             {
                 if (std::regex_search(coreSegment.name(), regex))
                 {
-                    result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
+                    childProcessor.process(result.addCoreSegment(coreSegment.name()), query.coreSegmentQueries, coreSegment);
                 }
-                return true;
             });
         }
 
+
     protected:
-        virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& a, const CoreSegmentT& o) const = 0;
+
+        ChildProcessorT childProcessor;
+
     };
 }
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
index cb191d02edeaaa471290d5bf67475a5950572213..5102a12829c106e58159e7dcc35a7df0890f93d5 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
@@ -1,39 +1,50 @@
 #pragma once
 
-#include <RobotAPI/interface/armem/query.h>
-
 #include "BaseQueryProcessorBase.h"
-#include "EntityQueryProcessorBase.h"
 
-#include <regex>
+#include <RobotAPI/libraries/armem/core/error.h>
 
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <RobotAPI/interface/armem/query.h>
 
-#include <RobotAPI/libraries/armem/core/error.h>
+#include <regex>
 
 
-namespace armarx::armem::base::query_proc
+namespace armarx::armem::server::query_proc::base
 {
 
-    /**
-     * @brief Handles memory queries.
-     */
-    template <class _ProviderSegmentT>
+    template <QueryTarget queryTarget, class _ProviderSegmentT, class _ResultProviderSegmentT, class _ChildProcessorT>
     class ProviderSegmentQueryProcessorBase :
-        virtual public BaseQueryProcessorBase<_ProviderSegmentT, armem::query::data::ProviderSegmentQuery>
+        public BaseQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, armem::query::data::ProviderSegmentQuery>
     {
-        using Base = BaseQueryProcessorBase<_ProviderSegmentT, armem::query::data::ProviderSegmentQuery>;
+        using Base = BaseQueryProcessorBase<queryTarget, _ProviderSegmentT, _ResultProviderSegmentT, armem::query::data::ProviderSegmentQuery>;
+
 
     public:
+
         using ProviderSegmentT = _ProviderSegmentT;
         using EntityT = typename ProviderSegmentT::EntityT;
-        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+
+        using ResultProviderSegmentT = _ResultProviderSegmentT;
+        using ResultEntityT = typename ResultProviderSegmentT::EntityT;
+
+        using ChildProcessorT = _ChildProcessorT;
+
+
+    public:
+
+        ProviderSegmentQueryProcessorBase()
+        {
+        }
+        ProviderSegmentQueryProcessorBase(ChildProcessorT&& childProcessor) :
+            childProcessor(childProcessor)
+        {
+        }
+
 
         using Base::process;
-        void process(_ProviderSegmentT& result,
-                     const armem::query::data::ProviderSegmentQuery& query,
-                     const _ProviderSegmentT& providerSegment) const override
+        virtual void process(ResultProviderSegmentT& result,
+                             const armem::query::data::ProviderSegmentQuery& query,
+                             const ProviderSegmentT& providerSegment) const override
         {
             if (auto q = dynamic_cast<const armem::query::data::provider::All*>(&query))
             {
@@ -49,29 +60,28 @@ namespace armarx::armem::base::query_proc
             }
             else
             {
-                throw armem::error::UnknownQueryType("provider segment", query);
+                throw armem::error::UnknownQueryType(ProviderSegmentT::getLevelName(), query);
             }
         }
 
-        void process(_ProviderSegmentT& result,
+        void process(ResultProviderSegmentT& result,
                      const armem::query::data::provider::All& query,
-                     const _ProviderSegmentT& providerSegment) const
+                     const ProviderSegmentT& providerSegment) const
         {
             providerSegment.forEachEntity([this, &result, &query](const EntityT & entity)
             {
-                result.addEntity(entityProcessorProcess(query.entityQueries, entity));
-                return true;
+                childProcessor.process(result.addEntity(entity.name()), query.entityQueries, entity);
             });
         }
 
-        void process(_ProviderSegmentT& result,
+        void process(ResultProviderSegmentT& result,
                      const armem::query::data::provider::Single& query,
-                     const _ProviderSegmentT& providerSegment) const
+                     const ProviderSegmentT& providerSegment) const
         {
             try
             {
                 const EntityT& entity = providerSegment.getEntity(query.entityName);
-                result.addEntity(entityProcessorProcess(query.entityQueries, entity));
+                childProcessor.process(result.addEntity(entity.name()), query.entityQueries, entity);
             }
             catch (const error::MissingEntry&)
             {
@@ -79,22 +89,25 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        void process(_ProviderSegmentT& result,
+        void process(ResultProviderSegmentT& result,
                      const armem::query::data::provider::Regex& query,
-                     const _ProviderSegmentT& providerSegment) const
+                     const ProviderSegmentT& providerSegment) const
         {
             const std::regex regex(query.entityNameRegex);
             providerSegment.forEachEntity([this, &result, &query, &regex](const EntityT & entity)
             {
                 if (std::regex_search(entity.name(), regex))
                 {
-                    result.addEntity(entityProcessorProcess(query.entityQueries, entity));
+                    childProcessor.process(result.addEntity(entity.name()), query.entityQueries, entity);
                 }
                 return true;
             });
         }
 
+
     protected:
-        virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& a, const EntityT& o) const = 0;
+
+        ChildProcessorT childProcessor;
+
     };
 }
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a695cf43d51dcbbc2329fa1c48fbe8e63565c24f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.cpp
@@ -0,0 +1,7 @@
+#include "diskmemory.h"
+
+
+namespace armarx::armem::server::query_proc::d_ltm
+{
+}
+
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f2ffe791d192b9bc2b5f2a2be311735808427a4
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/diskmemory/Memory.h>
+#include <RobotAPI/libraries/armem/server/query_proc/base.h>
+
+
+namespace armarx::armem::server::query_proc::d_ltm
+{
+    static const base::QueryTarget queryTarget = query::data::QueryTarget::LTM;
+
+
+    class EntityQueryProcessor :
+        public base::EntityQueryProcessorBase<queryTarget, armem::d_ltm::Entity, armem::d_ltm::Entity>
+    {
+    };
+
+    class ProviderSegmentQueryProcessor :
+        public base::ProviderSegmentQueryProcessorBase <queryTarget, armem::d_ltm::ProviderSegment, armem::d_ltm::ProviderSegment, EntityQueryProcessor >
+    {
+    };
+
+    class CoreSegmentQueryProcessor :
+        public base::CoreSegmentQueryProcessorBase<queryTarget, armem::d_ltm::CoreSegment, armem::d_ltm::CoreSegment, ProviderSegmentQueryProcessor>
+    {
+    };
+
+    class MemoryQueryProcessor :
+        public base::MemoryQueryProcessorBase <queryTarget, armem::d_ltm::Memory, armem::d_ltm::Memory, CoreSegmentQueryProcessor >
+    {
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp
deleted file mode 100644
index 68821bcd95cdf2aaccf7126d4055495d39d0393d..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "BaseQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h
deleted file mode 100644
index 0e3ddac45c6a8eee377f468767a3bc39a580c554..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-#include <RobotAPI/libraries/armem/core/DataMode.h>
-
-#include "../base/BaseQueryProcessorBase.h"
-
-
-namespace armarx::armem::d_ltm::query_proc
-{
-    /**
-     * @brief Base class for memory query processors.
-     */
-    template <class DataT, class QueryT>
-    class BaseQueryProcessor :
-        virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT>
-    {
-        using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>;
-
-    public:
-        BaseQueryProcessor()
-        {}
-
-    protected:
-
-        query::data::QueryTarget getTargetType() const override
-        {
-            return query::data::QueryTarget::LTM;
-        }
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp
deleted file mode 100644
index afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "CoreSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h
deleted file mode 100644
index 5c043a2d1dbe2218078591adc3fc0ebac0bfe932..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/CoreSegmentQueryProcessorBase.h"
-
-#include "../../../core/diskmemory/CoreSegment.h"
-
-#include "ProviderSegmentQueryProcessor.h"
-
-
-namespace armarx::armem::d_ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class CoreSegmentQueryProcessor :
-        virtual public BaseQueryProcessor<d_ltm::CoreSegment, armem::query::data::CoreSegmentQuery>,
-        virtual public base::query_proc::CoreSegmentQueryProcessorBase<d_ltm::CoreSegment>
-    {
-        using Base = BaseQueryProcessor<d_ltm::CoreSegment, armem::query::data::CoreSegmentQuery>;
-
-    public:
-        CoreSegmentQueryProcessor() :
-            Base()
-        {}
-
-    protected:
-        virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override
-        {
-            return providerSegmentProcessor.process(q, s);
-        }
-
-    private:
-        ProviderSegmentQueryProcessor providerSegmentProcessor;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp
deleted file mode 100644
index c1c321b026b173c6552758fb9d8b9fdf722ea5a4..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "EntityQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h
deleted file mode 100644
index 712345e2a3d650f43974af3190225daa51deb13a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/EntityQueryProcessorBase.h"
-
-#include "../../../core/diskmemory/Entity.h"
-
-#include "EntityQueryProcessor.h"
-
-namespace armarx::armem::d_ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class EntityQueryProcessor :
-        virtual public BaseQueryProcessor<d_ltm::Entity, armem::query::data::EntityQuery>,
-        virtual public base::query_proc::EntityQueryProcessorBase<d_ltm::Entity>
-    {
-        using Base = BaseQueryProcessor<d_ltm::Entity, armem::query::data::EntityQuery>;
-
-    public:
-
-        EntityQueryProcessor() :
-            Base()
-        {}
-
-
-    private:
-
-        void addResultSnapshot(d_ltm::Entity& result, d_ltm::Entity::ContainerT::const_iterator it) const override
-        {
-            addResultSnapshot(result, it->second);
-        }
-
-        void addResultSnapshot(d_ltm::Entity& result, const d_ltm::EntitySnapshot& snapshot) const override
-        {
-            result.addSnapshot(d_ltm::EntitySnapshot(snapshot));
-        }
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp
deleted file mode 100644
index 69b04de6c9e623286a5bda836dddfdc8b551b64a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "MemoryQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h
deleted file mode 100644
index 038523950bfe399c2ef7a65b79fde43376651617..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/MemoryQueryProcessorBase.h"
-
-#include "../../../core/diskmemory/Memory.h"
-
-#include "CoreSegmentQueryProcessor.h"
-
-namespace armarx::armem::d_ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class MemoryQueryProcessor :
-        virtual public BaseQueryProcessor<d_ltm::Memory, armem::query::data::MemoryQuery>,
-        virtual public base::query_proc::MemoryQueryProcessorBase<d_ltm::Memory>
-    {
-        using Base = BaseQueryProcessor<d_ltm::Memory, armem::query::data::MemoryQuery>;
-
-    public:
-        MemoryQueryProcessor() :
-            Base()
-        {}
-
-    protected:
-        virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override
-        {
-            return coreSegmentProcessor.process(q, s);
-        }
-
-    private:
-        CoreSegmentQueryProcessor coreSegmentProcessor;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp
deleted file mode 100644
index 9a2a4405001f0904b74fc6afcf96813eef0879cd..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "ProviderSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h
deleted file mode 100644
index 2043273ec7c5f3fee2d02410a145ef436c47459c..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/ProviderSegmentQueryProcessorBase.h"
-
-#include "../../../core/diskmemory/ProviderSegment.h"
-
-#include "EntityQueryProcessor.h"
-
-namespace armarx::armem::d_ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class ProviderSegmentQueryProcessor :
-        virtual public BaseQueryProcessor<d_ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>,
-        virtual public base::query_proc::ProviderSegmentQueryProcessorBase<d_ltm::ProviderSegment>
-    {
-        using Base = BaseQueryProcessor<d_ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>;
-
-    public:
-        ProviderSegmentQueryProcessor() :
-            Base()
-        {}
-
-    protected:
-        virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override
-        {
-            return entityProcessor.process(q, s);
-        }
-
-    private:
-        EntityQueryProcessor entityProcessor;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp
deleted file mode 100644
index 68821bcd95cdf2aaccf7126d4055495d39d0393d..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "BaseQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h
deleted file mode 100644
index 64f560afff93e5d0cfff4b036f68f0fb4e8cdaba..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-#include <RobotAPI/libraries/armem/core/DataMode.h>
-
-#include "../base/BaseQueryProcessorBase.h"
-
-
-namespace armarx::armem::ltm::query_proc
-{
-    /**
-     * @brief Base class for memory query processors.
-     */
-    template <class DataT, class QueryT>
-    class BaseQueryProcessor :
-        virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT>
-    {
-        using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>;
-
-    public:
-        BaseQueryProcessor()
-        {}
-
-    protected:
-
-        query::data::QueryTarget getTargetType() const override
-        {
-            return query::data::QueryTarget::LTM;
-        }
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp
deleted file mode 100644
index afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "CoreSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h
deleted file mode 100644
index dc379f1d88fa82bbe886e412e0341079fa43fce9..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/CoreSegmentQueryProcessorBase.h"
-
-#include "../../../core/longtermmemory/CoreSegment.h"
-
-#include "ProviderSegmentQueryProcessor.h"
-
-
-namespace armarx::armem::ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class CoreSegmentQueryProcessor :
-        virtual public BaseQueryProcessor<ltm::CoreSegment, armem::query::data::CoreSegmentQuery>,
-        virtual public base::query_proc::CoreSegmentQueryProcessorBase<ltm::CoreSegment>
-    {
-        using Base = BaseQueryProcessor<ltm::CoreSegment, armem::query::data::CoreSegmentQuery>;
-
-    public:
-        CoreSegmentQueryProcessor() :
-            Base()
-        {}
-
-    protected:
-        virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override
-        {
-            return providerSegmentProcessor.process(q, s);
-        }
-
-    private:
-        ProviderSegmentQueryProcessor providerSegmentProcessor;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp
deleted file mode 100644
index c1c321b026b173c6552758fb9d8b9fdf722ea5a4..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "EntityQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h
deleted file mode 100644
index c7f793705e9143bb7b2f947f2750498ee26b8411..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/EntityQueryProcessorBase.h"
-
-#include "../../../core/longtermmemory/Entity.h"
-
-#include "EntityQueryProcessor.h"
-
-namespace armarx::armem::ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class EntityQueryProcessor :
-        virtual public BaseQueryProcessor<ltm::Entity, armem::query::data::EntityQuery>,
-        virtual public base::query_proc::EntityQueryProcessorBase<ltm::Entity>
-    {
-        using Base = BaseQueryProcessor<ltm::Entity, armem::query::data::EntityQuery>;
-
-    public:
-        EntityQueryProcessor() :
-            Base()
-        {}
-
-    private:
-        void addResultSnapshot(ltm::Entity& result, ltm::Entity::ContainerT::const_iterator it) const override
-        {
-            addResultSnapshot(result, it->second);
-        }
-
-        void addResultSnapshot(ltm::Entity& result, const ltm::EntitySnapshot& snapshot) const override
-        {
-            result.addSnapshot(ltm::EntitySnapshot{snapshot});
-        }
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp
deleted file mode 100644
index 69b04de6c9e623286a5bda836dddfdc8b551b64a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "MemoryQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h
deleted file mode 100644
index a5129417262515975efa247398602272865ee5ec..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/MemoryQueryProcessorBase.h"
-
-#include "../../../core/longtermmemory/Memory.h"
-
-#include "CoreSegmentQueryProcessor.h"
-
-namespace armarx::armem::ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class MemoryQueryProcessor :
-        virtual public BaseQueryProcessor<ltm::Memory, armem::query::data::MemoryQuery>,
-        virtual public base::query_proc::MemoryQueryProcessorBase<ltm::Memory>
-    {
-        using Base = BaseQueryProcessor<ltm::Memory, armem::query::data::MemoryQuery>;
-
-    public:
-        MemoryQueryProcessor() :
-            Base()
-        {}
-
-    protected:
-        virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override
-        {
-            return coreSegmentProcessor.process(q, s);
-        }
-
-    private:
-        CoreSegmentQueryProcessor coreSegmentProcessor;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp
deleted file mode 100644
index 9a2a4405001f0904b74fc6afcf96813eef0879cd..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "ProviderSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h
deleted file mode 100644
index e0c6db9e3ef06e6241e9af8c572bb7fc78eec452..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include "BaseQueryProcessor.h"
-#include "../base/ProviderSegmentQueryProcessorBase.h"
-
-#include "../../../core/longtermmemory/ProviderSegment.h"
-
-#include "EntityQueryProcessor.h"
-
-namespace armarx::armem::ltm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class ProviderSegmentQueryProcessor :
-        virtual public BaseQueryProcessor<ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>,
-        virtual public base::query_proc::ProviderSegmentQueryProcessorBase<ltm::ProviderSegment>
-    {
-        using Base = BaseQueryProcessor<ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>;
-
-    public:
-        ProviderSegmentQueryProcessor() :
-            Base()
-        {}
-
-    protected:
-        virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override
-        {
-            return entityProcessor.process(q, s);
-        }
-
-    private:
-        EntityQueryProcessor entityProcessor;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..238cc4b8d1601bf1ffae131caabbf8ca8435899a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm.cpp
@@ -0,0 +1,7 @@
+#include "ltm.h"
+
+
+namespace armarx::armem::server::query_proc::ltm
+{
+}
+
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae0dc778c821ae138c98b8554a22237bf26e5989
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
+#include <RobotAPI/libraries/armem/server/query_proc/base.h>
+
+
+namespace armarx::armem::server::query_proc::ltm
+{
+    static const base::QueryTarget queryTarget = query::data::QueryTarget::LTM;
+
+
+    class EntityQueryProcessor :
+        public base::EntityQueryProcessorBase<queryTarget, armem::ltm::Entity, armem::ltm::Entity>
+    {
+    };
+
+    class ProviderSegmentQueryProcessor :
+        public base::ProviderSegmentQueryProcessorBase <queryTarget, armem::ltm::ProviderSegment, armem::ltm::ProviderSegment, EntityQueryProcessor >
+    {
+    };
+
+    class CoreSegmentQueryProcessor :
+        public base::CoreSegmentQueryProcessorBase <queryTarget, armem::ltm::CoreSegment, armem::ltm::CoreSegment, ProviderSegmentQueryProcessor>
+    {
+    };
+
+    class MemoryQueryProcessor :
+        public base::MemoryQueryProcessorBase <queryTarget, armem::ltm::Memory, armem::ltm::Memory, CoreSegmentQueryProcessor >
+    {
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp b/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4e968623d63aa57213507879608c81823d31c7d6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/wm.cpp
@@ -0,0 +1,70 @@
+#include "wm.h"
+
+
+
+namespace armarx::armem::server::query_proc::wm::detail
+{
+
+    HasDataMode::HasDataMode(armem::DataMode dataMode) : dataMode(dataMode)
+    {
+    }
+
+}
+
+
+namespace armarx::armem::server::query_proc::wm
+{
+
+    ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) :
+        ProviderSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode)
+    {
+    }
+
+
+    CoreSegmentQueryProcessor::CoreSegmentQueryProcessor(DataMode dataMode) :
+        CoreSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode)
+    {
+    }
+
+
+    MemoryQueryProcessor::MemoryQueryProcessor(DataMode dataMode) :
+        MemoryQueryProcessorBase(dataMode), HasDataMode(dataMode)
+    {
+    }
+
+}
+
+
+namespace armarx::armem::server::query_proc::wm_server
+{
+    ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) :
+        ProviderSegmentQueryProcessorBase(dataMode), HasDataMode(dataMode)
+    {
+    }
+
+
+    CoreSegmentQueryProcessor::CoreSegmentQueryProcessor(DataMode dataMode) :
+        CoreSegmentQueryProcessorBase(dataMode),
+        HasDataMode(dataMode)
+    {
+    }
+
+
+    void CoreSegmentQueryProcessor::process(
+        armem::wm::CoreSegment& result,
+        const armem::query::data::CoreSegmentQuery& query,
+        const CoreSegment& coreSegment) const
+    {
+        std::scoped_lock lock(coreSegment.mutex());
+        CoreSegmentQueryProcessorBase::process(result, query, coreSegment);
+    }
+
+
+    MemoryQueryProcessor::MemoryQueryProcessor(DataMode dataMode) :
+        MemoryQueryProcessorBase(dataMode),
+        HasDataMode(dataMode)
+    {
+    }
+
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/wm.h b/source/RobotAPI/libraries/armem/server/query_proc/wm.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa52b4ab22fe1c6ef194ef37d4e38f5c7720d6c5
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/wm.h
@@ -0,0 +1,164 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/DataMode.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/query_proc/base.h>
+
+
+namespace armarx::armem::server::query_proc::wm
+{
+    static const base::QueryTarget queryTarget = query::data::QueryTarget::WM;
+}
+namespace armarx::armem::server::query_proc::wm::detail
+{
+
+    class HasDataMode
+    {
+    public:
+
+        HasDataMode(armem::DataMode dataMode);
+
+
+    protected:
+
+        armem::DataMode dataMode;
+
+    };
+
+
+
+    template <class SourceEntityT>
+    class EntityQueryProcessor :
+        public base::EntityQueryProcessorBase<queryTarget, SourceEntityT, armem::wm::Entity>,
+        public HasDataMode
+    {
+    public:
+
+        EntityQueryProcessor(DataMode dataMode = DataMode::WithData) :
+            HasDataMode(dataMode)
+        {}
+
+
+    protected:
+
+        void addResultSnapshot(armem::wm::Entity& result, const typename SourceEntityT::EntitySnapshotT& snapshot) const
+        {
+            bool withData = (dataMode == DataMode::WithData);
+            if (withData)
+            {
+                result.addSnapshot(server::wm::EntitySnapshot{ snapshot });
+            }
+            else
+            {
+                server::wm::EntitySnapshot copy = snapshot;
+                copy.forEachInstance([](server::wm::EntityInstance & i)
+                {
+                    i.data() = nullptr;
+                    return true;
+                });
+                result.addSnapshot(std::move(copy));
+            }
+        }
+
+    };
+}
+
+
+namespace armarx::armem::server::query_proc::wm
+{
+
+    using EntityQueryProcessor = detail::EntityQueryProcessor<armem::wm::Entity>;
+
+
+    class ProviderSegmentQueryProcessor :
+        public base::ProviderSegmentQueryProcessorBase<queryTarget, armem::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor >,
+        public detail::HasDataMode
+    {
+    public:
+
+        ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData);
+
+    };
+
+
+    class CoreSegmentQueryProcessor :
+        public base::CoreSegmentQueryProcessorBase <queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor >,
+        public detail::HasDataMode
+    {
+        using Base = base::CoreSegmentQueryProcessorBase<queryTarget, armem::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>;
+        using CoreSegment = armem::wm::CoreSegment;
+        using ProviderSegment = armem::wm::ProviderSegment;
+
+    public:
+
+        CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData);
+
+    };
+
+
+    class MemoryQueryProcessor :
+        public base::MemoryQueryProcessorBase<queryTarget, armem::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>,
+        public detail::HasDataMode
+    {
+    public:
+
+        MemoryQueryProcessor(DataMode dataMode = DataMode::WithData);
+
+    };
+
+}
+
+
+namespace armarx::armem::server::query_proc::wm_server
+{
+
+    using EntityQueryProcessor = wm::detail::EntityQueryProcessor<server::wm::Entity>;
+
+
+    class ProviderSegmentQueryProcessor :
+        public base::ProviderSegmentQueryProcessorBase<wm::queryTarget, server::wm::ProviderSegment, armem::wm::ProviderSegment, EntityQueryProcessor >,
+        public wm::detail::HasDataMode
+    {
+    public:
+
+        ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData);
+
+    };
+
+
+    class CoreSegmentQueryProcessor :
+        public base::CoreSegmentQueryProcessorBase <wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor >,
+        public wm::detail::HasDataMode
+    {
+        using Base = base::CoreSegmentQueryProcessorBase<wm::queryTarget, server::wm::CoreSegment, armem::wm::CoreSegment, ProviderSegmentQueryProcessor>;
+        using CoreSegment = server::wm::CoreSegment;
+        using ProviderSegment = server::wm::ProviderSegment;
+
+    public:
+
+        CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData);
+
+
+        using Base::process;
+
+        /// Locks the core segment, then delegates back to `CoreSegmentQueryProcessorBase`.
+        void process(
+            armem::wm::CoreSegment& result,
+            const armem::query::data::CoreSegmentQuery& query,
+            const CoreSegment& coreSegment) const override;
+
+    };
+
+
+    class MemoryQueryProcessor :
+        public base::MemoryQueryProcessorBase<wm::queryTarget, server::wm::Memory, armem::wm::Memory, CoreSegmentQueryProcessor>,
+        public wm::detail::HasDataMode
+    {
+    public:
+
+        MemoryQueryProcessor(DataMode dataMode = DataMode::WithData);
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp
deleted file mode 100644
index 68821bcd95cdf2aaccf7126d4055495d39d0393d..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "BaseQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h
deleted file mode 100644
index d4875053c93dc2278cdb9f327fc0739370811fe7..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-#include <RobotAPI/libraries/armem/core/DataMode.h>
-
-#include <RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h>
-
-
-namespace armarx::armem::wm::query_proc
-{
-    /**
-     * @brief Base class for memory query processors.
-     */
-    template <class DataT, class QueryT>
-    class BaseQueryProcessor :
-        virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT>
-    {
-        using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>;
-
-    public:
-
-        BaseQueryProcessor(DataMode dataMode = DataMode::WithData) :
-            dataMode(dataMode)
-        {}
-
-
-    protected:
-
-        query::data::QueryTarget getTargetType() const override
-        {
-            return query::data::QueryTarget::WM;
-        }
-
-        DataMode dataMode;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp
deleted file mode 100644
index deb66ad71924022ba5a4ebcf2aa582265023dcf5..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "CoreSegmentQueryProcessor.h"
-
-#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
-
-
-namespace armarx::armem::wm::query_proc
-{
-
-    CoreSegmentQueryProcessor::CoreSegmentQueryProcessor(DataMode dataMode) :
-        Base(dataMode), providerSegmentProcessor(dataMode)
-    {}
-
-
-    CoreSegmentQueryProcessor::~CoreSegmentQueryProcessor() = default;
-
-
-    void CoreSegmentQueryProcessor::process(
-        CoreSegment& result, const armem::query::data::CoreSegmentQuery& query, const CoreSegment& coreSegment) const
-    {
-        std::scoped_lock lock(coreSegment.mutex());
-        CoreSegmentQueryProcessorBase::process(result, query, coreSegment);
-    }
-
-
-    data::CoreSegment CoreSegmentQueryProcessor::processToIce(const armem::query::data::CoreSegmentQuery& query, const wm::CoreSegment& coreSegment) const
-    {
-        data::CoreSegment data;
-        toIce(data, process(query, coreSegment));
-        return data;
-    }
-
-
-    ProviderSegment CoreSegmentQueryProcessor::providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegment& s) const
-    {
-        return providerSegmentProcessor.process(q, s);
-    }
-
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h
deleted file mode 100644
index a09f5c8cef96350398e35d0448f9a3aee1f27a53..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include <mutex>
-
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h>
-
-#include "BaseQueryProcessor.h"
-#include "ProviderSegmentQueryProcessor.h"
-
-
-namespace armarx::armem::wm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class CoreSegmentQueryProcessor :
-        virtual public BaseQueryProcessor<wm::CoreSegment, armem::query::data::CoreSegmentQuery>,
-        virtual public base::query_proc::CoreSegmentQueryProcessorBase<wm::CoreSegment>
-    {
-        using Base = BaseQueryProcessor<wm::CoreSegment, armem::query::data::CoreSegmentQuery>;
-
-    public:
-
-        CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData);
-        virtual ~CoreSegmentQueryProcessor() override;
-
-        using Base::process;
-
-        /// Locks the core segment, then delegates back to `CoreSegmentQueryProcessorBase`.
-        void process(CoreSegment& result,
-                     const armem::query::data::CoreSegmentQuery& query,
-                     const CoreSegment& coreSegment) const override;
-
-        data::CoreSegment processToIce(const armem::query::data::CoreSegmentQuery& query, const wm::CoreSegment& coreSegment) const;
-
-
-    protected:
-
-        virtual ProviderSegment providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override;
-
-
-    private:
-
-        ProviderSegmentQueryProcessor providerSegmentProcessor;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp
deleted file mode 100644
index ec1c7640c229c551d0b8b6b1a8f2df7b771139ef..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "EntityQueryProcessor.h"
-
-#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
-
-
-namespace armarx::armem::wm::query_proc
-{
-    EntityQueryProcessor::EntityQueryProcessor(DataMode dataMode) :
-        BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>(dataMode)
-    {}
-
-
-    EntityQueryProcessor::~EntityQueryProcessor() = default;
-
-
-    void EntityQueryProcessor::addResultSnapshot(wm::Entity& result, const wm::EntitySnapshot& snapshot) const
-    {
-        bool withData = (dataMode == DataMode::WithData);
-        if (withData)
-        {
-            result.addSnapshot(wm::EntitySnapshot{ snapshot });
-        }
-        else
-        {
-            wm::EntitySnapshot copy = snapshot;
-            copy.forEachInstance([](EntityInstance & i)
-            {
-                i.data() = nullptr;
-                return true;
-            });
-            result.addSnapshot(std::move(copy));
-        }
-    }
-
-
-    data::Entity EntityQueryProcessor::processToIce(const armem::query::data::EntityQuery& query, const wm::Entity& entity) const
-    {
-        data::Entity data;
-        toIce(data, process(query, entity));
-        return data;
-    }
-
-
-    void EntityQueryProcessor::addResultSnapshot(wm::Entity& result, wm::Entity::ContainerT::const_iterator it) const
-    {
-        addResultSnapshot(result, it->second);
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h
deleted file mode 100644
index 4d0a2e02ad44a3364ee4cfd6a4e7db3b0c5fb993..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h>
-
-#include "BaseQueryProcessor.h"
-
-
-namespace armarx::armem::wm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class EntityQueryProcessor :
-        virtual public BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>,
-        virtual public base::query_proc::EntityQueryProcessorBase<wm::Entity>
-    {
-        using Base = BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>;
-
-    public:
-
-        EntityQueryProcessor(DataMode dataMode = DataMode::WithData);
-        virtual ~EntityQueryProcessor() override;
-
-        data::Entity processToIce(const armem::query::data::EntityQuery& query, const wm::Entity& entity) const;
-
-
-    private:
-
-        void addResultSnapshot(wm::Entity& result, wm::Entity::ContainerT::const_iterator it) const override;
-        void addResultSnapshot(wm::Entity& result, const wm::EntitySnapshot& snapshot) const override;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp
deleted file mode 100644
index 7aa868af13bc525b42d93f230a8398c27531525d..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "MemoryQueryProcessor.h"
-
-
-namespace armarx::armem::wm::query_proc
-{
-
-    MemoryQueryProcessor::MemoryQueryProcessor(DataMode dataMode) :
-        Base(dataMode), coreSegmentProcessor(dataMode)
-    {}
-
-
-    MemoryQueryProcessor::~MemoryQueryProcessor()
-    {
-    }
-
-
-    CoreSegment MemoryQueryProcessor::coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegment& s) const
-    {
-        return coreSegmentProcessor.process(q, s);
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h
deleted file mode 100644
index a442baaf38b297ab3659228e21e0a158cd00a4bb..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h>
-
-#include "BaseQueryProcessor.h"
-
-#include "CoreSegmentQueryProcessor.h"
-
-
-namespace armarx::armem::wm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class MemoryQueryProcessor :
-        virtual public BaseQueryProcessor<wm::Memory, armem::query::data::MemoryQuery>,
-        virtual public base::query_proc::MemoryQueryProcessorBase<wm::Memory>
-    {
-        using Base = BaseQueryProcessor<wm::Memory, armem::query::data::MemoryQuery>;
-
-    public:
-
-        MemoryQueryProcessor(DataMode dataMode = DataMode::WithData);
-        virtual ~MemoryQueryProcessor() override;
-
-
-    protected:
-
-        virtual CoreSegment coreSegmentProcessorProcess(
-            const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegment& s) const override;
-
-
-    private:
-
-        CoreSegmentQueryProcessor coreSegmentProcessor;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp
deleted file mode 100644
index d50d252aacbd6460bcaa668b2e983c445b018f17..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "ProviderSegmentQueryProcessor.h"
-
-#include <RobotAPI/libraries/armem/core/wm/ice_conversions.h>
-
-
-namespace armarx::armem::wm::query_proc
-{
-
-    ProviderSegmentQueryProcessor::ProviderSegmentQueryProcessor(DataMode dataMode) :
-        Base(dataMode), entityProcessor(dataMode)
-    {}
-
-
-    ProviderSegmentQueryProcessor::~ProviderSegmentQueryProcessor() = default;
-
-
-    data::ProviderSegment ProviderSegmentQueryProcessor::processToIce(const armem::query::data::ProviderSegmentQuery& query, const wm::ProviderSegment& providerSegment) const
-    {
-        data::ProviderSegment data;
-        toIce(data, process(query, providerSegment));
-        return data;
-    }
-
-
-    Entity ProviderSegmentQueryProcessor::entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const Entity& s) const
-    {
-        return entityProcessor.process(q, s);
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h
deleted file mode 100644
index ee878428d4e52d237bb0fe9c9050fa071c38953a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
-#include <RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h>
-
-#include "BaseQueryProcessor.h"
-#include "EntityQueryProcessor.h"
-
-
-namespace armarx::armem::wm::query_proc
-{
-    /**
-     * @brief Handles memory queries.
-     */
-    class ProviderSegmentQueryProcessor :
-        virtual public BaseQueryProcessor<wm::ProviderSegment, armem::query::data::ProviderSegmentQuery>,
-        virtual public base::query_proc::ProviderSegmentQueryProcessorBase<wm::ProviderSegment>
-    {
-        using Base = BaseQueryProcessor<wm::ProviderSegment, armem::query::data::ProviderSegmentQuery>;
-
-    public:
-
-        ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData);
-        virtual ~ProviderSegmentQueryProcessor() override;
-
-
-        using Base::process;
-        data::ProviderSegment processToIce(const armem::query::data::ProviderSegmentQuery& query, const wm::ProviderSegment& providerSegment) const;
-
-
-    protected:
-
-        virtual Entity entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const Entity& s) const override;
-
-    private:
-
-        EntityQueryProcessor entityProcessor;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/server/segment/Segment.h b/source/RobotAPI/libraries/armem/server/segment/Segment.h
index 52d12980eaf68a022ae595e7da41f3b2c03fd5a4..7808e99d31f4df3543bfbd5b882a408dda143ed5 100644
--- a/source/RobotAPI/libraries/armem/server/segment/Segment.h
+++ b/source/RobotAPI/libraries/armem/server/segment/Segment.h
@@ -16,11 +16,12 @@ namespace armarx::armem
     namespace server
     {
         class MemoryToIceAdapter;
-    }
-    namespace wm
-    {
-        class CoreSegment;
-        class ProviderSegment;
+
+        namespace wm
+        {
+            class CoreSegment;
+            class ProviderSegment;
+        }
     }
 }
 namespace armarx::armem::server::segment
@@ -67,9 +68,9 @@ namespace armarx::armem::server::segment
         /**
          * @brief A base class for core segments
          */
-        class CoreSegmentBase : public detail::SegmentBase<armarx::armem::wm::CoreSegment>
+        class CoreSegmentBase : public detail::SegmentBase<server::wm::CoreSegment>
         {
-            using Base = detail::SegmentBase<armarx::armem::wm::CoreSegment>;
+            using Base = detail::SegmentBase<server::wm::CoreSegment>;
 
         public:
 
@@ -107,9 +108,9 @@ namespace armarx::armem::server::segment
         /**
          * @brief A base class for provider segments
          */
-        class ProviderSegmentBase : public detail::SegmentBase<armarx::armem::wm::ProviderSegment>
+        class ProviderSegmentBase : public detail::SegmentBase<server::wm::ProviderSegment>
         {
-            using Base = detail::SegmentBase<armarx::armem::wm::ProviderSegment>;
+            using Base = detail::SegmentBase<server::wm::ProviderSegment>;
 
         public:
 
@@ -142,7 +143,7 @@ namespace armarx::armem::server::segment
             aron::typenavigator::ObjectNavigatorPtr coreSegmentAronType;
             aron::typenavigator::ObjectNavigatorPtr providerSegmentAronType;
 
-            armarx::armem::wm::CoreSegment* coreSegment;
+            server::wm::CoreSegment* coreSegment;
         };
 
 
diff --git a/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h b/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h
index d6601c39b8076a140070db86859b38d575e52dc7..460fbf3f0f0cd4ea6c2835d499071f2e43bf2a7d 100644
--- a/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h
+++ b/source/RobotAPI/libraries/armem/server/segment/SpecializedSegment.h
@@ -14,11 +14,11 @@ namespace armarx::armem
     namespace server
     {
         class MemoryToIceAdapter;
-    }
 
-    namespace wm
-    {
-        class CoreSegment;
+        namespace wm
+        {
+            class CoreSegment;
+        }
     }
 }
 
@@ -59,7 +59,7 @@ namespace armarx::armem::server::segment
     protected:
 
         server::MemoryToIceAdapter& iceMemory;
-        wm::CoreSegment* coreSegment = nullptr;
+        server::wm::CoreSegment* coreSegment = nullptr;
         aron::typenavigator::ObjectNavigatorPtr aronType;
 
         struct Properties
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.cpp
similarity index 85%
rename from source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp
rename to source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.cpp
index f1a308f0764a8cb8067f3403ef5427d904fa93dc..d90756691871b6ad444a67fa76a733d0086b5b29 100644
--- a/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp
+++ b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.cpp
@@ -1,7 +1,7 @@
 #include "MaxHistorySize.h"
 
 
-namespace armarx::armem::base::detail
+namespace armarx::armem::server::detail
 {
     void MaxHistorySize::setMaxHistorySize(long maxSize)
     {
diff --git a/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.h b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2f2d498c2945f4456c281abafe0f1ad66074e72
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/wm/detail/MaxHistorySize.h
@@ -0,0 +1,58 @@
+#pragma once
+
+
+namespace armarx::armem::server::detail
+{
+    // TODO: Replace by ConstrainedHistorySize (not only max entries, e.g. delete oldest / delete least accessed / ...)
+
+    class MaxHistorySize
+    {
+    public:
+
+        /**
+         * @brief Set the maximum number of snapshots to be contained in an entity.
+         * Affected entities are to be update right away.
+         */
+        void setMaxHistorySize(long maxSize);
+
+        long getMaxHistorySize() const;
+
+
+    protected:
+
+        /**
+         * @brief Maximum size of entity histories.
+         *
+         * If negative, the size of `history` is not limited.
+         *
+         * @see Entity::maxHstorySize
+         */
+        long _maxHistorySize = -1;
+
+    };
+
+
+
+    template <class DerivedT>
+    class MaxHistorySizeParent : public MaxHistorySize
+    {
+    public:
+
+        /**
+         * @brief Sets the maximum history size of entities in this container.
+         * This affects all current entities as well as new ones.
+         *
+         * @see MaxHistorySize::setMaxHistorySize()
+         */
+        void setMaxHistorySize(long maxSize)
+        {
+            MaxHistorySize::setMaxHistorySize(maxSize);
+            static_cast<DerivedT&>(*this).forEachChild([maxSize](auto & child)
+            {
+                child.setMaxHistorySize(maxSize);
+                return true;
+            });
+        }
+
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/wm/ice_conversions.cpp b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ba3352d6e8bb443693ebfa5752a46cad9c24267
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.cpp
@@ -0,0 +1,64 @@
+#include "ice_conversions.h"
+
+#include <RobotAPI/libraries/armem/core/base/ice_conversions.h>
+
+
+namespace armarx::armem::server
+{
+
+    void wm::toIce(data::EntityInstance& ice, const EntityInstance& data)
+    {
+        base::toIce(ice, data);
+    }
+    void wm::fromIce(const data::EntityInstance& ice, EntityInstance& data)
+    {
+        base::fromIce(ice, data);
+    }
+
+
+    void wm::toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot)
+    {
+        base::toIce(ice, snapshot);
+    }
+    void wm::fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot)
+    {
+        base::fromIce(ice, snapshot);
+    }
+
+    void wm::toIce(data::Entity& ice, const Entity& entity)
+    {
+        base::toIce(ice, entity);
+    }
+    void wm::fromIce(const data::Entity& ice, Entity& entity)
+    {
+        base::fromIce(ice, entity);
+    }
+
+    void wm::toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment)
+    {
+        base::toIce(ice, providerSegment);
+    }
+    void wm::fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment)
+    {
+        base::fromIce(ice, providerSegment);
+    }
+
+    void wm::toIce(data::CoreSegment& ice, const CoreSegment& coreSegment)
+    {
+        base::toIce(ice, coreSegment);
+    }
+    void wm::fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment)
+    {
+        base::fromIce(ice, coreSegment);
+    }
+
+    void wm::toIce(data::Memory& ice, const Memory& memory)
+    {
+        base::toIce(ice, memory);
+    }
+    void wm::fromIce(const data::Memory& ice, Memory& memory)
+    {
+        base::fromIce(ice, memory);
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/wm/ice_conversions.h b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.h
new file mode 100644
index 0000000000000000000000000000000000000000..c25b16775bc577c61d0c804cf4525b23ecd5e5d1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/wm/ice_conversions.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/memory.h>
+
+#include "memory_definitions.h"
+
+
+namespace armarx::armem::server::wm
+{
+
+    void toIce(data::EntityInstance& ice, const EntityInstance& data);
+    void fromIce(const data::EntityInstance& ice, EntityInstance& data);
+
+
+    void toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot);
+    void fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot);
+
+    void toIce(data::Entity& ice, const Entity& entity);
+    void fromIce(const data::Entity& ice, Entity& entity);
+
+
+    void toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment);
+    void fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment);
+
+    void toIce(data::CoreSegment& ice, const CoreSegment& coreSegment);
+    void fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment);
+
+    void toIce(data::Memory& ice, const Memory& memory);
+    void fromIce(const data::Memory& ice, Memory& memory);
+}
diff --git a/source/RobotAPI/libraries/armem/server/wm/memory_definitions.cpp b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58be8027db2561979d3510b7d481715678b61eae
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.cpp
@@ -0,0 +1,202 @@
+#include "memory_definitions.h"
+
+#include "error.h"
+
+#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include <map>
+#include <vector>
+
+
+namespace armarx::armem::server::wm
+{
+
+    void Entity::setMaxHistorySize(long maxSize)
+    {
+        MaxHistorySize::setMaxHistorySize(maxSize);
+        truncate();
+    }
+
+
+    auto Entity::update(const EntityUpdate& update) -> UpdateResult
+    {
+        UpdateResult result = EntityBase::update(update);
+        result.removedSnapshots = this->truncate();
+        return result;
+    }
+
+
+    std::vector<EntitySnapshot> Entity::truncate()
+    {
+        std::vector<EntitySnapshot> removedElements;
+        if (_maxHistorySize >= 0)
+        {
+            while (this->_container.size() > size_t(_maxHistorySize))
+            {
+                removedElements.push_back(std::move(this->_container.begin()->second));
+                this->_container.erase(this->_container.begin());
+            }
+            ARMARX_CHECK_LESS_EQUAL(this->_container.size(), _maxHistorySize);
+        }
+        return removedElements;
+    }
+
+
+
+    Entity& ProviderSegment::addEntity(Entity&& entity)
+    {
+        Entity& added = ProviderSegmentBase::addEntity(std::move(entity));
+        added.setMaxHistorySize(this->getMaxHistorySize());
+        return added;
+    }
+
+
+
+    std::mutex& CoreSegment::mutex() const
+    {
+        return _mutex;
+    }
+
+
+    std::optional<wm::EntitySnapshot> CoreSegment::getLatestEntitySnapshot(const MemoryID& entityID) const
+    {
+        const wm::Entity& entity = this->getEntity(entityID);
+        if (entity.empty())
+        {
+            return std::nullopt;
+        }
+        else
+        {
+            return entity.getLatestSnapshot();
+        }
+    }
+
+
+    std::optional<wm::EntityInstance> CoreSegment::getLatestEntityInstance(
+        const MemoryID& entityID, int instanceIndex) const
+    {
+        auto snapshot = getLatestEntitySnapshot(entityID);
+        if (snapshot.has_value()
+            and instanceIndex >= 0
+            and static_cast<size_t>(instanceIndex) < snapshot->size())
+        {
+            return snapshot->getInstance(instanceIndex);
+        }
+        else
+        {
+            return std::nullopt;
+        }
+    }
+
+
+    armarx::aron::datanavigator::DictNavigatorPtr
+    CoreSegment::getLatestEntityInstanceData(const MemoryID& entityID, int instanceIndex) const
+    {
+        auto instance = getLatestEntityInstance(entityID, instanceIndex);
+        if (instance.has_value())
+        {
+            return instance->data();
+        }
+        else
+        {
+            return nullptr;
+        }
+    }
+
+
+    ProviderSegment& CoreSegment::addProviderSegment(ProviderSegment&& providerSegment)
+    {
+        ProviderSegmentT& added = CoreSegmentBase::addProviderSegment(std::move(providerSegment));
+        added.setMaxHistorySize(this->getMaxHistorySize());
+        return added;
+    }
+
+
+    std::optional<wm::EntitySnapshot>
+    CoreSegment::getLatestEntitySnapshotLocking(const MemoryID& entityID) const
+    {
+        std::scoped_lock lock(_mutex);
+        return getLatestEntitySnapshot(entityID);
+    }
+
+    std::optional<wm::EntityInstance>
+    CoreSegment::getLatestEntityInstanceLocking(const MemoryID& entityID, int instanceIndex) const
+    {
+        std::scoped_lock lock(_mutex);
+        return getLatestEntityInstance(entityID, instanceIndex);
+    }
+
+    armarx::aron::datanavigator::DictNavigatorPtr
+    CoreSegment::getLatestEntityInstanceDataLocking(const MemoryID& entityID, int instanceIndex) const
+    {
+        std::scoped_lock lock(_mutex);
+        return getLatestEntityInstanceData(entityID, instanceIndex);
+    }
+
+
+    // TODO: add core segment if param is set
+    std::vector<Memory::Base::UpdateResult>
+    Memory::updateLocking(const Commit& commit)
+    {
+        // Group updates by core segment, then update each core segment in a batch to only lock it once.
+        std::map<std::string, std::vector<const EntityUpdate*>> updatesPerCoreSegment;
+        for (const EntityUpdate& update : commit.updates)
+        {
+            updatesPerCoreSegment[update.entityID.coreSegmentName].push_back(&update);
+        }
+
+        std::vector<Memory::Base::UpdateResult> result;
+        // To throw an exception after the commit if a core segment is missing and the memory should not create new ones
+        std::vector<std::string> missingCoreSegmentNames;
+        for (const auto& [coreSegmentName, updates] : updatesPerCoreSegment)
+        {
+            auto it = this->_container.find(coreSegmentName);
+            if (it != this->_container.end())
+            {
+                CoreSegment& coreSegment = it->second;
+
+                // Lock the core segment for the whole batch.
+                std::scoped_lock lock(coreSegment.mutex());
+
+                for (const EntityUpdate* update : updates)
+                {
+                    auto r = coreSegment.update(*update);
+                    Base::UpdateResult ret { r };
+                    ret.memoryUpdateType = UpdateType::UpdatedExisting;
+                    result.push_back(ret);
+                }
+            }
+            else
+            {
+                // Perform the other updates first, then throw afterwards.
+                missingCoreSegmentNames.push_back(coreSegmentName);
+            }
+        }
+        // Throw an exception if something went wrong.
+        if (not missingCoreSegmentNames.empty())
+        {
+            // Just throw an exception for the first entry. We can extend this exception in the future.
+            throw armem::error::MissingEntry::create<CoreSegment>(missingCoreSegmentNames.front(), *this);
+        }
+        return result;
+    }
+
+
+    // TODO: Add core segment if param is set
+    Memory::Base::UpdateResult
+    Memory::updateLocking(const EntityUpdate& update)
+    {
+        this->_checkContainerName(update.entityID.memoryName, this->name());
+
+        CoreSegment& segment = getCoreSegment(update.entityID.coreSegmentName);
+        Base::UpdateResult result;
+        {
+            std::scoped_lock lock(segment.mutex());
+            result = segment.update(update);
+        }
+        result.memoryUpdateType = UpdateType::UpdatedExisting;
+        return result;
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/wm/memory_definitions.h b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.h
new file mode 100644
index 0000000000000000000000000000000000000000..4eb6fdbb3105b0ae2ce3148c8457b915040a170a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/wm/memory_definitions.h
@@ -0,0 +1,189 @@
+#pragma once
+
+#include "detail/MaxHistorySize.h"
+
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/core/base/EntityInstanceBase.h>
+#include <RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h>
+#include <RobotAPI/libraries/armem/core/base/EntityBase.h>
+#include <RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h>
+#include <RobotAPI/libraries/armem/core/base/CoreSegmentBase.h>
+#include <RobotAPI/libraries/armem/core/base/MemoryBase.h>
+
+#include <mutex>
+#include <optional>
+
+
+namespace armarx::armem::server::wm
+{
+    using EntityInstanceMetadata = base::EntityInstanceMetadata;
+    using EntityInstanceData = armarx::aron::datanavigator::DictNavigator;
+    using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr;
+
+    using EntityInstance = armem::wm::EntityInstance;
+    using EntitySnapshot = armem::wm::EntitySnapshot;
+
+
+    /// @see base::EntityBase
+    class Entity :
+        public base::EntityBase<EntitySnapshot, Entity>,
+        public detail::MaxHistorySize
+    {
+    public:
+
+        using base::EntityBase<EntitySnapshot, Entity>::EntityBase;
+
+
+        /**
+         * @brief Sets the maximum history size.
+         *
+         * The current history is truncated if necessary.
+         */
+        void setMaxHistorySize(long maxSize);
+
+        UpdateResult update(const EntityUpdate& update);
+
+
+    protected:
+
+        /// If maximum size is set, ensure `history`'s is not higher.
+        std::vector<EntitySnapshotT> truncate();
+
+    };
+
+
+
+    /// @see base::ProviderSegmentBase
+    class ProviderSegment :
+        public base::ProviderSegmentBase<Entity, ProviderSegment>,
+        public detail::MaxHistorySizeParent<ProviderSegment>
+    {
+    public:
+
+        using base::ProviderSegmentBase<Entity, ProviderSegment>::ProviderSegmentBase;
+
+
+        using ProviderSegmentBase::addEntity;
+        EntityT& addEntity(EntityT&& entity);
+
+    };
+
+
+
+    /// @brief base::CoreSegmentBase
+    class CoreSegment :
+        public base::CoreSegmentBase<ProviderSegment, CoreSegment>,
+        public detail::MaxHistorySizeParent<CoreSegment>
+    {
+        using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>;
+
+    public:
+
+        using Base::CoreSegmentBase;
+
+        // ToDo: Replace by runLocked()
+        std::mutex& mutex() const;
+
+
+        // Non-locking interface
+
+        std::optional<wm::EntitySnapshot> getLatestEntitySnapshot(
+            const MemoryID& entityID) const;
+        std::optional<wm::EntityInstance> getLatestEntityInstance(
+            const MemoryID& entityID, int instanceIndex = 0) const;
+        armarx::aron::datanavigator::DictNavigatorPtr getLatestEntityInstanceData(
+            const MemoryID& entityID, int instanceIndex = 0) const;
+
+
+        template <class AronDtoT>
+        std::optional<AronDtoT> getLatestEntityInstanceDataAs(
+            const MemoryID& entityID, int instanceIndex = 0) const
+        {
+            wm::EntityInstanceDataPtr data = getLatestEntityInstanceData(entityID, instanceIndex);
+            if (data)
+            {
+                AronDtoT aron;
+                aron.fromAron(data);
+                return aron;
+            }
+            else
+            {
+                return std::nullopt;
+            }
+        }
+
+
+        /// @see base::CoreSegmentBase::addProviderSegment()
+        using CoreSegmentBase::addProviderSegment;
+        ProviderSegment& addProviderSegment(ProviderSegment&& providerSegment);
+
+
+        // Locking interface
+
+        std::optional<wm::EntitySnapshot> getLatestEntitySnapshotLocking(
+            const MemoryID& entityID) const;
+        std::optional<wm::EntityInstance> getLatestEntityInstanceLocking(
+            const MemoryID& entityID, int instanceIndex = 0) const;
+        armarx::aron::datanavigator::DictNavigatorPtr getLatestEntityInstanceDataLocking(
+            const MemoryID& entityID, int instanceIndex = 0) const;
+
+
+        template <class AronDtoT>
+        std::optional<AronDtoT> getLatestEntityInstanceDataLockingAs(
+            const MemoryID& entityID, int instanceIndex = 0) const
+        {
+            // Keep lock to a minimum.
+            wm::EntityInstanceDataPtr data = nullptr;
+            {
+                std::scoped_lock lock(_mutex);
+                data = getLatestEntityInstanceData(entityID, instanceIndex);
+            }
+            if (data)
+            {
+                AronDtoT aron;
+                aron.fromAron(data);
+                return aron;
+            }
+            else
+            {
+                return std::nullopt;
+            }
+        }
+
+
+    protected:
+
+        mutable std::mutex _mutex;
+
+    };
+
+
+
+    /// @see base::MemoryBase
+    class Memory :
+        public base::MemoryBase<CoreSegment, Memory>
+    {
+        using Base = base::MemoryBase<CoreSegment, Memory>;
+
+    public:
+
+        using Base::MemoryBase;
+
+
+        /**
+         * @brief Perform the commit, locking the core segments.
+         *
+         * Groups the commits by core segment, and updates each core segment
+         * in a batch, locking the core segment.
+         */
+        std::vector<Base::UpdateResult> updateLocking(const Commit& commit);
+
+        /**
+         * @brief Update the memory, locking the updated core segment.
+         */
+        Base::UpdateResult updateLocking(const EntityUpdate& update);
+
+    };
+
+}
+
diff --git a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
index 0e51493955af7e917e4cd2ef533f0872b4b7488d..376f2ec680f92e64a5c72b496543749a303e8cc1 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
@@ -27,6 +27,7 @@
 #include <RobotAPI/Test.h>
 
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
 #include <RobotAPI/libraries/armem/core/diskmemory/Memory.h>
 #include <RobotAPI/libraries/armem/core/error.h>
@@ -701,7 +702,7 @@ BOOST_AUTO_TEST_CASE(test_segment_setup)
 
 BOOST_AUTO_TEST_CASE(test_history_size_in_entity)
 {
-    armem::wm::Entity entity("entity");
+    armem::server::wm::Entity entity("entity");
 
     armem::EntityUpdate update;
     update.entityID.entityName = entity.name();
@@ -744,7 +745,7 @@ BOOST_AUTO_TEST_CASE(test_history_size_in_entity)
 
 BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment)
 {
-    armem::wm::ProviderSegment providerSegment("SomeRGBImageProvider");
+    armem::server::wm::ProviderSegment providerSegment("SomeRGBImageProvider");
 
     armem::EntityUpdate update;
     update.entityID.providerSegmentName = providerSegment.name();
diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
index 32795093a9c602e694a580b962279891f2062d50..656842b3dcd23d49a84a51a04fc02143c14cada2 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
@@ -26,9 +26,9 @@
 
 #include <RobotAPI/Test.h>
 #include <RobotAPI/interface/armem/query.h>
-#include <RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h>
 #include <RobotAPI/libraries/armem/core/error.h>
 #include <RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.h>
+#include <RobotAPI/libraries/armem/server/query_proc/wm.h>
 
 #include <SimoxUtility/algorithm/get_map_keys_values.h>
 #include <SimoxUtility/algorithm/string.h>
@@ -39,7 +39,7 @@
 namespace armem = armarx::armem;
 namespace aron = armarx::aron;
 namespace query = armarx::armem::query::data;
-using EntityQueryProcessor = armarx::armem::wm::query_proc::EntityQueryProcessor;
+using EntityQueryProcessor = armarx::armem::server::query_proc::wm::EntityQueryProcessor;
 
 
 namespace ArMemQueryTest
@@ -53,7 +53,7 @@ namespace ArMemQueryTest
     {
         armem::wm::Entity entity;
 
-        armem::wm::query_proc::EntityQueryProcessor processor;
+        armem::server::query_proc::wm::EntityQueryProcessor processor;
 
         std::vector<armem::wm::Entity> results;
 
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
index bc63d69b96701b226b10c83d3b28eca3a7ea154c..5e5431e41aa6a94ba8616247ec19a5529ca9927e 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
@@ -5,8 +5,8 @@
 
 #include <RobotAPI/libraries/armem/core/diskmemory/Memory.h>
 
-#include <RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h>
-#include <RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h>
+#include <RobotAPI/libraries/armem/server/query_proc/diskmemory.h>
+#include <RobotAPI/libraries/armem/server/query_proc/wm.h>
 
 #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h>
 
@@ -243,7 +243,7 @@ namespace armarx::armem::gui
 
                         input.addQueryTargetToAll(armem::query::data::QueryTarget::LTM); // We use LTM as query target for the disk
 
-                        armem::d_ltm::query_proc::MemoryQueryProcessor d_ltm_processor;
+                        armem::server::query_proc::d_ltm::MemoryQueryProcessor d_ltm_processor;
                         dMem = d_ltm_processor.process(input.toIce(), dMem);
 
                         wm::Memory converted = dMem.convert();
@@ -302,7 +302,7 @@ namespace armarx::armem::gui
         std::stringstream ss;
         auto now = std::chrono::system_clock::now();
         auto in_time_t = std::chrono::system_clock::to_time_t(now);
-        ss << "Last update: " << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
+        ss << "Last update: " ;// << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
 
         if (dataChanged)
         {
diff --git a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp
index 67ffed4ba2e37812dc40a31a8534f1119b384282..5860b2f48f9659c7ac631e1270425f112a0efcab 100644
--- a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp
@@ -1,8 +1,3 @@
-// STD / STL
-#include <iostream>
-#include <fstream>
-#include <sstream>
-
 // BaseClass
 #include "Segment.h"
 
@@ -11,10 +6,16 @@
 
 #include <RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 
 #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
 #include <ArmarXCore/core/application/properties/ProxyPropertyDefinition.h>
 
+// STD / STL
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
 
 namespace armarx::armem::server::motions::mdb
 {
diff --git a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp
index 365958be88ce336c2404b1af157940cd27b5acf9..2ddcc827d80c0700f59cb5f9ee8638322f4e5633 100644
--- a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp
@@ -3,14 +3,15 @@
 #include <sstream>
 
 #include <ArmarXCore/core/time/TimeUtil.h>
-#include "ArmarXCore/core/logging/Logging.h"
-#include <ArmarXCore/core/application/properties/forward_declarations.h>
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
+#include <ArmarXCore/core/application/properties/PluginAll.h>
 
-#include "RobotAPI/libraries/armem/util/util.h"
-#include "RobotAPI/libraries/aron/common/aron_conversions.h"
+#include <RobotAPI/libraries/armem/util/util.h>
+#include <RobotAPI/libraries/aron/common/aron_conversions.h>
 
 #include <RobotAPI/libraries/armem/core/aron_conversions.h>
-#include "RobotAPI/libraries/armem/core/MemoryID.h"
+#include <RobotAPI/libraries/armem/core/MemoryID.h>
 #include <RobotAPI/libraries/armem/client/Writer.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
@@ -49,34 +50,32 @@ namespace armarx::armem::server::obj::attachments
     {
     }
 
-    std::vector<armarx::armem::attachment::ObjectAttachment> Segment::getAttachments(const armem::Time& timestamp) const
+    std::vector<armarx::armem::attachment::ObjectAttachment>
+    Segment::getAttachments(const armem::Time& timestamp) const
     {
         ARMARX_CHECK_NOT_NULL(coreSegment);
         std::scoped_lock(coreSegment->mutex());
 
         std::vector<armarx::armem::attachment::ObjectAttachment> attachments;
-
-        for (const auto& [_, provSeg] : *coreSegment)
+        coreSegment->forEachEntity([this, &attachments](const wm::Entity & entity)
         {
-            for (const auto& [name, entity] :  provSeg.entities())
-            {
-                const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
-                const auto aronAttachment = tryCast<armarx::armem::arondto::attachment::ObjectAttachment>(entityInstance);
+            const wm::EntityInstance& entityInstance = entity.getLatestSnapshot().getInstance(0);
 
-                if (not aronAttachment)
-                {
-                    ARMARX_WARNING << "Could not convert entity instance to 'ObjectAttachment'";
-                    continue;
-                }
+            const auto aronAttachment = tryCast<armarx::armem::arondto::attachment::ObjectAttachment>(entityInstance);
+            if (not aronAttachment)
+            {
+                ARMARX_WARNING << "Could not convert entity instance to 'ObjectAttachment'";
+                return true;
+            }
 
-                ARMARX_DEBUG << "Key is " << armem::MemoryID(entity.id());
+            ARMARX_DEBUG << "Key is " << armem::MemoryID(entity.id());
 
-                armarx::armem::attachment::ObjectAttachment attachment;
-                fromAron(*aronAttachment, attachment);
+            armarx::armem::attachment::ObjectAttachment attachment;
+            fromAron(*aronAttachment, attachment);
 
-                attachments.push_back(attachment);
-            }
-        }
+            attachments.push_back(attachment);
+            return true;
+        });
 
         return attachments;
     }
diff --git a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h
index 0b9302d93390c473b87c67066bfe173237f3774b..4f8cd20ccd9a0ce456bb664f5f5eb8a25f1981e0 100644
--- a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h
@@ -21,41 +21,19 @@
 
 #pragma once
 
-#include <string>
-#include <optional>
-#include <mutex>
-#include <unordered_map>
+#include <RobotAPI/libraries/armem/core/Time.h>
+#include <RobotAPI/libraries/armem/core/forward_declarations.h>
+#include <RobotAPI/libraries/armem/server/forward_declarations.h>
+#include <RobotAPI/libraries/armem_objects/types.h>
 
-#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/application/properties/forward_declarations.h>
+#include <ArmarXCore/core/logging/Logging.h>
 
-// #include "ArmarXGui/libraries/RemoteGui/Client/Widgets.h"
-
-#include "RobotAPI/components/ArViz/Client/Client.h"
-
-#include "RobotAPI/libraries/armem/core/MemoryID.h"
-#include "RobotAPI/libraries/armem/core/Time.h"
-#include "RobotAPI/libraries/armem_objects/types.h"
-
-
-namespace armarx::armem
-{
-    namespace server
-    {
-        class MemoryToIceAdapter;
-    }
-
-    namespace wm
-    {
-        class CoreSegment;
-    }
-}  // namespace armarx::armem
+#include <string>
 
 
 namespace armarx::armem::server::obj::attachments
 {
-    class Visu;
-
 
     class Segment : public armarx::Logging
     {
diff --git a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp
index 35ce3d1cf113183ea60489a522048caa8058645e..1e9957aff7b0d093d3bd1d6e16f289d6a2a04afd 100644
--- a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.cpp
@@ -1,6 +1,7 @@
 #include "FloorVis.h"
 
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem_objects/aron/ObjectClass.aron.generated.h>
 
 #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h>
@@ -13,16 +14,19 @@ namespace armarx::armem::server::obj::clazz
     {
     }
 
+
     void FloorVis::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
     {
         properties.define(defs, prefix);
     }
 
+
     void FloorVis::setArViz(armarx::viz::Client arviz)
     {
         this->arviz = arviz;
     }
 
+
     void FloorVis::updateFloorObject(const wm::CoreSegment& classCoreSegment)
     {
         viz::Layer layer = arviz.layer(properties.layerName);
@@ -42,6 +46,7 @@ namespace armarx::armem::server::obj::clazz
         arviz.commit(layer);
     }
 
+
     armarx::viz::Object FloorVis::makeFloorObject(const wm::Entity& classEntity)
     {
         const wm::EntityInstance& instance = classEntity.getLatestSnapshot().getInstance(0);
@@ -50,6 +55,7 @@ namespace armarx::armem::server::obj::clazz
         return makeFloorObject(classEntity.name(), data);
     }
 
+
     armarx::viz::Object FloorVis::makeFloorObject(
         const std::string& name,
         const arondto::ObjectClass& objectClass)
@@ -61,7 +67,6 @@ namespace armarx::armem::server::obj::clazz
     }
 
 
-
     void FloorVis::Properties::define(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
     {
         defs->optional(show, prefix + "Show", "Whether to show the floor.");
diff --git a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h
index dcce63977438bdd0d646b50aa8e5dd9679354df8..49f8a6ddd71f5c24172ddfbbfd8e312dcea2fd3f 100644
--- a/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h
+++ b/source/RobotAPI/libraries/armem_objects/server/class/FloorVis.h
@@ -10,7 +10,7 @@ namespace armarx
 {
     using PropertyDefinitionsPtr = IceUtil::Handle<class PropertyDefinitionContainer>;
 }
-namespace armarx::armem::wm
+namespace armarx::armem::server::wm
 {
     class CoreSegment;
     class Entity;
diff --git a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp
index 22608257c1abcf39340643870b704c2dadfcd54d..cd10a49c91957e5fa86094597c7903f76fb04c13 100644
--- a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp
@@ -285,16 +285,13 @@ namespace armarx::armem::server::obj::clazz
 
         showComboBox = {};
         showOptionsIndex.clear();
-        for (const auto& [_, prov] : *segment.coreSegment)
+        segment.coreSegment->forEachEntity([this](const wm::Entity & entity)
         {
-            for (const auto& [_, entity] : prov)
-            {
-                std::stringstream option;
-                option << entity.id().entityName << " (" << entity.id().providerSegmentName << ")";
-                showComboBox.addOption(option.str());
-                showOptionsIndex.push_back(entity.id());
-            }
-        }
+            std::stringstream option;
+            option << entity.id().entityName << " (" << entity.id().providerSegmentName << ")";
+            showComboBox.addOption(option.str());
+            showOptionsIndex.push_back(entity.id());
+        });
         if (showOptionsIndex.empty())
         {
             showComboBox.addOption("<none>");
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
index e1826b2b2e3556734b3224d2cb3cc112cab755c4..d6d224fe0580e4aa73656515a671ba5753e33326 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
@@ -25,8 +25,9 @@
 #include <RobotAPI/libraries/core/FramedPose.h>
 #include <RobotAPI/libraries/core/remoterobot/RemoteRobot.h>
 
-#include <ArmarXCore/core/time/TimeUtil.h>
+#include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/system/cmake/CMakePackageFinder.h>
+#include <ArmarXCore/core/time/TimeUtil.h>
 
 #include <SimoxUtility/algorithm/get_map_keys_values.h>
 #include <SimoxUtility/json.h>
@@ -142,7 +143,7 @@ namespace armarx::armem::server::obj::instance
 
             // Check whether we have an old snapshot for this object.
             std::optional<objpose::ObjectPose> previousPose;
-            const armem::wm::Entity* entity = findObjectEntity(armarx::fromIce(provided.objectID), providerName);
+            const wm::Entity* entity = findObjectEntity(armarx::fromIce(provided.objectID), providerName);
             if (entity)
             {
                 const arondto::ObjectInstance data = getLatestInstanceData(*entity);
@@ -249,21 +250,24 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    wm::CoreSegment& Segment::getCoreSegment()
+    wm::CoreSegment&
+    Segment::getCoreSegment()
     {
         ARMARX_CHECK_NOT_NULL(coreSegment);
         return *coreSegment;
     }
 
 
-    const wm::CoreSegment& Segment::getCoreSegment() const
+    const wm::CoreSegment&
+    Segment::getCoreSegment() const
     {
         ARMARX_CHECK_NOT_NULL(coreSegment);
         return *coreSegment;
     }
 
 
-    objpose::ObjectPoseMap Segment::getObjectPoses(IceUtil::Time now)
+    objpose::ObjectPoseMap
+    Segment::getObjectPoses(IceUtil::Time now)
     {
         ObjectPoseMap objectPoses = getLatestObjectPoses();
         updateObjectPoses(objectPoses, now);
@@ -272,7 +276,8 @@ namespace armarx::armem::server::obj::instance
 
 
 
-    objpose::ObjectPoseMap Segment::getObjectPosesByProvider(
+    objpose::ObjectPoseMap
+    Segment::getObjectPosesByProvider(
         const std::string& providerName,
         IceUtil::Time now)
     {
@@ -283,13 +288,14 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    armem::wm::Entity* Segment::findObjectEntity(const ObjectID& objectID, const std::string& providerName)
+    wm::Entity*
+    Segment::findObjectEntity(const ObjectID& objectID, const std::string& providerName)
     {
         ARMARX_CHECK_NOT_NULL(coreSegment);
         armem::MemoryID entityID = armem::MemoryID().withEntityName(objectID.str());
         if (providerName.empty())
         {
-            armem::wm::Entity* result = nullptr;
+            wm::Entity* result = nullptr;
             coreSegment->forEachProviderSegment([&result, &entityID](wm::ProviderSegment & prov)
             {
                 if (prov.hasEntity(entityID.entityName))
@@ -306,7 +312,7 @@ namespace armarx::armem::server::obj::instance
             entityID.providerSegmentName = providerName;
             if (coreSegment->hasProviderSegment(providerName))
             {
-                armem::wm::ProviderSegment& prov = coreSegment->getProviderSegment(providerName);
+                wm::ProviderSegment& prov = coreSegment->getProviderSegment(providerName);
                 return prov.hasEntity(entityID.entityName) ? &prov.getEntity(entityID) : nullptr;
             }
             else
@@ -389,14 +395,16 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    objpose::ObjectPoseMap Segment::getLatestObjectPoses() const
+    objpose::ObjectPoseMap
+    Segment::getLatestObjectPoses() const
     {
         ARMARX_CHECK_NOT_NULL(coreSegment);
         return getLatestObjectPoses(*coreSegment);
     }
 
 
-    objpose::ObjectPoseMap Segment::getLatestObjectPoses(const armem::wm::CoreSegment& coreSeg)
+    objpose::ObjectPoseMap
+    Segment::getLatestObjectPoses(const wm::CoreSegment& coreSeg)
     {
         ObjectPoseMap result;
         getLatestObjectPoses(coreSeg, result);
@@ -404,7 +412,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    objpose::ObjectPoseMap Segment::getLatestObjectPoses(const armem::wm::ProviderSegment& provSeg)
+    objpose::ObjectPoseMap
+    Segment::getLatestObjectPoses(const wm::ProviderSegment& provSeg)
     {
         ObjectPoseMap result;
         getLatestObjectPoses(provSeg, result);
@@ -412,7 +421,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    objpose::ObjectPose Segment::getLatestObjectPose(const armem::wm::Entity& entity)
+    objpose::ObjectPose
+    Segment::getLatestObjectPose(const wm::Entity& entity)
     {
         ObjectPose result;
         getLatestObjectPose(entity, result);
@@ -420,7 +430,7 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    void Segment::getLatestObjectPoses(const armem::wm::CoreSegment& coreSeg, ObjectPoseMap& out)
+    void Segment::getLatestObjectPoses(const wm::CoreSegment& coreSeg, ObjectPoseMap& out)
     {
         coreSeg.forEachProviderSegment([&out](const wm::ProviderSegment & provSegment)
         {
@@ -429,7 +439,7 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    void Segment::getLatestObjectPoses(const armem::wm::ProviderSegment& provSegment, ObjectPoseMap& out)
+    void Segment::getLatestObjectPoses(const wm::ProviderSegment& provSegment, ObjectPoseMap& out)
     {
         provSegment.forEachEntity([&out](const wm::Entity & entity)
         {
@@ -451,7 +461,7 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    void Segment::getLatestObjectPose(const armem::wm::Entity& entity, ObjectPose& out)
+    void Segment::getLatestObjectPose(const wm::Entity& entity, ObjectPose& out)
     {
         entity.getLatestSnapshot().forEachInstance([&out](const wm::EntityInstance & instance)
         {
@@ -463,13 +473,13 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    arondto::ObjectInstance Segment::getLatestInstanceData(const armem::wm::Entity& entity)
+    arondto::ObjectInstance Segment::getLatestInstanceData(const wm::Entity& entity)
     {
         ARMARX_CHECK_GREATER_EQUAL(entity.size(), 1);
-        const armem::wm::EntitySnapshot& snapshot = entity.getLatestSnapshot();
+        const wm::EntitySnapshot& snapshot = entity.getLatestSnapshot();
 
         ARMARX_CHECK_EQUAL(snapshot.size(), 1);
-        const armem::wm::EntityInstance& instance = snapshot.getInstance(0);
+        const wm::EntityInstance& instance = snapshot.getInstance(0);
 
         arondto::ObjectInstance data;
         data.fromAron(instance.data());
@@ -478,7 +488,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    ::armarx::armem::articulated_object::ArticulatedObjects Segment::getArticulatedObjects()
+    ::armarx::armem::articulated_object::ArticulatedObjects
+    Segment::getArticulatedObjects()
     {
         objpose::ObjectPoseMap objectPoses = getObjectPoses(IceUtil::Time::now());
 
@@ -591,7 +602,7 @@ namespace armarx::armem::server::obj::instance
 
 
         // Find object pose (provider name can be empty).
-        armem::wm::Entity* objectEntity = this->findObjectEntity(objectID, input.providerName);
+        wm::Entity* objectEntity = this->findObjectEntity(objectID, input.providerName);
         if (!objectEntity || objectEntity->empty())
         {
             ARMARX_WARNING << "Tried to attach object " << objectID << " to node '" << frameName
@@ -652,7 +663,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    objpose::DetachObjectFromRobotNodeOutput Segment::detachObjectFromRobotNode(
+    objpose::DetachObjectFromRobotNodeOutput
+    Segment::detachObjectFromRobotNode(
         const objpose::DetachObjectFromRobotNodeInput& input)
     {
         const armem::Time now = armem::Time::now();
@@ -664,7 +676,7 @@ namespace armarx::armem::server::obj::instance
         {
             // Remove from latest pose (if it was cached).
             // Find object pose (provider name can be empty).
-            armem::wm::Entity* entity = this->findObjectEntity(objectID, input.providerName);
+            wm::Entity* entity = this->findObjectEntity(objectID, input.providerName);
             if (entity)
             {
                 const arondto::ObjectInstance data = getLatestInstanceData(*entity);
@@ -699,7 +711,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    objpose::DetachAllObjectsFromRobotNodesOutput Segment::detachAllObjectsFromRobotNodes(
+    objpose::DetachAllObjectsFromRobotNodesOutput
+    Segment::detachAllObjectsFromRobotNodes(
         const objpose::DetachAllObjectsFromRobotNodesInput& input)
     {
         ARMARX_CHECK_NOT_NULL(coreSegment);
@@ -726,9 +739,9 @@ namespace armarx::armem::server::obj::instance
 
 
     void Segment::storeDetachedSnapshot(
-        armem::wm::Entity& entity,
+        wm::Entity& entity,
         const arondto::ObjectInstance& data,
-        armem::Time now,
+        Time now,
         bool commitAttachedPose)
     {
         armem::EntityUpdate update;
@@ -760,7 +773,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    std::optional<wm::EntityInstance> Segment::findClassInstance(const ObjectID& objectID) const
+    std::optional<wm::EntityInstance>
+    Segment::findClassInstance(const ObjectID& objectID) const
     {
         const ObjectID classID = { objectID.dataset(), objectID.className() };
         try
@@ -810,7 +824,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    std::optional<armem::obj::SceneSnapshot> Segment::loadScene(const std::string& filename)
+    std::optional<armem::obj::SceneSnapshot>
+    Segment::loadScene(const std::string& filename)
     {
         if (const std::optional<std::filesystem::path> path = resolveSceneFilename(filename))
         {
@@ -823,7 +838,8 @@ namespace armarx::armem::server::obj::instance
     }
 
 
-    std::optional<armem::obj::SceneSnapshot> Segment::loadScene(const std::filesystem::path& path)
+    std::optional<armem::obj::SceneSnapshot>
+    Segment::loadScene(const std::filesystem::path& path)
     {
         ARMARX_INFO << "Loading scene snapshot from: \n" << path;
         nlohmann::json j;
@@ -845,7 +861,8 @@ namespace armarx::armem::server::obj::instance
     const std::string Segment::timestampPlaceholder = "%TIMESTAMP";
 
 
-    std::optional<std::filesystem::path> Segment::resolveSceneFilename(const std::string& _filename)
+    std::optional<std::filesystem::path>
+    Segment::resolveSceneFilename(const std::string& _filename)
     {
         std::string filename = _filename;
 
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
index f6ba671898adbae4fb84db127e17bfb6ed0fbaed..27ffbc746af05451b5fdd54f15a3afc4c7822e08 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
@@ -8,8 +8,6 @@
 #include <SimoxUtility/caching/CacheMap.h>
 #include <SimoxUtility/shapes/OrientedBox.h>
 
-#include <ArmarXCore/core/logging/Logging.h>
-
 #include <RobotAPI/interface/core/RobotState.h>
 #include <RobotAPI/interface/objectpose/ObjectPoseStorageInterface.h>
 
@@ -19,7 +17,7 @@
 #include <RobotAPI/libraries/ArmarXObjects/ObjectPose.h>
 #include <RobotAPI/libraries/ArmarXObjects/ObjectFinder.h>
 
-#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/server/segment/SpecializedSegment.h>
 
 #include "ArticulatedObjectVisu.h"
diff --git a/source/RobotAPI/libraries/armem_objects/types.h b/source/RobotAPI/libraries/armem_objects/types.h
index 976f438e7c39009fd5d37fb6afdf19378da488c4..5ca91ff285e5fc92d1d3523a504379d582dda8b5 100644
--- a/source/RobotAPI/libraries/armem_objects/types.h
+++ b/source/RobotAPI/libraries/armem_objects/types.h
@@ -21,13 +21,11 @@
 
 #pragma once
 
-#include "RobotAPI/libraries/armem/core/Time.h"
-#include <vector>
-
 #include <Eigen/Geometry>
 
-#include <RobotAPI/libraries/armem_robot/types.h>
 #include <RobotAPI/libraries/armem/core/MemoryID.h>
+#include <RobotAPI/libraries/armem/core/Time.h>
+#include <RobotAPI/libraries/armem_robot/types.h>
 
 
 namespace armarx::armem::attachment
@@ -97,4 +95,4 @@ namespace armarx::armem::articulated_object
 
     using ArticulatedObject  = armarx::armem::robot::Robot;
     using ArticulatedObjects = armarx::armem::robot::Robots;
-} // namespace armarx::armem::articulated_object
\ No newline at end of file
+} // namespace armarx::armem::articulated_object
diff --git a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp
index 7990703b1bb8bd1c533e9d01f427d905f4b1eedd..18b84d7c665c593369b4bd15dd5505d5c5fa88d1 100644
--- a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp
@@ -2,7 +2,6 @@
 
 #include <SimoxUtility/algorithm/get_map_keys_values.h>
 #include <SimoxUtility/algorithm/string/string_tools.h>
-#include <SimoxUtility/color/cmaps.h>
 #include <SimoxUtility/math/pose/interpolate.h>
 
 #include <ArmarXCore/core/exceptions/LocalException.h>
@@ -10,8 +9,10 @@
 
 #include <RobotAPI/libraries/aron/common/aron_conversions.h>
 
+#include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem/core/error/ArMemError.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+#include <RobotAPI/libraries/armem/server/wm/memory_definitions.h>
 
 #include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot_state/aron_conversions.h>
@@ -20,86 +21,100 @@
 namespace armarx::armem::common::robot_state::localization
 {
 
-    TransformChainResult TransformHelper::lookupTransformChain(const armem::wm::CoreSegment& localizationCoreSegment,
-            const TransformQuery& query)
+    template <class ...Args>
+    TransformResult
+    TransformHelper::_lookupTransform(
+        const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+        const TransformQuery& query)
     {
-        const std::vector<std::string> tfChain =
-            buildTransformChain(localizationCoreSegment, query);
-
+        const std::vector<std::string> tfChain = _buildTransformChain(localizationCoreSegment, query);
         if (tfChain.empty())
         {
-            return {.header = query.header,
-                    .transforms    = std::vector<Eigen::Affine3f>{},
-                    .status       = TransformChainResult::Status::ErrorFrameNotAvailable,
+            return {.transform    = {.header = query.header},
+                    .status       = TransformResult::Status::ErrorFrameNotAvailable,
                     .errorMessage = "Cannot create tf lookup chain '" +
                                     query.header.parentFrame + " -> " + query.header.frame +
                                     "'"};
         }
 
-        const std::vector<Eigen::Affine3f> transforms = obtainTransforms(
+        const std::vector<Eigen::Affine3f> transforms = _obtainTransforms(
                     localizationCoreSegment, tfChain, query.header.agent, query.header.timestamp);
-
         if (transforms.empty())
         {
             ARMARX_WARNING << deactivateSpam(1) << "No transform available.";
-            return {.header = query.header,
-                    .transforms    = {},
-                    .status       = TransformChainResult::Status::ErrorFrameNotAvailable,
+            return {.transform    = {.header = query.header},
+                    .status       = TransformResult::Status::ErrorFrameNotAvailable,
                     .errorMessage = "Error in TF loookup:  '" + query.header.parentFrame +
                                     " -> " + query.header.frame +
                                     "'. No memory data in time range."};
         }
 
+        const Eigen::Affine3f transform = std::accumulate(transforms.begin(),
+                                          transforms.end(),
+                                          Eigen::Affine3f::Identity(),
+                                          std::multiplies<>());
 
         ARMARX_DEBUG << "Found valid transform";
 
-        return {.header = query.header,
-                .transforms = transforms,
-                .status    = TransformChainResult::Status::Success};
+        return {.transform = {.header = query.header, .transform = transform},
+                .status    = TransformResult::Status::Success};
     }
 
-    TransformResult TransformHelper::lookupTransform(const armem::wm::CoreSegment& localizationCoreSegment,
-            const TransformQuery& query)
-    {
-        const std::vector<std::string> tfChain =
-            buildTransformChain(localizationCoreSegment, query);
 
+    template <class ...Args>
+    TransformChainResult
+    TransformHelper::_lookupTransformChain(
+        const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+        const TransformQuery& query)
+    {
+        const std::vector<std::string> tfChain = _buildTransformChain(localizationCoreSegment, query);
         if (tfChain.empty())
         {
-            return {.transform    = {.header = query.header},
-                    .status       = TransformResult::Status::ErrorFrameNotAvailable,
-                    .errorMessage = "Cannot create tf lookup chain '" +
-                                    query.header.parentFrame + " -> " + query.header.frame +
-                                    "'"};
+            return
+            {
+                .header = query.header,
+                .transforms    = std::vector<Eigen::Affine3f>{},
+                .status       = TransformChainResult::Status::ErrorFrameNotAvailable,
+                .errorMessage = "Cannot create tf lookup chain '" +
+                query.header.parentFrame + " -> " + query.header.frame +
+                "'"
+            };
         }
 
-        const std::vector<Eigen::Affine3f> transforms = obtainTransforms(
+        const std::vector<Eigen::Affine3f> transforms = _obtainTransforms(
                     localizationCoreSegment, tfChain, query.header.agent, query.header.timestamp);
-
         if (transforms.empty())
         {
             ARMARX_WARNING << deactivateSpam(1) << "No transform available.";
-            return {.transform    = {.header = query.header},
-                    .status       = TransformResult::Status::ErrorFrameNotAvailable,
-                    .errorMessage = "Error in TF loookup:  '" + query.header.parentFrame +
-                                    " -> " + query.header.frame +
-                                    "'. No memory data in time range."};
+            return
+            {
+                .header = query.header,
+                .transforms    = {},
+                .status       = TransformChainResult::Status::ErrorFrameNotAvailable,
+                .errorMessage = "Error in TF loookup:  '" + query.header.parentFrame +
+                " -> " + query.header.frame +
+                "'. No memory data in time range."
+            };
         }
 
-        const Eigen::Affine3f transform = std::accumulate(transforms.begin(),
-                                          transforms.end(),
-                                          Eigen::Affine3f::Identity(),
-                                          std::multiplies<>());
 
         ARMARX_DEBUG << "Found valid transform";
 
-        return {.transform = {.header = query.header, .transform = transform},
-                .status    = TransformResult::Status::Success};
+        return
+        {
+            .header = query.header,
+            .transforms = transforms,
+            .status    = TransformChainResult::Status::Success
+        };
     }
 
+
+
+    template <class ...Args>
     std::vector<std::string>
-    TransformHelper::buildTransformChain(const armem::wm::CoreSegment& localizationCoreSegment,
-                                         const TransformQuery& query)
+    TransformHelper::_buildTransformChain(
+        const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+        const TransformQuery& query)
     {
         ARMARX_DEBUG << "Building transform chain";
 
@@ -172,8 +187,100 @@ namespace armarx::armem::common::robot_state::localization
         return chain;
     }
 
-    inline ::armarx::armem::robot_state::Transform
-    convertEntityToTransform(const armem::wm::EntityInstance& item)
+
+    template <class ...Args>
+    std::vector<Eigen::Affine3f>
+    TransformHelper::_obtainTransforms(
+        const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+        const std::vector<std::string>& tfChain,
+        const std::string& agent,
+        const armem::Time& timestamp)
+    {
+        const auto& agentProviderSegment = localizationCoreSegment.getProviderSegment(agent);
+
+        ARMARX_DEBUG << "Provider segments" << localizationCoreSegment.getProviderSegmentNames();
+        ARMARX_DEBUG << "Entities: " << agentProviderSegment.getEntityNames();
+
+        try
+        {
+            std::vector<Eigen::Affine3f> transforms;
+            transforms.reserve(tfChain.size());
+            std::transform(tfChain.begin(),
+                           tfChain.end(),
+                           std::back_inserter(transforms),
+                           [&](const std::string & entityName)
+            {
+                return _obtainTransform(entityName, agentProviderSegment, timestamp);
+            });
+            return transforms;
+        }
+        catch (const armem::error::MissingEntry& missingEntryError)
+        {
+            ARMARX_WARNING << missingEntryError.what();
+        }
+        catch (const ::armarx::exceptions::local::ExpressionException& ex)
+        {
+            ARMARX_WARNING << "local exception: " << ex.what();
+        }
+        catch (...)
+        {
+            ARMARX_WARNING << "Error: " << GetHandledExceptionString();
+        }
+
+        return {};
+    }
+
+
+    template <class ...Args>
+    Eigen::Affine3f
+    TransformHelper::_obtainTransform(
+        const std::string& entityName,
+        const armem::base::ProviderSegmentBase<Args...>& agentProviderSegment,
+        const armem::Time& timestamp)
+    {
+        ARMARX_DEBUG << "getEntity:" + entityName;
+        const auto& entity = agentProviderSegment.getEntity(entityName);
+
+        ARMARX_DEBUG << "History (size: " << entity.size() << "): " << entity.getTimestamps();
+
+        // if (entity.history.empty())
+        // {
+        //     // TODO(fabian.reister): fixme boom
+        //     ARMARX_ERROR << "No snapshots received.";
+        //     return Eigen::Affine3f::Identity();
+        // }
+
+        std::vector<::armarx::armem::robot_state::Transform> transforms;
+        transforms.push_back(_convertEntityToTransform(entity.getLatestSnapshot().getInstance(0)));
+
+        ARMARX_DEBUG << "obtaining transform";
+        if (transforms.size() > 1)
+        {
+            // TODO(fabian.reister): remove
+            return transforms.front().transform;
+
+            ARMARX_DEBUG << "More than one snapshots received: " << transforms.size();
+            const auto p = _interpolateTransform(transforms, timestamp);
+            ARMARX_DEBUG << "Done interpolating transform";
+            return p;
+        }
+
+        // accept this to fail (will raise armem::error::MissingEntry)
+        if (transforms.empty())
+        {
+            ARMARX_DEBUG << "empty transform";
+
+            throw armem::error::MissingEntry("foo", "bar", "foo2", "bar2", 0);
+        }
+
+        ARMARX_DEBUG << "single transform";
+
+        return transforms.front().transform;
+    }
+
+
+    ::armarx::armem::robot_state::Transform
+    TransformHelper::_convertEntityToTransform(const armem::wm::EntityInstance& item)
     {
         arondto::Transform aronTransform;
         aronTransform.fromAron(item.data());
@@ -211,8 +318,9 @@ namespace armarx::armem::common::robot_state::localization
     }
 
     Eigen::Affine3f
-    interpolateTransform(const std::vector<::armarx::armem::robot_state::Transform>& queue,
-                         armem::Time timestamp)
+    TransformHelper::_interpolateTransform(
+        const std::vector<::armarx::armem::robot_state::Transform>& queue,
+        armem::Time timestamp)
     {
         ARMARX_TRACE;
 
@@ -255,109 +363,33 @@ namespace armarx::armem::common::robot_state::localization
         return simox::math::interpolatePose(posePreIt->transform, poseNextIt->transform, static_cast<float>(t));
     }
 
-    std::vector<Eigen::Affine3f>
-    TransformHelper::obtainTransforms(const armem::wm::CoreSegment& localizationCoreSegment,
-                                      const std::vector<std::string>& tfChain,
-                                      const std::string& agent,
-                                      const armem::Time& timestamp)
-    {
-        const auto& agentProviderSegment = localizationCoreSegment.getProviderSegment(agent);
-
-        ARMARX_DEBUG << "Provider segments"
-                     << simox::alg::get_keys(localizationCoreSegment.providerSegments());
-
-        ARMARX_DEBUG << "Entities: " << simox::alg::get_keys(agentProviderSegment.entities());
-
-        try
-        {
-            std::vector<Eigen::Affine3f> transforms;
-            transforms.reserve(tfChain.size());
-            std::transform(tfChain.begin(),
-                           tfChain.end(),
-                           std::back_inserter(transforms),
-                           [&](const std::string & entityName)
-            {
-                return obtainTransform(
-                           entityName, agentProviderSegment, timestamp);
-            });
-            return transforms;
-        }
-        catch (const armem::error::MissingEntry& missingEntryError)
-        {
-            ARMARX_WARNING << missingEntryError.what();
-        }
-        catch (const ::armarx::exceptions::local::ExpressionException& ex)
-        {
-            ARMARX_WARNING << "local exception: " << ex.what();
-        }
-        catch (...)
-        {
-            ARMARX_WARNING << "Error: " << GetHandledExceptionString();
-        }
-
-
 
-        return {};
+    TransformResult TransformHelper::lookupTransform(
+        const armem::wm::CoreSegment& localizationCoreSegment,
+        const TransformQuery& query)
+    {
+        return _lookupTransform(localizationCoreSegment, query);
     }
-
-    Eigen::Affine3f
-    TransformHelper::obtainTransform(const std::string& entityName,
-                                     const armem::wm::ProviderSegment& agentProviderSegment,
-                                     const armem::Time& timestamp)
+    TransformResult TransformHelper::lookupTransform(
+        const armem::server::wm::CoreSegment& localizationCoreSegment,
+        const TransformQuery& query)
     {
+        return _lookupTransform(localizationCoreSegment, query);
+    }
 
-        ARMARX_DEBUG << "getEntity:" + entityName;
-        const auto& entity = agentProviderSegment.getEntity(entityName);
-
-        ARMARX_DEBUG << "History (size: " << entity.history().size() << ")"
-                     << simox::alg::get_keys(entity.history());
-
-        // if (entity.history.empty())
-        // {
-        //     // TODO(fabian.reister): fixme boom
-        //     ARMARX_ERROR << "No snapshots received.";
-        //     return Eigen::Affine3f::Identity();
-        // }
-
-        std::vector<::armarx::armem::robot_state::Transform> transforms;
-        transforms.reserve(entity.history().size());
-
-        // const auto entitySnapshots = simox::alg::get_values(entity.history());
-
-        const std::vector<wm::EntitySnapshot> entitySnapshots = {entity.getLatestSnapshot()};
-
-        std::transform(
-            entitySnapshots.begin(),
-            entitySnapshots.end(),
-            std::back_inserter(transforms),
-            [](const auto & entitySnapshot)
-        {
-            return convertEntityToTransform(entitySnapshot.getInstance(0));
-        });
-
-        ARMARX_DEBUG << "obtaining transform";
-
-        if (transforms.size() > 1)
-        {
-            // TODO(fabian.reister): remove
-            return transforms.front().transform;
-
-            ARMARX_DEBUG << "More than one snapshots received: " << transforms.size();
-            const auto p = interpolateTransform(transforms, timestamp);
-            ARMARX_DEBUG << "Done interpolating transform";
-            return p;
-        }
 
-        // accept this to fail (will raise armem::error::MissingEntry)
-        if (transforms.empty())
-        {
-            ARMARX_DEBUG << "empty transform";
-
-            throw armem::error::MissingEntry("foo", "bar", "foo2", "bar2", 0);
-        }
+    TransformChainResult TransformHelper::lookupTransformChain(
+        const armem::wm::CoreSegment& localizationCoreSegment,
+        const TransformQuery& query)
+    {
+        return _lookupTransformChain(localizationCoreSegment, query);
+    }
+    TransformChainResult TransformHelper::lookupTransformChain(
+        const armem::server::wm::CoreSegment& localizationCoreSegment,
+        const TransformQuery& query)
+    {
+        return _lookupTransformChain(localizationCoreSegment, query);
+    }
 
-        ARMARX_DEBUG << "single transform";
 
-        return transforms.front().transform;
-    }
 } // namespace armarx::armem::common::robot_state::localization
diff --git a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h
index 0f1f20de89fa551c4e84fff8a378cc03172c52ef..9de1fbd994f5a17c00987ce70d31525db7d9d1dd 100644
--- a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h
+++ b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.h
@@ -26,45 +26,102 @@
 #include <Eigen/Core>
 #include <Eigen/Geometry>
 
+#include <RobotAPI/libraries/armem/core/forward_declarations.h>
 #include <RobotAPI/libraries/armem_robot_state/common/localization/types.h>
 
 
-namespace armarx::armem::wm
-{
-    class CoreSegment;
-    class ProviderSegment;
-} // namespace armarx::armem::wm
-
 namespace armarx::armem::common::robot_state::localization
 {
     using armarx::armem::common::robot_state::localization::TransformQuery;
     using armarx::armem::common::robot_state::localization::TransformResult;
 
+
+
     class TransformHelper
     {
     public:
-        static TransformResult
-        lookupTransform(const armem::wm::CoreSegment& localizationCoreSegment,
-                        const TransformQuery& query);
 
-        static TransformChainResult
-        lookupTransformChain(const armem::wm::CoreSegment& localizationCoreSegment,
-                             const TransformQuery& query);
+        static
+        TransformResult
+        lookupTransform(
+            const armem::wm::CoreSegment& localizationCoreSegment,
+            const TransformQuery& query);
+
+        static
+        TransformResult
+        lookupTransform(
+            const armem::server::wm::CoreSegment& localizationCoreSegment,
+            const TransformQuery& query);
+
+
+        static
+        TransformChainResult
+        lookupTransformChain(
+            const armem::wm::CoreSegment& localizationCoreSegment,
+            const TransformQuery& query);
+
+        static
+        TransformChainResult
+        lookupTransformChain(
+            const armem::server::wm::CoreSegment& localizationCoreSegment,
+            const TransformQuery& query);
+
 
     private:
-        static std::vector<std::string>
-        buildTransformChain(const armem::wm::CoreSegment& localizationCoreSegment,
-                            const TransformQuery& query);
-
-        static std::vector<Eigen::Affine3f>
-        obtainTransforms(const armem::wm::CoreSegment& localizationCoreSegment,
-                         const std::vector<std::string>& tfChain,
-                         const std::string& agent,
-                         const armem::Time& timestamp);
-
-        static Eigen::Affine3f
-        obtainTransform(const std::string& entityName,
-                        const armem::wm::ProviderSegment& agentProviderSegment,
-                        const armem::Time& timestamp);
+
+        template <class ...Args>
+        static
+        TransformResult
+        _lookupTransform(
+            const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+            const TransformQuery& query);
+
+
+        template <class ...Args>
+        static
+        TransformChainResult
+        _lookupTransformChain(
+            const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+            const TransformQuery& query);
+
+
+        template <class ...Args>
+        static
+        std::vector<std::string>
+        _buildTransformChain(
+            const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+            const TransformQuery& query);
+
+
+        template <class ...Args>
+        static
+        std::vector<Eigen::Affine3f>
+        _obtainTransforms(
+            const armem::base::CoreSegmentBase<Args...>& localizationCoreSegment,
+            const std::vector<std::string>& tfChain,
+            const std::string& agent,
+            const armem::Time& timestamp);
+
+
+        template <class ...Args>
+        static
+        Eigen::Affine3f
+        _obtainTransform(
+            const std::string& entityName,
+            const armem::base::ProviderSegmentBase<Args...>& agentProviderSegment,
+            const armem::Time& timestamp);
+
+
+        static
+        Eigen::Affine3f
+        _interpolateTransform(
+            const std::vector<::armarx::armem::robot_state::Transform>& queue,
+            armem::Time timestamp);
+
+        static
+        ::armarx::armem::robot_state::Transform
+        _convertEntityToTransform(
+            const armem::wm::EntityInstance& item);
+
     };
 } // namespace armarx::armem::common::robot_state::localization