From 527ec329612adba70b7ae51b73a518402e0866f0 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Thu, 5 Aug 2021 16:38:55 +0200
Subject: [PATCH] Merge files into memory_definitions, rename directory to
 match namespace

---
 .../RobotAPI/libraries/armem/CMakeLists.txt   |  41 ++--
 source/RobotAPI/libraries/armem/core/wm.h     |  10 +
 .../aron_conversions.cpp}                     |   0
 .../aron_conversions.h}                       |   3 +-
 .../{workingmemory => wm}/ice_conversions.cpp |   4 +-
 .../{workingmemory => wm}/ice_conversions.h   |   2 +-
 .../json_conversions.cpp                      |   0
 .../{workingmemory => wm}/json_conversions.h  |   2 +-
 .../armem/core/wm/memory_definitions.cpp      | 214 ++++++++++++++++
 .../armem/core/wm/memory_definitions.h        | 230 ++++++++++++++++++
 .../core/{workingmemory => wm}/visitor.h      |   0
 .../visitor/FunctionalVisitor.cpp             |   4 +-
 .../visitor/FunctionalVisitor.h               |   0
 .../{workingmemory => wm}/visitor/Visitor.cpp |   2 +-
 .../{workingmemory => wm}/visitor/Visitor.h   |   0
 .../armem/core/workingmemory/CoreSegment.cpp  | 115 ---------
 .../armem/core/workingmemory/CoreSegment.h    | 107 --------
 .../armem/core/workingmemory/Entity.cpp       |   8 -
 .../armem/core/workingmemory/Entity.h         |  38 ---
 .../core/workingmemory/EntityInstance.cpp     |  40 ---
 .../armem/core/workingmemory/EntityInstance.h |  37 ---
 .../core/workingmemory/EntitySnapshot.cpp     |   7 -
 .../armem/core/workingmemory/EntitySnapshot.h |  22 --
 .../armem/core/workingmemory/Memory.cpp       |  74 ------
 .../armem/core/workingmemory/Memory.h         |  38 ---
 .../core/workingmemory/ProviderSegment.cpp    |   8 -
 .../core/workingmemory/ProviderSegment.h      |  23 --
 27 files changed, 478 insertions(+), 551 deletions(-)
 create mode 100644 source/RobotAPI/libraries/armem/core/wm.h
 rename source/RobotAPI/libraries/armem/core/{workingmemory/entityInstance_conversions.cpp => wm/aron_conversions.cpp} (100%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory/entityInstance_conversions.h => wm/aron_conversions.h} (76%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/ice_conversions.cpp (95%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/ice_conversions.h (97%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/json_conversions.cpp (100%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/json_conversions.h (94%)
 create mode 100644 source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp
 create mode 100644 source/RobotAPI/libraries/armem/core/wm/memory_definitions.h
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor.h (100%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/FunctionalVisitor.cpp (82%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/FunctionalVisitor.h (100%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/Visitor.cpp (98%)
 rename source/RobotAPI/libraries/armem/core/{workingmemory => wm}/visitor/Visitor.h (100%)
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Entity.h
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h

diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 475bfbcf1..972d51e11 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -28,8 +28,8 @@ set(LIB_FILES
     core/operations.cpp
     core/SuccessHeader.cpp
     core/Time.cpp
-    core/ice_conversions.cpp
     core/aron_conversions.cpp
+    core/ice_conversions.cpp
     core/json_conversions.cpp
 
     core/base/detail/MemoryItem.cpp
@@ -47,18 +47,13 @@ set(LIB_FILES
     # core/base/MemoryBase.cpp
     # core/base/ProviderSegmentBase.cpp
 
-    core/workingmemory/ice_conversions.cpp
-    core/workingmemory/CoreSegment.cpp
-    core/workingmemory/Entity.cpp
-    core/workingmemory/EntityInstance.cpp
-    core/workingmemory/EntitySnapshot.cpp
-    core/workingmemory/Memory.cpp
-    core/workingmemory/ProviderSegment.cpp
-    core/workingmemory/ice_conversions.cpp
-    core/workingmemory/json_conversions.cpp
-    core/workingmemory/entityInstance_conversions.cpp
-    core/workingmemory/visitor/Visitor.cpp
-    core/workingmemory/visitor/FunctionalVisitor.cpp
+    core/wm/memory_definitions.cpp
+    core/wm/ice_conversions.cpp
+    core/wm/ice_conversions.cpp
+    core/wm/json_conversions.cpp
+    core/wm/aron_conversions.cpp
+    core/wm/visitor/Visitor.cpp
+    core/wm/visitor/FunctionalVisitor.cpp
 
     core/longtermmemory/CoreSegment.cpp
     core/longtermmemory/Entity.cpp
@@ -167,18 +162,14 @@ set(LIB_HEADERS
     core/base/MemoryBase.h
     core/base/ProviderSegmentBase.h
 
-    core/workingmemory/CoreSegment.h
-    core/workingmemory/Entity.h
-    core/workingmemory/EntityInstance.h
-    core/workingmemory/EntitySnapshot.h
-    core/workingmemory/Memory.h
-    core/workingmemory/ProviderSegment.h
-    core/workingmemory/ice_conversions.h
-    core/workingmemory/json_conversions.h
-    core/workingmemory/entityInstance_conversions.h
-    core/workingmemory/visitor.h
-    core/workingmemory/visitor/Visitor.h
-    core/workingmemory/visitor/FunctionalVisitor.h
+    core/wm.h
+    core/wm/memory_definitions.h
+    core/wm/aron_conversions.h
+    core/wm/ice_conversions.h
+    core/wm/json_conversions.h
+    core/wm/visitor.h
+    core/wm/visitor/Visitor.h
+    core/wm/visitor/FunctionalVisitor.h
 
     core/longtermmemory/CoreSegment.h
     core/longtermmemory/Entity.h
diff --git a/source/RobotAPI/libraries/armem/core/wm.h b/source/RobotAPI/libraries/armem/core/wm.h
new file mode 100644
index 000000000..83776ed70
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/wm.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "wm/memory_definitions.h"
+
+
+namespace armarx::armem::wm
+{
+
+}
+
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.cpp
rename to source/RobotAPI/libraries/armem/core/wm/aron_conversions.cpp
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.h b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h
similarity index 76%
rename from source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.h
rename to source/RobotAPI/libraries/armem/core/wm/aron_conversions.h
index ab9ab27c4..f40d1d757 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/entityInstance_conversions.h
+++ b/source/RobotAPI/libraries/armem/core/wm/aron_conversions.h
@@ -1,6 +1,7 @@
 #pragma once
 
-#include "EntityInstance.h"
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+
 
 namespace armarx::armem
 {
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp
similarity index 95%
rename from source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp
rename to source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp
index 8509ed5ea..a1fc88f19 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp
+++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.cpp
@@ -6,14 +6,14 @@
 
 namespace armarx::armem
 {
-    void toIce(armarx::armem::data::EntityInstanceMetadata& ice, const armarx::armem::wm::EntityInstanceMetadata& metadata)
+    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 armarx::armem::data::EntityInstanceMetadata& ice, armarx::armem::wm::EntityInstanceMetadata& metadata)
+    void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata)
     {
         metadata.confidence = ice.confidence;
         fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h
similarity index 97%
rename from source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h
rename to source/RobotAPI/libraries/armem/core/wm/ice_conversions.h
index 4d14e6b0d..d2f7ef01f 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h
+++ b/source/RobotAPI/libraries/armem/core/wm/ice_conversions.h
@@ -3,7 +3,7 @@
 #include <RobotAPI/interface/armem/commit.h>
 #include <RobotAPI/interface/armem/memory.h>
 
-#include "Memory.h"
+#include "memory_definitions.h"
 
 
 namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.cpp b/source/RobotAPI/libraries/armem/core/wm/json_conversions.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.cpp
rename to source/RobotAPI/libraries/armem/core/wm/json_conversions.cpp
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.h b/source/RobotAPI/libraries/armem/core/wm/json_conversions.h
similarity index 94%
rename from source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.h
rename to source/RobotAPI/libraries/armem/core/wm/json_conversions.h
index d132d88f7..daea55b95 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/json_conversions.h
+++ b/source/RobotAPI/libraries/armem/core/wm/json_conversions.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Memory.h"
+#include "memory_definitions.h"
 
 #include <RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h>
 #include <RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h>
diff --git a/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp
new file mode 100644
index 000000000..c200e6f68
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.cpp
@@ -0,0 +1,214 @@
+#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::wm
+{
+
+    bool EntityInstance::equalsDeep(const EntityInstance& other) const
+    {
+        if (_data and other.data())
+        {
+            return id() == other.id()
+                   && _metadata == other.metadata()
+                   && *_data == *other.data();
+        }
+        if (_data or other.data())
+        {
+            return false;
+        }
+        return id() == other.id() && _metadata == other.metadata();
+    }
+
+
+    void EntityInstance::update(const EntityUpdate& update)
+    {
+        ARMARX_CHECK_FITS_SIZE(this->index(), update.instancesData.size());
+
+        this->data() = update.instancesData.at(size_t(this->index()));
+
+        this->_metadata.confidence = update.confidence;
+
+        this->_metadata.timeCreated = update.timeCreated;
+        this->_metadata.timeSent = update.timeSent;
+        this->_metadata.timeArrived = update.timeArrived;
+    }
+
+
+    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
+    {
+        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;
+        }
+    }
+
+
+    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
new file mode 100644
index 000000000..4763944c8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/wm/memory_definitions.h
@@ -0,0 +1,230 @@
+#pragma once
+
+#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::wm
+{
+
+    using EntityInstanceMetadata = base::EntityInstanceMetadata;
+    using EntityInstanceData = armarx::aron::datanavigator::DictNavigator;
+    using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr;
+
+
+    /**
+     * @brief Data of a single entity instance.
+     */
+    class EntityInstance :
+        public base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>
+    {
+        using Base = base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>;
+
+    public:
+
+        using Base::EntityInstanceBase;
+
+
+        /**
+         * @brief Fill `*this` with the update's values.
+         * @param update The update.
+         * @param index The instances index.
+         */
+        void update(const EntityUpdate& update);
+
+        bool equalsDeep(const EntityInstance& other) const;
+
+    };
+
+
+
+    /**
+     * @brief Data of an entity at one point in time.
+     */
+    class EntitySnapshot :
+        public base::EntitySnapshotBase<EntityInstance, EntitySnapshot>
+    {
+    public:
+
+        using base::EntitySnapshotBase<EntityInstance, EntitySnapshot>::EntitySnapshotBase;
+
+    };
+
+
+
+    /**
+     * @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`.
+     */
+    class Entity :
+        public base::EntityBase<EntitySnapshot, Entity>
+    {
+    public:
+
+        using base::EntityBase<EntitySnapshot, Entity>::EntityBase;
+
+    };
+
+
+
+    /**
+     * @brief Data of a provider segment containing multiple entities.
+     */
+    class ProviderSegment :
+        public base::ProviderSegmentBase<Entity, ProviderSegment>
+    {
+    public:
+
+        using base::ProviderSegmentBase<Entity, ProviderSegment>::ProviderSegmentBase;
+
+    };
+
+
+
+    /**
+     * @brief Data of a core segment containing multiple provider segments.
+     */
+    class CoreSegment :
+        public base::CoreSegmentBase<ProviderSegment, CoreSegment>
+    {
+        using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>;
+
+    public:
+
+        using Base::CoreSegmentBase;
+
+        CoreSegment(const CoreSegment& other);
+        CoreSegment(CoreSegment&& other);
+        CoreSegment& operator=(const CoreSegment& other);
+        CoreSegment& operator=(CoreSegment&& other);
+
+        /**
+         * @brief Convert the content of this segmnet into a commit
+         * @return The resulting commit
+         */
+        Commit toCommit() const;
+
+        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;
+            }
+        }
+
+
+        // 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.
+     */
+    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/core/workingmemory/visitor.h b/source/RobotAPI/libraries/armem/core/wm/visitor.h
similarity index 100%
rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor.h
rename to source/RobotAPI/libraries/armem/core/wm/visitor.h
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.cpp b/source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.cpp
similarity index 82%
rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.cpp
rename to source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.cpp
index 53016fc6c..f72b37c1a 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.cpp
+++ b/source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.cpp
@@ -2,7 +2,7 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/error.h>
 
 
@@ -18,6 +18,4 @@ namespace armarx::armem::wm
     {
     }
 
-
-
 }
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.h b/source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.h
similarity index 100%
rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/FunctionalVisitor.h
rename to source/RobotAPI/libraries/armem/core/wm/visitor/FunctionalVisitor.h
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp b/source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.cpp
similarity index 98%
rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp
rename to source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.cpp
index 125ca569d..1140bc11b 100644
--- a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.cpp
+++ b/source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.cpp
@@ -2,7 +2,7 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/error.h>
 
 
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.h b/source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.h
similarity index 100%
rename from source/RobotAPI/libraries/armem/core/workingmemory/visitor/Visitor.h
rename to source/RobotAPI/libraries/armem/core/wm/visitor/Visitor.h
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp
deleted file mode 100644
index eb437eb16..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "CoreSegment.h"
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "error.h"
-
-
-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
-    {
-        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;
-        }
-    }
-
-
-    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);
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h
deleted file mode 100644
index 341c065a0..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#pragma once
-
-#include <mutex>
-#include <optional>
-
-#include <RobotAPI/libraries/armem/core/base/CoreSegmentBase.h>
-
-#include "ProviderSegment.h"
-
-
-namespace armarx::armem::wm
-{
-
-    /**
-     * @brief Data of a core segment containing multiple provider segments.
-     */
-    class CoreSegment :
-        public base::CoreSegmentBase<ProviderSegment, CoreSegment>
-    {
-        using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>;
-
-    public:
-
-        using Base::CoreSegmentBase;
-
-        CoreSegment(const CoreSegment& other);
-        CoreSegment(CoreSegment&& other);
-        CoreSegment& operator=(const CoreSegment& other);
-        CoreSegment& operator=(CoreSegment&& other);
-
-        /**
-         * @brief Convert the content of this segmnet into a commit
-         * @return The resulting commit
-         */
-        Commit toCommit() const;
-
-        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;
-            }
-        }
-
-
-        // 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;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp
deleted file mode 100644
index e212c0d36..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "Entity.h"
-
-
-namespace armarx::armem::wm
-{
-
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h
deleted file mode 100644
index 34e9b2abd..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/base/EntityBase.h>
-
-#include "EntitySnapshot.h"
-
-
-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`.
-     */
-    class Entity :
-        public base::EntityBase<EntitySnapshot, Entity>
-    {
-    public:
-
-        using base::EntityBase<EntitySnapshot, Entity>::EntityBase;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp
deleted file mode 100644
index 8cda21f29..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "EntityInstance.h"
-
-#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-
-namespace armarx::armem::wm
-{
-
-    bool EntityInstance::equalsDeep(const EntityInstance& other) const
-    {
-        if (_data and other.data())
-        {
-            return id() == other.id()
-                   && _metadata == other.metadata()
-                   && *_data == *other.data();
-        }
-        if (_data or other.data())
-        {
-            return false;
-        }
-        return id() == other.id() && _metadata == other.metadata();
-    }
-
-
-    void EntityInstance::update(const EntityUpdate& update)
-    {
-        ARMARX_CHECK_FITS_SIZE(this->index(), update.instancesData.size());
-
-        this->data() = update.instancesData.at(size_t(this->index()));
-
-        this->_metadata.confidence = update.confidence;
-
-        this->_metadata.timeCreated = update.timeCreated;
-        this->_metadata.timeSent = update.timeSent;
-        this->_metadata.timeArrived = update.timeArrived;
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h
deleted file mode 100644
index 158b1c0f8..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/base/EntityInstanceBase.h>
-
-
-namespace armarx::armem::wm
-{
-
-    using EntityInstanceMetadata = base::EntityInstanceMetadata;
-    using EntityInstanceData = armarx::aron::datanavigator::DictNavigator;
-    using EntityInstanceDataPtr = armarx::aron::datanavigator::DictNavigatorPtr;
-
-
-    /**
-     * @brief Data of a single entity instance.
-     */
-    class EntityInstance :
-        public base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>
-    {
-        using Base = base::EntityInstanceBase<EntityInstanceDataPtr, EntityInstanceMetadata>;
-
-    public:
-
-        using Base::EntityInstanceBase;
-
-
-        /**
-         * @brief Fill `*this` with the update's values.
-         * @param update The update.
-         * @param index The instances index.
-         */
-        void update(const EntityUpdate& update);
-
-        bool equalsDeep(const EntityInstance& other) const;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp
deleted file mode 100644
index b5daa3192..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "EntitySnapshot.h"
-
-
-namespace armarx::armem::wm
-{
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h
deleted file mode 100644
index c19a2f830..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h>
-
-#include "EntityInstance.h"
-
-
-namespace armarx::armem::wm
-{
-
-    /**
-     * @brief Data of an entity at one point in time.
-     */
-    class EntitySnapshot :
-        public base::EntitySnapshotBase<EntityInstance, EntitySnapshot>
-    {
-    public:
-
-        using base::EntitySnapshotBase<EntityInstance, EntitySnapshot>::EntitySnapshotBase;
-
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
deleted file mode 100644
index 7bff4f19e..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-#include "Memory.h"
-
-#include <map>
-#include <vector>
-
-
-namespace armarx::armem::wm
-{
-
-    // 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/workingmemory/Memory.h b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
deleted file mode 100644
index e3684b3b6..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/base/MemoryBase.h>
-
-#include "CoreSegment.h"
-
-
-namespace armarx::armem::wm
-{
-
-    /**
-     * @brief Data of a memory consisting of multiple core segments.
-     */
-    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/core/workingmemory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp
deleted file mode 100644
index 01aa4e39b..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "ProviderSegment.h"
-
-
-namespace armarx::armem::wm
-{
-
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h
deleted file mode 100644
index 75b5d3b36..000000000
--- a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h>
-
-#include "Entity.h"
-
-
-namespace armarx::armem::wm
-{
-
-    /**
-     * @brief Data of a provider segment containing multiple entities.
-     */
-    class ProviderSegment :
-        public base::ProviderSegmentBase<Entity, ProviderSegment>
-    {
-    public:
-
-        using base::ProviderSegmentBase<Entity, ProviderSegment>::ProviderSegmentBase;
-
-    };
-
-}
-- 
GitLab