From 8f3edae2919c0ebbcc1c58c81232d0d237275014 Mon Sep 17 00:00:00 2001
From: Fabian Peller-Konrad <fabian.peller-konrad@kit.edu>
Date: Tue, 2 Nov 2021 16:52:59 +0100
Subject: [PATCH] full working ltm pipeline

---
 .../RobotAPI/libraries/armem/CMakeLists.txt   |  36 ++--
 .../armem/server/MemoryRemoteGui.cpp          |   3 +-
 .../armem/server/MemoryToIceAdapter.cpp       |   4 +-
 .../armem/server/RemoteGuiAronDataVisitor.h   |  24 +--
 .../ltm/base/converter/bson/BsonConverter.cpp |   0
 .../ltm/base/converter/bson/BsonConverter.h   |   0
 .../ltm/base/converter/dict/Converter.cpp     |   1 +
 .../ltm/base/converter/dict/Converter.h       |  35 ++++
 .../converter/dict/bson/BsonConverter.cpp     |  35 ++++
 .../base/converter/dict/bson/BsonConverter.h  |  27 +++
 .../converter/dict/json/JsonConverter.cpp     |  20 ++
 .../base/converter/dict/json/JsonConverter.h  |  24 +++
 .../ltm/base/converter/image/Converter.cpp    |   1 +
 .../ltm/base/converter/image/Converter.h      |  35 ++++
 .../base/converter/image/png/PngConverter.cpp |  25 +++
 .../base/converter/image/png/PngConverter.h   |  21 ++
 .../ltm/base/converter/json/JsonConverter.cpp |   0
 .../ltm/base/converter/json/JsonConverter.h   |   0
 .../ltm/base/detail/BufferedMemoryBase.h      |  13 +-
 .../server/ltm/base/detail/CoreSegmentBase.h  |  20 +-
 .../armem/server/ltm/base/detail/EntityBase.h |  20 +-
 .../ltm/base/detail/EntitySnapshotBase.h      |  28 ++-
 .../server/ltm/base/detail/LUTMemoryBase.h    |  10 +-
 .../armem/server/ltm/base/detail/MemoryBase.h |  44 +++-
 .../ltm/base/detail/ProviderSegmentBase.h     |  18 +-
 .../armem/server/ltm/base/encoder/Encoder.cpp |   0
 .../armem/server/ltm/base/encoder/Encoder.h   |   0
 .../ltm/base/encoder/noEncoder/NoEncoder.cpp  |   0
 .../ltm/base/encoder/noEncoder/NoEncoder.h    |   0
 .../server/ltm/base/extractor/Extractor.cpp   |   1 +
 .../server/ltm/base/extractor/Extractor.h     |  32 +++
 .../imageExtractor/ImageExtractor.cpp         |  54 +++++
 .../extractor/imageExtractor/ImageExtractor.h |  29 +++
 .../extractor/noExtractor/NoExtractor.cpp     |  17 ++
 .../base/extractor/noExtractor/NoExtractor.h  |  19 ++
 .../armem/server/ltm/base/filter/Filter.cpp   |   2 +
 .../armem/server/ltm/base/filter/Filter.h     |  23 +++
 .../frequencyFilter/FrequencyFilter.cpp       |  17 ++
 .../filter/frequencyFilter/FrequencyFilter.h  |  23 +++
 .../ltm/base/filter/noFilter/NoFilter.cpp     |   0
 .../ltm/base/filter/noFilter/NoFilter.h       |   0
 .../LRUForgetter/LRUForgetter.cpp}            |   0
 .../LRUForgetter/LRUForgetter.h}              |   0
 .../forgetter/noForgetter/NoForgetter.cpp     |   0
 .../base/forgetter/noForgetter/NoForgetter.h  |   0
 .../armem/server/ltm/disk/CoreSegment.cpp     |  15 +-
 .../armem/server/ltm/disk/CoreSegment.h       |   9 +-
 .../armem/server/ltm/disk/Entity.cpp          |  15 +-
 .../libraries/armem/server/ltm/disk/Entity.h  |   9 +-
 .../armem/server/ltm/disk/EntitySnapshot.cpp  |  84 +++++---
 .../armem/server/ltm/disk/EntitySnapshot.h    |   9 +-
 .../armem/server/ltm/disk/Memory.cpp          |  30 +--
 .../libraries/armem/server/ltm/disk/Memory.h  |  15 +-
 .../armem/server/ltm/disk/ProviderSegment.cpp |  15 +-
 .../armem/server/ltm/disk/ProviderSegment.h   |   9 +-
 .../armem/server/ltm/disk/detail/Data.h       |   6 +-
 .../ltm/detail/EntityQueryProcessorBase.h     |   6 +-
 .../armem/test/ArMemLTMBenchmark.cpp          |  21 +-
 .../armem_gui/disk/ControlWidget.cpp          |   7 +-
 .../display_visitors/DataDisplayVisitor.h     |   2 +-
 .../TypedDataDisplayVisitor.h                 |   2 +-
 .../instance/tree_visitors/TreeDataVisitor.h  |  24 +--
 .../tree_visitors/TreeTypedDataVisitor.h      |  46 ++---
 .../aron/converter/opencv/OpenCVConverter.cpp |   3 +-
 .../cpp/generator/ndarray/Image.cpp           |   4 +-
 .../nlohmannJSON/NlohmannJSONConverter.h      |   2 +-
 .../data/converter/variant/VariantConverter.h |   2 +-
 .../aron/core/data/variant/Variant.h          |  17 +-
 .../aron/core/data/variant/complex/NDArray.h  |   6 +
 .../aron/core/data/variant/container/Dict.cpp |  24 ++-
 .../aron/core/data/variant/container/Dict.h   |  14 +-
 .../aron/core/data/variant/container/List.cpp |  32 ++-
 .../aron/core/data/variant/container/List.h   |  10 +
 .../data/variant/detail/PrimitiveVariant.h    |   6 +
 .../aron/core/data/visitor/RecursiveVisitor.h | 188 +++++++++---------
 .../nlohmannJSON/NlohmannJSONVisitor.h        |   4 +-
 .../data/visitor/variant/VariantVisitor.h     |  43 +++-
 77 files changed, 993 insertions(+), 347 deletions(-)
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/bson/BsonConverter.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/bson/BsonConverter.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.h
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/json/JsonConverter.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/converter/json/JsonConverter.h
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/encoder/Encoder.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/encoder/Encoder.h
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/encoder/noEncoder/NoEncoder.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/encoder/noEncoder/NoEncoder.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.h
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.cpp
 create mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.h
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/filter/noFilter/NoFilter.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/filter/noFilter/NoFilter.h
 rename source/RobotAPI/libraries/armem/server/ltm/base/{converter/Converter.cpp => forgetter/LRUForgetter/LRUForgetter.cpp} (100%)
 rename source/RobotAPI/libraries/armem/server/ltm/base/{converter/Converter.h => forgetter/LRUForgetter/LRUForgetter.h} (100%)
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/forgetter/noForgetter/NoForgetter.cpp
 delete mode 100644 source/RobotAPI/libraries/armem/server/ltm/base/forgetter/noForgetter/NoForgetter.h

diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 784cb0460..18ddb3492 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -20,6 +20,7 @@ set(LIBS
 
     # Needed for LTM
     RobotAPI::aron::converter::json
+    RobotAPI::aron::converter::opencv
     ${LIBMONGOCXX_LIBRARIES}
     ${LIBBSONCXX_LIBRARIES}
 )
@@ -93,17 +94,20 @@ set(LIB_FILES
     server/ltm/base/detail/EntitySnapshotBase.cpp
 
     server/ltm/base/filter/Filter.cpp
-    server/ltm/base/filter/noFilter/NoFilter.cpp
+    server/ltm/base/filter/frequencyFilter/FrequencyFilter.cpp
 
-    server/ltm/base/encoder/Encoder.cpp
-    server/ltm/base/encoder/noEncoder/NoEncoder.cpp
+    server/ltm/base/extractor/Extractor.cpp
+    server/ltm/base/extractor/imageExtractor/ImageExtractor.cpp
+    server/ltm/base/extractor/noExtractor/NoExtractor.cpp
 
-    server/ltm/base/converter/Converter.cpp
-    server/ltm/base/converter/json/JsonConverter.cpp
-    server/ltm/base/converter/bson/BsonConverter.cpp
+    server/ltm/base/converter/dict/Converter.cpp
+    server/ltm/base/converter/dict/json/JsonConverter.cpp
+    server/ltm/base/converter/dict/bson/BsonConverter.cpp
+    server/ltm/base/converter/image/Converter.cpp
+    server/ltm/base/converter/image/png/PngConverter.cpp
 
     server/ltm/base/forgetter/Forgetter.cpp
-    server/ltm/base/forgetter/noForgetter/NoForgetter.cpp
+    server/ltm/base/forgetter/LRUForgetter/LRUForgetter.cpp
 
     server/ltm/disk/detail/Data.cpp
     server/ltm/disk/detail/DiskStorage.cpp
@@ -239,17 +243,21 @@ set(LIB_HEADERS
     server/ltm/base/detail/EntitySnapshotBase.h
 
     server/ltm/base/filter/Filter.h
-    server/ltm/base/filter/noFilter/NoFilter.h
+    server/ltm/base/filter/frequencyFilter/FrequencyFilter.h
 
-    server/ltm/base/encoder/Encoder.h
-    server/ltm/base/encoder/noEncoder/NoEncoder.h
+    server/ltm/base/extractor/Extractor.h
+    server/ltm/base/extractor/imageExtractor/ImageExtractor.h
+    server/ltm/base/extractor/noExtractor/NoExtractor.h
+
+    server/ltm/base/converter/dict/Converter.h
+    server/ltm/base/converter/dict/json/JsonConverter.h
+    server/ltm/base/converter/dict/bson/BsonConverter.h
+    server/ltm/base/converter/image/Converter.h
+    server/ltm/base/converter/image/png/PngConverter.h
 
-    server/ltm/base/converter/Converter.h
-    server/ltm/base/converter/json/JsonConverter.h
-    server/ltm/base/converter/bson/BsonConverter.h
 
     server/ltm/base/forgetter/Forgetter.h
-    server/ltm/base/forgetter/noForgetter/NoForgetter.h
+    server/ltm/base/forgetter/LRUForgetter/LRUForgetter.h
 
     server/ltm/disk/detail/Data.h
     server/ltm/disk/detail/DiskStorage.h
diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
index 3b4882789..8c76449e7 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
@@ -195,7 +195,8 @@ namespace armarx::armem::server
         if (instance.data())
         {
             RemoteGuiAronDataVisitor v;
-            aron::data::visitRecursive(v, "", instance.data());
+            aron::data::VariantPtr p;
+            aron::data::visitRecursive(v, instance.data(), "", p);
             group = v.result;
         }
         else
diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
index 32c8f9672..12553981e 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
@@ -251,7 +251,7 @@ namespace armarx::armem::server
         {
             ARMARX_INFO << "The LTM returned data after query";
 
-            longtermMemory->convert(ltmResult); // convert memory ==> meaning resolving references
+            longtermMemory->load(ltmResult); // convert memory ==> meaning resolving references
 
             wmResult.append(ltmResult);
             if (wmResult.empty())
@@ -326,7 +326,7 @@ namespace armarx::armem::server
         {
             armem::wm::Memory m;
             fromIce(queryResult.memory, m);
-            longtermMemory->append(m);
+            longtermMemory->store(m);
             longtermMemory->storeBuffer();
         }
 
diff --git a/source/RobotAPI/libraries/armem/server/RemoteGuiAronDataVisitor.h b/source/RobotAPI/libraries/armem/server/RemoteGuiAronDataVisitor.h
index 36c83a632..a38c3d50d 100644
--- a/source/RobotAPI/libraries/armem/server/RemoteGuiAronDataVisitor.h
+++ b/source/RobotAPI/libraries/armem/server/RemoteGuiAronDataVisitor.h
@@ -13,7 +13,7 @@ namespace armarx::armem::server
 {
 
     struct RemoteGuiAronDataVisitor :
-            public aron::data::RecursiveVariantVisitor
+            public aron::data::RecursiveConstVariantVisitor
     {
         using GroupBox = armarx::RemoteGui::Client::GroupBox;
         using GridLayout = armarx::RemoteGui::Client::GridLayout;
@@ -35,22 +35,22 @@ namespace armarx::armem::server
 
         virtual ~RemoteGuiAronDataVisitor() = default;
 
-        void visitDictOnEnter(const std::string& key, const aron::data::VariantPtr& n) override
+        void visitDictOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& n) override
         {
             ARMARX_CHECK_NOT_NULL(n);
             visitEnter(key, "dict", n->childrenSize());
         }
-        void visitDictOnExit(const std::string&, const aron::data::VariantPtr&) override
+        void visitDictOnExit(const std::string&, const aron::data::VariantPtr&, const aron::data::VariantPtr&) override
         {
             visitExit();
         }
 
-        void visitListOnEnter(const std::string& key, const aron::data::VariantPtr& n) override
+        void visitListOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& n) override
         {
             ARMARX_CHECK_NOT_NULL(n);
             visitEnter(key, "list", n->childrenSize());
         }
-        void visitListOnExit(const std::string&, const aron::data::VariantPtr&) override
+        void visitListOnExit(const std::string&, const aron::data::VariantPtr&, const aron::data::VariantPtr&) override
         {
             visitExit();
         }
@@ -59,38 +59,38 @@ namespace armarx::armem::server
         bool visitEnter(const std::string& key, const std::string& type, size_t size);
         bool visitExit();
 
-        void visitBool(const std::string& key, const aron::data::VariantPtr& b) override
+        void visitBool(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& b) override
         {
             ARMARX_CHECK_NOT_NULL(b);
             this->addValueLabel(key, *aron::data::Bool::DynamicCastAndCheck(b), "bool");
         }
-        void visitDouble(const std::string& key, const aron::data::VariantPtr& d) override
+        void visitDouble(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& d) override
         {
             ARMARX_CHECK_NOT_NULL(d);
             this->addValueLabel(key, *aron::data::Double::DynamicCastAndCheck(d), "double");
         }
-        void visitFloat(const std::string& key, const aron::data::VariantPtr& f) override
+        void visitFloat(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& f) override
         {
             ARMARX_CHECK_NOT_NULL(f);
             this->addValueLabel(key, *aron::data::Float::DynamicCastAndCheck(f), "float");
         }
-        void visitInt(const std::string& key, const aron::data::VariantPtr& i) override
+        void visitInt(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& i) override
         {
             ARMARX_CHECK_NOT_NULL(i);
             this->addValueLabel(key, *aron::data::Int::DynamicCastAndCheck(i), "int");
         }
-        void visitLong(const std::string& key, const aron::data::VariantPtr& l) override
+        void visitLong(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& l) override
         {
             ARMARX_CHECK_NOT_NULL(l);
             this->addValueLabel(key, *aron::data::Long::DynamicCastAndCheck(l), "long");
         }
-        void visitString(const std::string& key, const aron::data::VariantPtr& string) override
+        void visitString(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& string) override
         {
             ARMARX_CHECK_NOT_NULL(string);
             this->addValueLabel(key, *aron::data::String::DynamicCastAndCheck(string), "string");
         }
 
-        void visitNDArray(const std::string& key, const aron::data::VariantPtr& array) override
+        void visitNDArray(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& array) override
         {
             ARMARX_CHECK_NOT_NULL(array);
             this->addValueLabel(key, *aron::data::NDArray::DynamicCastAndCheck(array), "ND Array");
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/bson/BsonConverter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/bson/BsonConverter.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/bson/BsonConverter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/bson/BsonConverter.h
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.cpp
new file mode 100644
index 000000000..fd719807e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.cpp
@@ -0,0 +1 @@
+#include "Converter.h"
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.h
new file mode 100644
index 000000000..776b7c05c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/Converter.h
@@ -0,0 +1,35 @@
+#pragma once
+
+// STD/STL
+#include <memory>
+
+// ArmarX
+#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
+
+namespace armarx::armem::server::ltm
+{
+    class DictConverter;
+    using DictConverterPtr = std::shared_ptr<DictConverter>;
+
+    class DictConverter
+    {
+    public:
+        enum class ConverterType
+        {
+            Str,
+            Binary
+        };
+
+        DictConverter(const ConverterType t, const std::string& s):
+            type(t),
+            suffix(s)
+        {}
+        virtual ~DictConverter() = default;
+
+        virtual std::vector<unsigned char> convert(const aron::data::DictPtr& data) = 0;
+        virtual aron::data::DictPtr convert(const std::vector<unsigned char>& data) = 0;
+
+        const ConverterType type;
+        const std::string suffix;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.cpp
new file mode 100644
index 000000000..e78913abd
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.cpp
@@ -0,0 +1,35 @@
+#include "BsonConverter.h"
+
+#include <bsoncxx/json.hpp>
+#include <bsoncxx/builder/stream/helpers.hpp>
+#include <bsoncxx/builder/stream/document.hpp>
+#include <bsoncxx/builder/stream/array.hpp>
+
+namespace armarx::armem::server::ltm::converter::dict
+{
+    namespace bsoncxxbuilder = bsoncxx::builder::stream;
+    namespace bsoncxxdoc = bsoncxx::document;
+
+    std::vector<unsigned char> BsonConverter::convert(const aron::data::DictPtr& data)
+    {
+        std::vector<unsigned char> jsonVec = jsonConverter.convert(data);
+        std::string json(jsonVec.begin(), jsonVec.end());
+        auto view = bsoncxx::from_json(json).view();
+
+        std::vector<unsigned char> bson(view.length());
+        if (view.length() > 0)
+        {
+            std::memcpy(bson.data(), view.data(), view.length());
+        }
+        return bson;
+    }
+
+    aron::data::DictPtr BsonConverter::convert(const std::vector<unsigned char>& data)
+    {
+        bsoncxx::document::view view(data.data(), data.size());
+        nlohmann::json json = bsoncxx::to_json(view);
+        std::string str = json.dump(2);
+        std::vector<unsigned char> jsonVec(str.begin(), str.end());
+        return jsonConverter.convert(jsonVec);
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.h
new file mode 100644
index 000000000..0d6f858b0
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/bson/BsonConverter.h
@@ -0,0 +1,27 @@
+#pragma once
+
+// Base Class
+#include "../Converter.h"
+
+// ArmarX
+#include "../json/JsonConverter.h"
+
+namespace armarx::armem::server::ltm::converter::dict
+{
+    class BsonConverter;
+    using BsonConverterPtr = std::shared_ptr<BsonConverter>;
+
+    class BsonConverter : public DictConverter
+    {
+    public:
+        BsonConverter() :
+            DictConverter(ConverterType::Binary, ".bson")
+        {}
+
+        virtual std::vector<unsigned char> convert(const aron::data::DictPtr& data) override;
+        virtual aron::data::DictPtr convert(const std::vector<unsigned char>& data) override;
+
+    private:
+        JsonConverter jsonConverter;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.cpp
new file mode 100644
index 000000000..379caf9b7
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.cpp
@@ -0,0 +1,20 @@
+#include "JsonConverter.h"
+
+#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
+
+namespace armarx::armem::server::ltm::converter::dict
+{
+    std::vector<unsigned char> JsonConverter::convert(const aron::data::DictPtr& data)
+    {
+        nlohmann::json j = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(data);
+        auto str = j.dump(2);
+        return std::vector<unsigned char>(str.begin(), str.end());
+    }
+
+    aron::data::DictPtr JsonConverter::convert(const std::vector<unsigned char>& data)
+    {
+        std::string str(data.begin(), data.end());
+        nlohmann::json j = nlohmann::json::parse(str);
+        return aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(j);
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.h
new file mode 100644
index 000000000..fad44583f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/dict/json/JsonConverter.h
@@ -0,0 +1,24 @@
+#pragma once
+
+// Base Class
+#include "../Converter.h"
+
+// Simox
+#include <SimoxUtility/json.h>
+
+namespace armarx::armem::server::ltm::converter::dict
+{
+    class JsonConverter;
+    using JsonConverterPtr = std::shared_ptr<JsonConverter>;
+
+    class JsonConverter : public DictConverter
+    {
+    public:
+        JsonConverter() :
+            DictConverter(ConverterType::Str, ".json")
+        {}
+
+        virtual std::vector<unsigned char> convert(const aron::data::DictPtr& data) override;
+        virtual aron::data::DictPtr convert(const std::vector<unsigned char>& data) override;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.cpp
new file mode 100644
index 000000000..fd719807e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.cpp
@@ -0,0 +1 @@
+#include "Converter.h"
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.h
new file mode 100644
index 000000000..740757ef8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/Converter.h
@@ -0,0 +1,35 @@
+#pragma once
+
+// STD/STL
+#include <memory>
+
+// ArmarX
+#include <RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h>
+
+namespace armarx::armem::server::ltm
+{
+    class ImageConverter;
+    using ImageConverterPtr = std::shared_ptr<ImageConverter>;
+
+    class ImageConverter
+    {
+    public:
+        enum class ConverterType
+        {
+            Str,
+            Binary
+        };
+
+        ImageConverter(const ConverterType t, const std::string& s):
+            type(t),
+            suffix(s)
+        {}
+        virtual ~ImageConverter() = default;
+
+        virtual std::vector<unsigned char> convert(const aron::data::NDArrayPtr& data) = 0;
+        virtual aron::data::NDArrayPtr convert(const std::vector<unsigned char>& data) = 0;
+
+        const ConverterType type;
+        const std::string suffix;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.cpp
new file mode 100644
index 000000000..917bbde00
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.cpp
@@ -0,0 +1,25 @@
+#include "PngConverter.h"
+
+// ArmarX
+#include <RobotAPI/libraries/aron/converter/opencv/OpenCVConverter.h>
+
+#include <opencv2/opencv.hpp>
+#include <opencv2/imgcodecs.hpp>
+#include <opencv2/imgproc.hpp>
+
+
+namespace armarx::armem::server::ltm::converter::image
+{
+    std::vector<unsigned char> PngConverter::convert(const aron::data::NDArrayPtr& data)
+    {
+        auto img = aron::converter::AronOpenCVConverter::ConvertToMat(data);
+        std::vector<unsigned char> buffer;
+        cv::imencode(".png", img, buffer);
+        return buffer;
+    }
+
+    aron::data::NDArrayPtr PngConverter::convert(const std::vector<unsigned char>& data)
+    {
+        return {};
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.h
new file mode 100644
index 000000000..13581518a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/converter/image/png/PngConverter.h
@@ -0,0 +1,21 @@
+#pragma once
+
+// Base Class
+#include "../Converter.h"
+
+namespace armarx::armem::server::ltm::converter::image
+{
+    class PngConverter;
+    using PngConverterPtr = std::shared_ptr<PngConverter>;
+
+    class PngConverter : public ImageConverter
+    {
+    public:
+        PngConverter() :
+            ImageConverter(ConverterType::Str, ".png")
+        {}
+
+        virtual std::vector<unsigned char> convert(const aron::data::NDArrayPtr& data) override;
+        virtual aron::data::NDArrayPtr convert(const std::vector<unsigned char>& data) override;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/json/JsonConverter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/converter/json/JsonConverter.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/json/JsonConverter.h b/source/RobotAPI/libraries/armem/server/ltm/base/converter/json/JsonConverter.h
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h
index aabceb4c0..71806cbcb 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/BufferedMemoryBase.h
@@ -17,9 +17,16 @@ namespace armarx::armem::server::ltm
             return buffer;
         }
 
+        void directlyStore(const armem::wm::Memory& memory)
+        {
+            TIMING_START(LTM_Memory_DirectlyStore);
+            _directlyStore(memory);
+            TIMING_END(LTM_Memory_DirectlyStore);
+        }
+
         void storeBuffer()
         {
-            this->store(buffer);
+            this->directlyStore(buffer);
             buffer.clear();
         }
 
@@ -29,7 +36,9 @@ namespace armarx::armem::server::ltm
             buffer.name() = this->name();
         }
 
-        void append(const armem::wm::Memory& memory) override
+    protected:
+        virtual void _directlyStore(const armem::wm::Memory& memory) = 0;
+        void _store(const armem::wm::Memory& memory) override
         {
             std::lock_guard l(this->ltm_mutex);
             buffer.append(memory);
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h
index 807d45f20..47a6278ab 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/CoreSegmentBase.h
@@ -24,13 +24,22 @@ namespace armarx::armem::server::ltm
 
         /// return the full sub-ltm as a wm::CoreSegment with only references
         /// the ltm may be huge, use with caution
-        virtual armem::wm::CoreSegment loadAll() = 0;
+        void loadAll(armem::wm::CoreSegment& coreSeg)
+        {
+            _loadAll(coreSeg);
+        }
 
         /// convert the references of the input into a wm::Memory
-        virtual void convert(armem::wm::CoreSegment&) = 0;
+        void load(armem::wm::CoreSegment& coreSeg)
+        {
+            _load(coreSeg);
+        }
 
         /// encode the content of a wm::Memory and store
-        virtual void store(const armem::wm::CoreSegment&) = 0;
+        void store(const armem::wm::CoreSegment& coreSeg)
+        {
+            _store(coreSeg);
+        }
 
         /// iterate over all provider segments of this ltm
         virtual bool forEachProviderSegment(std::function<void(ProviderSegmentT&)>&& func) const = 0;
@@ -50,6 +59,11 @@ namespace armarx::armem::server::ltm
             return "LT-CoreSegment";
         }
 
+    protected:
+        virtual void _loadAll(armem::wm::CoreSegment&) = 0;
+        virtual void _load(armem::wm::CoreSegment&) = 0;
+        virtual void _store(const armem::wm::CoreSegment&) = 0;
+
     protected:
         mutable std::recursive_mutex ltm_mutex;
     };
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h
index 49dcbbee0..38d3dec99 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntityBase.h
@@ -24,13 +24,22 @@ namespace armarx::armem::server::ltm
 
         /// return the full sub-ltm as a wm::Entity with only references
         /// the ltm may be huge, use with caution
-        virtual armem::wm::Entity loadAll() = 0;
+        void loadAll(armem::wm::Entity& e)
+        {
+            _loadAll(e);
+        }
 
         /// convert the references of the input into a wm::Memory
-        virtual void convert(armem::wm::Entity&) = 0;
+        void load(armem::wm::Entity& e)
+        {
+            _load(e);
+        }
 
         /// encode the content of a wm::Memory and store
-        virtual void store(const armem::wm::Entity&) = 0;
+        void store(const armem::wm::Entity& e)
+        {
+            _store(e);
+        }
 
         /// iterate over all entity snapshots of this ltm
         virtual bool forEachSnapshot(std::function<void(EntitySnapshotT&)>&& func) const = 0;
@@ -52,6 +61,11 @@ namespace armarx::armem::server::ltm
             return "LT-Entity";
         }
 
+    protected:
+        virtual void _loadAll(armem::wm::Entity&) = 0;
+        virtual void _load(armem::wm::Entity&) = 0;
+        virtual void _store(const armem::wm::Entity&) = 0;
+
     protected:
         mutable std::recursive_mutex ltm_mutex;
     };
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntitySnapshotBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntitySnapshotBase.h
index 027ac262f..a94255064 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntitySnapshotBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/EntitySnapshotBase.h
@@ -9,6 +9,10 @@
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/wm/aron_conversions.h>
 
+#include "../extractor/Extractor.h"
+#include "../converter/dict/Converter.h"
+#include "../converter/image/Converter.h"
+
 namespace armarx::armem::server::ltm
 {
     /// @brief Interface functions for the longterm memory classes
@@ -20,17 +24,35 @@ namespace armarx::armem::server::ltm
 
         /// return the full sub-ltm as a wm::EntitySnapshot with only references
         /// the ltm may be huge, use with caution
-        virtual armem::wm::EntitySnapshot loadAll() const = 0;
+        void loadAll(armem::wm::EntitySnapshot& e) const
+        {
+            _loadAll(e);
+        }
 
         /// convert the references of the input into a wm::Memory
-        virtual void convert(armem::wm::EntitySnapshot&) const = 0;
+        void load(armem::wm::EntitySnapshot& e) const
+        {
+            _load(e);
+        }
 
         /// encode the content of a wm::Memory and store
-        virtual void store(const armem::wm::EntitySnapshot&) const = 0;
+        void store(const armem::wm::EntitySnapshot& e) const
+        {
+            _store(e);
+        }
 
         static std::string getLevelName();
 
+    protected:
+        virtual void _loadAll(armem::wm::EntitySnapshot&) const = 0;
+        virtual void _load(armem::wm::EntitySnapshot&) const = 0;
+        virtual void _store(const armem::wm::EntitySnapshot&) const = 0;
+
     protected:
         mutable std::recursive_mutex ltm_mutex;
+
+        DictConverterPtr dictConverter;
+        ImageConverterPtr imgConverter;
+        ExtractorPtr extractor;
     };
 } // namespace armarx::armem::server::ltm
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h
index 49d05ab2b..159e1912c 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/LUTMemoryBase.h
@@ -5,21 +5,21 @@
 namespace armarx::armem::server::ltm
 {
     template <class _CoreSegmentT>
-    class LUTMemoryBase : virtual public MemoryBase<_CoreSegmentT>
+    class CachedMemoryBase : virtual public MemoryBase<_CoreSegmentT>
     {
     public:
         using MemoryBase<_CoreSegmentT>::MemoryBase;
 
-        armem::wm::Memory getLUT() const
+        armem::wm::Memory getCache() const
         {
             std::lock_guard l(this->ltm_mutex);
-            return lut;
+            return cache;
         }
 
         void setMemoryID(const MemoryID& id) override
         {
             MemoryBase<_CoreSegmentT>::setMemoryID(id);
-            lut.name() = this->name();
+            cache.name() = this->name();
         }
 
     protected:
@@ -41,7 +41,7 @@ namespace armarx::armem::server::ltm
 
     protected:
 
-        armem::wm::Memory lut;
+        armem::wm::Memory cache;
 
     };
 } // namespace armarx::armem::server::ltm
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h
index 919619488..d56d3e798 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryBase.h
@@ -5,8 +5,15 @@
 // BaseClass
 #include "MemoryItem.h"
 
+// ChildType
 #include "CoreSegmentBase.h"
 
+// Members
+#include "../filter/Filter.h"
+
+// ArmarX
+#include <ArmarXCore/core/time/TimeUtil.h>
+#include <ArmarXCore/core/logging/LoggingUtil.h>
 #include <RobotAPI/libraries/armem/core/MemoryID.h>
 #include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
 #include <RobotAPI/libraries/armem/core/wm/aron_conversions.h>
@@ -24,16 +31,31 @@ namespace armarx::armem::server::ltm
 
         /// return the full ltm as a wm::Memory with only references
         /// the ltm may be huge, use with caution
-        virtual armem::wm::Memory loadAll() = 0;
-
-        /// append a wm::Memory instance to the ltm
-        virtual void append(const armem::wm::Memory& memory) = 0;
+        void loadAll(armem::wm::Memory& memory)
+        {
+            TIMING_START(LTM_Memory_LoadAll);
+            _loadAll(memory);
+            TIMING_END(LTM_Memory_LoadAll);
+        }
 
         /// convert the references of the input into a wm::Memory
-        virtual void convert(armem::wm::Memory&) = 0;
+        void load(armem::wm::Memory& memory)
+        {
+            TIMING_START(LTM_Memory_Load);
+            _load(memory);
+            TIMING_END(LTM_Memory_Load);
+        }
 
-        /// encode the content of a wm::Memory and store
-        virtual void store(const armem::wm::Memory&) = 0;
+        /// append a wm::Memory instance to the ltm
+        void store(const armem::wm::Memory& memory, bool force = false)
+        {
+            TIMING_START(LTM_Memory_Append);
+            if (force or filter->accept(memory))
+            {
+                _store(memory);
+            }
+            TIMING_END(LTM_Memory_Append);
+        }
 
         /// iterate over all core segments of this ltm
         virtual bool forEachCoreSegment(std::function<void(CoreSegmentT&)>&& func) const = 0;
@@ -48,8 +70,14 @@ namespace armarx::armem::server::ltm
         }
 
     protected:
-        mutable std::recursive_mutex ltm_mutex;
+        virtual void _loadAll(armem::wm::Memory& memory) = 0;
+        virtual void _load(armem::wm::Memory& memory) = 0;
+        virtual void _store(const armem::wm::Memory& memory) = 0;
 
+    protected:
+        mutable std::recursive_mutex ltm_mutex;
 
+        FilterPtr filter;
+        // ForgetterPtr forgetter;
     };
 } // namespace armarx::armem::server::ltm
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h
index 9294a6c19..167858dc7 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/ProviderSegmentBase.h
@@ -24,13 +24,22 @@ namespace armarx::armem::server::ltm
 
         /// return the full sub-ltm as a wm::ProviderSegment with only references
         /// the ltm may be huge, use with caution
-        virtual armem::wm::ProviderSegment loadAll() = 0;
+        void loadAll(armem::wm::ProviderSegment& provSeg)
+        {
+            _loadAll(provSeg);
+        }
 
         /// convert the references of the input into a wm::Memory
-        virtual void convert(armem::wm::ProviderSegment&) = 0;
+        void load(armem::wm::ProviderSegment& provSeg)
+        {
+            _load(provSeg);
+        }
 
         /// encode the content of a wm::Memory and store
-        virtual void store(const armem::wm::ProviderSegment&) = 0;
+        void store(const armem::wm::ProviderSegment& provSeg)
+        {
+            _store(provSeg);
+        }
 
         /// iterate over all core segments of this ltm
         virtual bool forEachEntity(std::function<void(EntityT&)>&& func) const = 0;
@@ -49,6 +58,9 @@ namespace armarx::armem::server::ltm
         }
 
     protected:
+        virtual void _loadAll(armem::wm::ProviderSegment&) = 0;
+        virtual void _load(armem::wm::ProviderSegment&) = 0;
+        virtual void _store(const armem::wm::ProviderSegment&) = 0;
 
     protected:
         mutable std::recursive_mutex ltm_mutex;
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/encoder/Encoder.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/encoder/Encoder.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/encoder/Encoder.h b/source/RobotAPI/libraries/armem/server/ltm/base/encoder/Encoder.h
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/encoder/noEncoder/NoEncoder.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/encoder/noEncoder/NoEncoder.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/encoder/noEncoder/NoEncoder.h b/source/RobotAPI/libraries/armem/server/ltm/base/encoder/noEncoder/NoEncoder.h
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.cpp
new file mode 100644
index 000000000..574431539
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.cpp
@@ -0,0 +1 @@
+#include "Extractor.h"
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.h b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.h
new file mode 100644
index 000000000..4c3030f89
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/Extractor.h
@@ -0,0 +1,32 @@
+#pragma once
+
+// STD/STL
+#include <memory>
+
+// ArmarX
+#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
+#include <RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h>
+
+namespace armarx::armem::server::ltm
+{
+    class Extractor;
+    typedef std::shared_ptr<Extractor> ExtractorPtr;
+
+    class Extractor
+    {
+    public:
+        struct Extraction
+        {
+            aron::data::DictPtr data;
+            std::map<std::string, aron::data::NDArrayPtr> images;
+            std::map<std::string, aron::data::NDArrayPtr> pointclouds;
+            std::map<std::string, aron::data::NDArrayPtr> matrices;
+        };
+
+        Extractor() = default;
+        virtual ~Extractor() = default;
+
+        virtual Extraction extract(aron::data::DictPtr& data) = 0;
+        virtual aron::data::DictPtr merge(Extraction& encoding) = 0;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.cpp
new file mode 100644
index 000000000..845b66e82
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.cpp
@@ -0,0 +1,54 @@
+#include "ImageExtractor.h"
+
+
+namespace armarx::armem::server::ltm::extractor
+{
+    void ImageExtractorVisitor::visitNDArray(const std::string& key, Input& parent, Input& variant)
+    {
+        ARMARX_CHECK_NOT_NULL(parent);
+        ARMARX_CHECK_NOT_NULL(variant);
+
+        auto ndarray = aron::data::NDArray::DynamicCastAndCheck(variant);
+        if (ndarray->getShape().size() == 3)
+        {
+            images[key] = ndarray;
+            switch (parent->getDescriptor())
+            {
+                case aron::data::Descriptor::eDict:
+                {
+                    auto dict = aron::data::Dict::DynamicCastAndCheck(parent);
+                    dict->setElement(key, nullptr);
+                    break;
+                }
+                case aron::data::Descriptor::eList:
+                {
+                    auto list = aron::data::List::DynamicCastAndCheck(parent);
+                    list->setElement(std::stoi(key), nullptr);
+                    break;
+                }
+                default:
+                {
+                    throw aron::error::AronException(__PRETTY_FUNCTION__, "Found invalid parent in visitor.");
+                }
+            }
+        }
+    }
+
+    Extractor::Extraction ImageExtractor::extract(aron::data::DictPtr& data)
+    {
+        ImageExtractorVisitor visitor;
+        aron::data::VariantPtr var = std::static_pointer_cast<aron::data::Variant>(data);
+        aron::data::VariantPtr p;
+        aron::data::visitRecursive(visitor, var, "", p);
+
+        Extraction encoding;
+        encoding.data = data;
+        encoding.images = visitor.images;
+        return encoding;
+    }
+
+    aron::data::DictPtr ImageExtractor::merge(Extraction& encoding)
+    {
+        return encoding.data;
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.h b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.h
new file mode 100644
index 000000000..a1a5b3823
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/imageExtractor/ImageExtractor.h
@@ -0,0 +1,29 @@
+#pragma once
+
+// Base Class
+#include "../Extractor.h"
+
+#include <RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h>
+
+namespace armarx::armem::server::ltm::extractor
+{
+    class ImageExtractor;
+    typedef std::shared_ptr<ImageExtractor> ImageExtractorPtr;
+
+    class ImageExtractorVisitor : public aron::data::RecursiveVariantVisitor
+    {
+    public:
+        std::map<std::string, aron::data::NDArrayPtr> images;
+
+        void visitNDArray(const std::string& key, Input& parent, Input& data);
+    };
+
+    class ImageExtractor : public Extractor
+    {
+    public:
+        ImageExtractor() = default;
+
+        virtual Extraction extract(aron::data::DictPtr& data) override;
+        virtual aron::data::DictPtr merge(Extraction& encoding) override;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.cpp
new file mode 100644
index 000000000..a0d446f7f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.cpp
@@ -0,0 +1,17 @@
+#include "NoExtractor.h"
+
+
+namespace armarx::armem::server::ltm::extractor
+{
+    Extractor::Extraction NoExtractor::extract(aron::data::DictPtr& data)
+    {
+        Extraction encoding;
+        encoding.data = data;
+        return encoding;
+    }
+
+    aron::data::DictPtr NoExtractor::merge(Extraction& encoding)
+    {
+        return encoding.data;
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.h b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.h
new file mode 100644
index 000000000..fdcc66684
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/extractor/noExtractor/NoExtractor.h
@@ -0,0 +1,19 @@
+#pragma once
+
+// Base Class
+#include "../Extractor.h"
+
+namespace armarx::armem::server::ltm::extractor
+{
+    class NoExtractor;
+    typedef std::shared_ptr<NoExtractor> NoExtractorPtr;
+
+    class NoExtractor : public Extractor
+    {
+    public:
+        NoExtractor() = default;
+
+        virtual Extraction extract(aron::data::DictPtr& data) override;
+        virtual aron::data::DictPtr merge(Extraction& encoding) override;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.cpp
index e69de29bb..088af9712 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.cpp
@@ -0,0 +1,2 @@
+#include "Filter.h"
+
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.h b/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.h
index e69de29bb..c4b5871c8 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/filter/Filter.h
@@ -0,0 +1,23 @@
+#pragma once
+
+// STD/STL
+#include <memory>
+
+// ArmarX
+#include <RobotAPI/libraries/armem/core/MemoryID.h>
+#include <RobotAPI/libraries/armem/core/wm/memory_definitions.h>
+
+namespace armarx::armem::server::ltm
+{
+    class Filter;
+    typedef std::shared_ptr<Filter> FilterPtr;
+
+    class Filter
+    {
+    public:
+        Filter() = default;
+        virtual ~Filter() = default;
+
+        virtual bool accept(const armem::wm::Memory& memory) = 0;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.cpp
new file mode 100644
index 000000000..15802afb6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.cpp
@@ -0,0 +1,17 @@
+#include "FrequencyFilter.h"
+
+#include <IceUtil/Time.h>
+
+namespace armarx::armem::server::ltm::filter
+{
+    bool FrequencyFilter::accept(const armem::wm::Memory&)
+    {
+        auto now = IceUtil::Time::now().toMilliSeconds();
+        if (waitingTimeInMs < 0 || (now - timestampLastCommitInMs) > waitingTimeInMs)
+        {
+            timestampLastCommitInMs = now;
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.h b/source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.h
new file mode 100644
index 000000000..acf952825
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/ltm/base/filter/frequencyFilter/FrequencyFilter.h
@@ -0,0 +1,23 @@
+#pragma once
+
+// Base Class
+#include "../Filter.h"
+
+namespace armarx::armem::server::ltm::filter
+{
+    class FrequencyFilter;
+    typedef std::shared_ptr<FrequencyFilter> FrequencyFilterPtr;
+
+    class FrequencyFilter :
+            public Filter
+    {
+    public:
+        FrequencyFilter() = default;
+
+        virtual bool accept(const armem::wm::Memory& memory) override;
+
+    private:
+        int waitingTimeInMs = 100;
+        long timestampLastCommitInMs = 0;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/filter/noFilter/NoFilter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/filter/noFilter/NoFilter.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/filter/noFilter/NoFilter.h b/source/RobotAPI/libraries/armem/server/ltm/base/filter/noFilter/NoFilter.h
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/Converter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/forgetter/LRUForgetter/LRUForgetter.cpp
similarity index 100%
rename from source/RobotAPI/libraries/armem/server/ltm/base/converter/Converter.cpp
rename to source/RobotAPI/libraries/armem/server/ltm/base/forgetter/LRUForgetter/LRUForgetter.cpp
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/converter/Converter.h b/source/RobotAPI/libraries/armem/server/ltm/base/forgetter/LRUForgetter/LRUForgetter.h
similarity index 100%
rename from source/RobotAPI/libraries/armem/server/ltm/base/converter/Converter.h
rename to source/RobotAPI/libraries/armem/server/ltm/base/forgetter/LRUForgetter/LRUForgetter.h
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/forgetter/noForgetter/NoForgetter.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/forgetter/noForgetter/NoForgetter.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/forgetter/noForgetter/NoForgetter.h b/source/RobotAPI/libraries/armem/server/ltm/base/forgetter/noForgetter/NoForgetter.h
deleted file mode 100644
index e69de29bb..000000000
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp
index 5de81875d..93809ca6d 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.cpp
@@ -66,29 +66,28 @@ namespace armarx::armem::server::ltm::disk
         return name();
     }
 
-    armem::wm::CoreSegment CoreSegment::loadAll()
+    void CoreSegment::_loadAll(armem::wm::CoreSegment& e)
     {
-        armem::wm::CoreSegment e(id());
+        e.id() = id();
 
         forEachProviderSegment([&e](ProviderSegment& x) {
-            auto s = x.loadAll();
+            armem::wm::ProviderSegment s;
+            x.loadAll(s);
             e.addProviderSegment(s);
         });
-
-        return e;
     }
 
-    void CoreSegment::convert(armem::wm::CoreSegment& c)
+    void CoreSegment::_load(armem::wm::CoreSegment& c)
     {
         c.forEachProviderSegment([this](armem::wm::ProviderSegment& e)
         {
             util::ensureFolderExists(std::filesystem::path(path) / e.id().providerSegmentName, false);
             ProviderSegment c(std::filesystem::path(path) / e.id().providerSegmentName);
-            c.convert(e);
+            c.load(e);
         });
     }
 
-    void CoreSegment::store(const armem::wm::CoreSegment& c)
+    void CoreSegment::_store(const armem::wm::CoreSegment& c)
     {
         c.forEachProviderSegment([this](const armem::wm::ProviderSegment& e)
         {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h
index a0d3872ce..c7125b59e 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/CoreSegment.h
@@ -15,18 +15,17 @@ namespace armarx::armem::server::ltm::disk
             public DiskStorage
     {
     public:
-        using CoreSegmentBase::CoreSegmentBase;
         CoreSegment(const std::filesystem::path&);
 
-        armem::wm::CoreSegment loadAll() override;
-        void convert(armem::wm::CoreSegment&) override;
-        void store(const armem::wm::CoreSegment&) override;
-
         bool forEachProviderSegment(std::function<void(ProviderSegment&)>&& func) const override;
 
         std::shared_ptr<ProviderSegment> findProviderSegment(const std::string&) const override;
 
     protected:
+        void _loadAll(armem::wm::CoreSegment&) override;
+        void _load(armem::wm::CoreSegment&) override;
+        void _store(const armem::wm::CoreSegment&) override;
+
         std::string getExpectedFolderName() const override;
     };
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp
index 5ddabc38e..7b9313217 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.cpp
@@ -114,29 +114,28 @@ namespace armarx::armem::server::ltm::disk
         return {};
     }
 
-    armem::wm::Entity Entity::loadAll()
+    void Entity::_loadAll(armem::wm::Entity& e)
     {
-        armem::wm::Entity e(id());
+        e.id() = id();
 
         forEachSnapshot([&e](EntitySnapshotBase& x) {
-            auto s = x.loadAll();
+            armem::wm::EntitySnapshot s;
+            x.loadAll(s);
             e.addSnapshot(s);
         });
-
-        return e;
     }
 
-    void Entity::convert(armem::wm::Entity& p)
+    void Entity::_load(armem::wm::Entity& p)
     {
         p.forEachSnapshot([this](armem::wm::EntitySnapshot& e)
         {
             util::ensureFolderExists(std::filesystem::path(path) / std::to_string(e.id().timestamp.toMicroSeconds()), false);
             EntitySnapshot c(std::filesystem::path(path) / std::to_string(e.id().timestamp.toMicroSeconds()));
-            c.store(e);
+            c.load(e);
         });
     }
 
-    void Entity::store(const armem::wm::Entity& c)
+    void Entity::_store(const armem::wm::Entity& c)
     {
         c.forEachSnapshot([this](armem::wm::EntitySnapshot& e)
         {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h
index 48b46c34e..fa77b6adc 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Entity.h
@@ -16,13 +16,8 @@ namespace armarx::armem::server::ltm::disk
             public DiskStorage
     {
     public:
-        using EntityBase::EntityBase;
         Entity(const std::filesystem::path&);
 
-        armem::wm::Entity loadAll() override;
-        void convert(armem::wm::Entity&) override;
-        void store(const armem::wm::Entity&) override;
-
         bool forEachSnapshot(std::function<void(EntitySnapshot&)>&& func) const override;
         bool forEachSnapshotInIndexRange(long first, long last, std::function<void(EntitySnapshot&)>&& func) const override;
         bool forEachSnapshotInTimeRange(const Time& min, const Time& max, std::function<void(EntitySnapshot&)>&& func) const override;
@@ -37,6 +32,10 @@ namespace armarx::armem::server::ltm::disk
         std::shared_ptr<EntitySnapshot> findFirstSnapshotAfterOrAt(const Time& time) const override;
 
     protected:
+        void _loadAll(armem::wm::Entity&) override;
+        void _load(armem::wm::Entity&) override;
+        void _store(const armem::wm::Entity&) override;
+
         std::string getExpectedFolderName() const override;
     };
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp
index 204769226..8256d1af9 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.cpp
@@ -9,7 +9,13 @@
 #include <ArmarXCore/core/time/TimeUtil.h>
 #include <ArmarXCore/core/logging/Logging.h>
 #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h>
-#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h>
+
+// ArmarX
+#include "../base/extractor/noExtractor/NoExtractor.h"
+#include "../base/extractor/imageExtractor/ImageExtractor.h"
+#include "../base/converter/dict/json/JsonConverter.h"
+#include "../base/converter/dict/bson/BsonConverter.h"
+#include "../base/converter/image/png/PngConverter.h"
 
 namespace armarx::armem::server::ltm::disk
 {
@@ -28,12 +34,23 @@ namespace armarx::armem::server::ltm::disk
             m.timestamp = IceUtil::Time::microSeconds(std::stol(p.filename()));
             return m;
         }
+
+        void writeDataToFile(const std::filesystem::path& path, const std::vector<unsigned char>& data)
+        {
+            std::ofstream dataofs;
+            dataofs.open(path);
+            dataofs.write(reinterpret_cast<const char*>(data.data()), data.size());
+            dataofs.close();
+        }
     }
 
     EntitySnapshot::EntitySnapshot(const std::filesystem::path& p) :
         EntitySnapshotBase(getMemoryIDFromPath(p)),
         DiskStorage(p)
     {
+        extractor = std::make_shared<extractor::ImageExtractor>();
+        dictConverter = std::make_shared<converter::dict::JsonConverter>();
+        imgConverter = std::make_shared<converter::image::PngConverter>();
     }
 
     std::string EntitySnapshot::getExpectedFolderName() const
@@ -41,12 +58,12 @@ namespace armarx::armem::server::ltm::disk
         return name();
     }
 
-    armem::wm::EntitySnapshot EntitySnapshot::loadAll() const
+    void EntitySnapshot::_loadAll(armem::wm::EntitySnapshot& e) const
     {
         std::filesystem::path p = path;
         util::ensureFolderExists(p, false);
 
-        armem::wm::EntitySnapshot e(id());
+        e.id() = id();
 
         for (unsigned int i = 0; i < 1000; ++i) // 1000 is max size for instances in a single timestamp
         {
@@ -58,10 +75,9 @@ namespace armarx::armem::server::ltm::disk
             // add instance. Do not set data, since we only return references
             e.addInstance();
         }
-        return e;
     }
 
-    void EntitySnapshot::convert(armem::wm::EntitySnapshot& e) const
+    void EntitySnapshot::_load(armem::wm::EntitySnapshot& e) const
     {
         // Get data from disk
         std::filesystem::path p = path;
@@ -71,61 +87,67 @@ namespace armarx::armem::server::ltm::disk
         {
             util::ensureFolderExists(p / std::to_string(i), false);
 
-            std::filesystem::path data = p / std::to_string(i) / constantes::DATA_FILENAME;
-            std::filesystem::path metadata = p / std::to_string(i) / constantes::METADATA_FILENAME;
+            std::filesystem::path data = p / std::to_string(i) / (constantes::DATA_FILENAME + dictConverter->suffix);
+            std::filesystem::path metadata = p / std::to_string(i) / (constantes::METADATA_FILENAME + dictConverter->suffix);
 
             util::ensureFileExists(data);
 
             auto& ins = e.getInstance(i);
 
             std::ifstream dataifs(data);
-            std::string datafilecontent((std::istreambuf_iterator<char>(dataifs)), (std::istreambuf_iterator<char>()));
-            nlohmann::json datajson = nlohmann::json::parse(datafilecontent);
-            auto dataaron = aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(datajson);
+            std::vector<unsigned char> datafilecontent((std::istreambuf_iterator<char>(dataifs)), (std::istreambuf_iterator<char>()));
+            auto dataaron = dictConverter->convert(datafilecontent);
 
             std::ifstream metadataifs(metadata);
-            std::string metadatafilecontent((std::istreambuf_iterator<char>(metadataifs)), (std::istreambuf_iterator<char>()));
-            nlohmann::json metadatajson = nlohmann::json::parse(metadatafilecontent);
-            auto metadataaron = aron::converter::AronNlohmannJSONConverter::ConvertFromNlohmannJSONObject(metadatajson);
+            std::vector<unsigned char> metadatafilecontent((std::istreambuf_iterator<char>(metadataifs)), (std::istreambuf_iterator<char>()));
+            auto metadataaron = dictConverter->convert(metadatafilecontent);
 
             from_aron(metadataaron, dataaron, ins);
         }
     }
 
-    void EntitySnapshot::store(const armem::wm::EntitySnapshot& e) const
+    void EntitySnapshot::_store(const armem::wm::EntitySnapshot& e) const
     {
         std::filesystem::path p = path;
         util::ensureFolderExists(p);
 
         for (unsigned int i = 0; i < e.size(); ++i)
         {
-            util::ensureFolderExists(p / std::to_string(i));
+            std::filesystem::path instancePath = p / std::to_string(i);
+            util::ensureFolderExists(instancePath);
 
-            std::filesystem::path data = p / std::to_string(i) / constantes::DATA_FILENAME;
-            std::filesystem::path metadata = p / std::to_string(i) / constantes::METADATA_FILENAME;
+            std::filesystem::path dataPath = instancePath / (constantes::DATA_FILENAME + dictConverter->suffix);
+            std::filesystem::path metadataPath = instancePath / (constantes::METADATA_FILENAME + dictConverter->suffix);
 
-            if (util::checkIfFileExists(data) or util::checkIfFileExists(metadata))
+            if (util::checkIfFileExists(dataPath) or util::checkIfFileExists(metadataPath))
             {
                 continue;
             }
 
             auto& ins = e.getInstance(i);
 
-            auto dataaron = std::make_shared<aron::data::Dict>();
-            auto metadataaron = std::make_shared<aron::data::Dict>();
-            to_aron(metadataaron, dataaron, ins);
-            nlohmann::json datajson = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(dataaron);
-            nlohmann::json metadatajson = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(metadataaron);
+            // data
+            auto dataAron = std::make_shared<aron::data::Dict>();
+            auto metadataAron = std::make_shared<aron::data::Dict>();
+            to_aron(metadataAron, dataAron, ins);
 
-            std::ofstream dataofs;
-            dataofs.open(data);
-            dataofs << datajson.dump(2);
-            dataofs.close();
+            // extract
+            auto dataExt = extractor->extract(dataAron);
+            auto metadataExt = extractor->extract(metadataAron);
+
+            // convert images
+            for (const auto& [memberName, img] : dataExt.images)
+            {
+                std::filesystem::path imgPath = instancePath / (memberName + imgConverter->suffix);
+                auto imgVec = imgConverter->convert(img);
+                writeDataToFile(imgPath, imgVec);
+            }
 
-            std::ofstream metadataofs;
-            metadataofs.open(metadata);
-            metadataofs << metadatajson.dump(2);
-            metadataofs.close();
+            // convert dict and metadata
+            auto dataVec = dictConverter->convert(dataExt.data);
+            auto metadataVec = dictConverter->convert(metadataExt.data);
+            writeDataToFile(dataPath, dataVec);
+            writeDataToFile(metadataPath, metadataVec);
         }
     }
 }
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h
index d93a62c9c..8206d9d6d 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/EntitySnapshot.h
@@ -14,14 +14,13 @@ namespace armarx::armem::server::ltm::disk
             public DiskStorage
     {
     public:
-        using EntitySnapshotBase::EntitySnapshotBase;
         EntitySnapshot(const std::filesystem::path&);
 
-        armem::wm::EntitySnapshot loadAll() const override;
-        void convert(armem::wm::EntitySnapshot&) const override;
-        void store(const armem::wm::EntitySnapshot&) const override;
-
     protected:
+        void _loadAll(armem::wm::EntitySnapshot&) const override;
+        void _load(armem::wm::EntitySnapshot&) const override;
+        void _store(const armem::wm::EntitySnapshot&) const override;
+
         std::string getExpectedFolderName() const override;
     };
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp
index b75a3f557..0735a4389 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.cpp
@@ -23,6 +23,7 @@ namespace armarx::armem::server::ltm::disk
         BufferedMemoryBase(),
         DiskStorage()
     {
+        filter = std::make_shared<filter::FrequencyFilter>();
         setMemoryID(MemoryID("Test", ""));
 
         /*std::string armarx_home = std::string(getenv("HOME")) + "/.armarx";
@@ -38,6 +39,7 @@ namespace armarx::armem::server::ltm::disk
         BufferedMemoryBase(),
         DiskStorage(p)
     {
+        filter = std::make_shared<filter::FrequencyFilter>();
         setMemoryID(getMemoryIDFromPath(p));
     }
 
@@ -81,25 +83,19 @@ namespace armarx::armem::server::ltm::disk
         return c;
     }
 
-    armem::wm::Memory Memory::loadAll()
+    void Memory::_loadAll(armem::wm::Memory& m)
     {
-        TIMING_START(LTM_Memory_Load);
-
-        armem::wm::Memory m(id());
+        m.id() = id();
 
         forEachCoreSegment([&m](CoreSegment& x) {
-            auto s = x.loadAll();
+            armem::wm::CoreSegment s;
+            x.loadAll(s);
             m.addCoreSegment(s);
         });
-
-        TIMING_END_STREAM(LTM_Memory_Load, ARMARX_DEBUG);
-        return m;
     }
 
-    void Memory::convert(armem::wm::Memory& m)
+    void Memory::_load(armem::wm::Memory& m)
     {
-        TIMING_START(LTM_Memory_Convert);
-
         if (!checkPath())
         {
             return;
@@ -110,16 +106,13 @@ namespace armarx::armem::server::ltm::disk
         {
             util::ensureFolderExists(std::filesystem::path(path) / e.id().coreSegmentName, false);
             CoreSegment c(std::filesystem::path(path) / e.id().coreSegmentName);
-            c.convert(e);
+            c.load(e);
         });
 
-        TIMING_END_STREAM(LTM_Memory_Convert, ARMARX_DEBUG);
     }
 
-    void Memory::store(const armem::wm::Memory& m)
+    void Memory::_directlyStore(const armem::wm::Memory& m)
     {
-        TIMING_START(LTM_Memory_Store);
-
         if (!checkPath())
         {
             return;
@@ -133,10 +126,5 @@ namespace armarx::armem::server::ltm::disk
             CoreSegment c(std::filesystem::path(path) / e.id().coreSegmentName);
             c.store(e);
         });
-
-        // Finaly clear cache and put reference to lut
-        buffer.clear();
-
-        TIMING_END_STREAM(LTM_Memory_Store, ARMARX_DEBUG);
     }
 }
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h
index e9e422577..5b17f97ca 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/Memory.h
@@ -6,8 +6,13 @@
 #include "../base/detail/BufferedMemoryBase.h"
 #include "detail/DiskStorage.h"
 
+// Segmnet Type
 #include "CoreSegment.h"
 
+// Config
+#include "../base/filter/frequencyFilter/FrequencyFilter.h"
+
+
 namespace armarx::armem::server::ltm::disk
 {
     /// @brief A memory storing data in mongodb (needs 'armarx memory start' to start the mongod instance)
@@ -16,19 +21,19 @@ namespace armarx::armem::server::ltm::disk
             public DiskStorage
     {
     public:
-        using BufferedMemoryBase::BufferedMemoryBase;
         Memory();
         Memory(const std::filesystem::path&);
 
-        armem::wm::Memory loadAll() override;
-        void convert(armem::wm::Memory&) override;
-        void store(const armem::wm::Memory&) override;
-
         bool forEachCoreSegment(std::function<void(CoreSegment&)>&& func) const override;
 
         std::shared_ptr<CoreSegment> findCoreSegment(const std::string&) const override;
 
     protected:
+        void _loadAll(armem::wm::Memory&) override;
+        void _load(armem::wm::Memory&) override;
+        void _directlyStore(const armem::wm::Memory&) override;
+
         std::string getExpectedFolderName() const override;
+
     };
 } // namespace armarx::armem::server::ltm::disk
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp
index bc3310c11..ec0eee681 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.cpp
@@ -67,29 +67,28 @@ namespace armarx::armem::server::ltm::disk
         return name();
     }
 
-    armem::wm::ProviderSegment ProviderSegment::loadAll()
+    void ProviderSegment::_loadAll(armem::wm::ProviderSegment& e)
     {
-        armem::wm::ProviderSegment e(id());
+        e.id() = id();
 
         forEachEntity([&e](Entity& x) {
-            auto s = x.loadAll();
+            armem::wm::Entity s;
+            x.loadAll(s);
             e.addEntity(s);
         });
-
-        return e;
     }
 
-    void ProviderSegment::convert(armem::wm::ProviderSegment& p)
+    void ProviderSegment::_load(armem::wm::ProviderSegment& p)
     {
         p.forEachEntity([this](armem::wm::Entity& e)
         {
             util::ensureFolderExists(std::filesystem::path(path) / e.id().entityName, false);
             Entity c(std::filesystem::path(path) / e.id().entityName);
-            c.convert(e);
+            c.load(e);
         });
     }
 
-    void ProviderSegment::store(const armem::wm::ProviderSegment& p)
+    void ProviderSegment::_store(const armem::wm::ProviderSegment& p)
     {
         p.forEachEntity([this](const armem::wm::Entity& e)
         {
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h
index 45ed5c8ac..80524afd0 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/ProviderSegment.h
@@ -15,18 +15,17 @@ namespace armarx::armem::server::ltm::disk
             public DiskStorage
     {
     public:
-        using ProviderSegmentBase::ProviderSegmentBase;
         ProviderSegment(const std::filesystem::path&);
 
-        armem::wm::ProviderSegment loadAll() override;
-        void convert(armem::wm::ProviderSegment&) override;
-        void store(const armem::wm::ProviderSegment&) override;
-
         bool forEachEntity(std::function<void(Entity&)>&& func) const override;
 
         std::shared_ptr<Entity> findEntity(const std::string&) const override;
 
     protected:
+        void _loadAll(armem::wm::ProviderSegment&) override;
+        void _load(armem::wm::ProviderSegment&) override;
+        void _store(const armem::wm::ProviderSegment&) override;
+
         std::string getExpectedFolderName() const override;
     };
 
diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h
index f5dc9078f..6adbf12e2 100644
--- a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h
+++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/Data.h
@@ -8,9 +8,9 @@ namespace armarx::armem::server::ltm::disk
 {
     namespace constantes
     {
-        const std::string TYPE_FILENAME = "type.aron.json";
-        const std::string DATA_FILENAME = "data.aron.json";
-        const std::string METADATA_FILENAME = "metadata.aron.json";
+        const std::string TYPE_FILENAME = "type.aron";
+        const std::string DATA_FILENAME = "data.aron";
+        const std::string METADATA_FILENAME = "metadata.aron";
     }
 
     namespace util
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h
index 405abb2e3..a0be62d21 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/ltm/detail/EntityQueryProcessorBase.h
@@ -18,7 +18,7 @@ namespace armarx::armem::server::query_proc::ltm::detail
         using EntityT = typename Base::EntityT;
         using EntitySnapshotT = typename Base::EntitySnapshotT;
         using ResultEntityT = typename Base::ResultEntityT;
-        using ResultSnapshotT = typename Base::EntitySnapshotT;
+        using ResultSnapshotT = typename Base::ResultSnapshotT;
 
     public:
         virtual ~EntityQueryProcessorBase() = default;
@@ -29,7 +29,9 @@ namespace armarx::armem::server::query_proc::ltm::detail
     protected:
         void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const override
         {
-            result.addSnapshot(snapshot.loadAll());
+            ResultSnapshotT s;
+            snapshot.loadAll(s);
+            result.addSnapshot(s);
         }
     };
 }
diff --git a/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp b/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp
index a5d1b1a81..e539ce52d 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemLTMBenchmark.cpp
@@ -83,14 +83,14 @@ BOOST_AUTO_TEST_CASE(test_memory_export__benchmark)
     ltm.setMemoryID(ltm.id().withMemoryName("Test"));
 
     auto data = std::make_shared<aron::data::Dict>();
-    //auto member1 = std::make_shared<aron::data::Int>(42);
-    //auto member2 = std::make_shared<aron::data::String>("Hallo Welt");
-    //data->addElement("Member1", member1);
-    //data->addElement("Member2", member2);
-
-    std::vector<int> dimensions = {1280, 720, 3};
-    std::string type = "0";
-    std::vector<unsigned char> d(1280*720*3, 0);
+    auto member1 = std::make_shared<aron::data::Int>(42);
+    auto member2 = std::make_shared<aron::data::String>("Hallo Welt");
+    data->addElement("Member1", member1);
+    data->addElement("Member2", member2);
+
+    std::vector<int> dimensions = {720, 1280, 3};
+    std::string type = "16";
+    std::vector<unsigned char> d(720*1280*3, 255);
     data->addElement("image", std::make_shared<aron::data::NDArray>(dimensions, type, d));
 
     armem::wm::Memory wm("Test");
@@ -105,9 +105,10 @@ BOOST_AUTO_TEST_CASE(test_memory_export__benchmark)
         en.clear();
         auto& snap = en.addSnapshot(IceUtil::Time::now());
         auto& ins = snap.addInstance();
-        ins.data() = data;
+        auto cloned = aron::data::Dict::DynamicCastAndCheck(data->clone());
+        ins.data() = cloned;
 
-        ltm.append(wm);
+        ltm.store(wm);
         ltm.storeBuffer();
     }
 
diff --git a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp
index 2306f3c60..5d4542d2f 100644
--- a/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/disk/ControlWidget.cpp
@@ -103,7 +103,7 @@ namespace armarx::armem::gui::disk
                     std::filesystem::create_directories(path / name);
 
                     armem::server::ltm::disk::Memory memory((path / name));
-                    memory.append(data);
+                    memory.store(data);
                     memory.storeBuffer();
 
                     numStored++;
@@ -147,7 +147,10 @@ namespace armarx::armem::gui::disk
                 if (dir.is_directory())
                 {
                     armem::server::ltm::disk::Memory ltm(dir.path());
-                    armem::wm::Memory memory = ltm.loadAll();
+
+                    armem::wm::Memory memory;
+                    ltm.loadAll(memory);
+
                     memoryData[memory.name()] = std::move(memory);
 
                     numLoaded++;
diff --git a/source/RobotAPI/libraries/armem_gui/instance/display_visitors/DataDisplayVisitor.h b/source/RobotAPI/libraries/armem_gui/instance/display_visitors/DataDisplayVisitor.h
index 765cb6026..1595e6ffb 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/display_visitors/DataDisplayVisitor.h
+++ b/source/RobotAPI/libraries/armem_gui/instance/display_visitors/DataDisplayVisitor.h
@@ -8,7 +8,7 @@
 namespace armarx::aron
 {
 
-    class DataDisplayVisitor : public aron::data::VariantVisitor
+    class DataDisplayVisitor : public aron::data::ConstVariantVisitor
     {
     public:
         static std::string getValue(const data::VariantPtr& n);
diff --git a/source/RobotAPI/libraries/armem_gui/instance/display_visitors/TypedDataDisplayVisitor.h b/source/RobotAPI/libraries/armem_gui/instance/display_visitors/TypedDataDisplayVisitor.h
index e05d92031..fa42d27ad 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/display_visitors/TypedDataDisplayVisitor.h
+++ b/source/RobotAPI/libraries/armem_gui/instance/display_visitors/TypedDataDisplayVisitor.h
@@ -11,7 +11,7 @@
 namespace armarx::aron
 {
 
-    class TypedDataDisplayVisitor : public aron::data::TypedVariantVisitor
+    class TypedDataDisplayVisitor : public aron::data::ConstTypedVariantVisitor
     {
     public:
 
diff --git a/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeDataVisitor.h b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeDataVisitor.h
index d65c6bc3f..a34459ee1 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeDataVisitor.h
+++ b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeDataVisitor.h
@@ -13,7 +13,7 @@ namespace armarx::armem::gui::instance
 {
 
     class TreeDataVisitor :
-        public aron::data::RecursiveVariantVisitor,
+        public aron::data::RecursiveConstVariantVisitor,
         public TreeDataVisitorBase
     {
     public:
@@ -21,57 +21,57 @@ namespace armarx::armem::gui::instance
         using TreeDataVisitorBase::TreeDataVisitorBase;
 
 
-        void visitDictOnEnter(const std::string& key, const aron::data::VariantPtr& n) override
+        void visitDictOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& n) override
         {
             _visitEnter(key, "Dict", n->childrenSize());
         }
-        void visitDictOnExit(const std::string&, const aron::data::VariantPtr&) override
+        void visitDictOnExit(const std::string&, const aron::data::VariantPtr&, const aron::data::VariantPtr&) override
         {
             _visitExit();
         }
 
-        void visitListOnEnter(const std::string& key, const aron::data::VariantPtr& n) override
+        void visitListOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& n) override
         {
             _visitEnter(key, "List", n->childrenSize());
         }
-        void visitListOnExit(const std::string&, const aron::data::VariantPtr&) override
+        void visitListOnExit(const std::string&, const aron::data::VariantPtr&, const aron::data::VariantPtr&) override
         {
             _visitExit();
         }
 
 
-        void visitBool(const std::string& key, const aron::data::VariantPtr& b) override
+        void visitBool(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& b) override
         {
             const auto x = *aron::data::Bool::DynamicCastAndCheck(b);
             this->addValueRow(key, x, "Bool");
         }
-        void visitDouble(const std::string& key, const aron::data::VariantPtr& d) override
+        void visitDouble(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& d) override
         {
             const auto x = *aron::data::Double::DynamicCastAndCheck(d);
             this->addValueRow(key, x, "Double");
         }
-        void visitFloat(const std::string& key, const aron::data::VariantPtr& f) override
+        void visitFloat(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& f) override
         {
             const auto x = *aron::data::Float::DynamicCastAndCheck(f);
             this->addValueRow(key, x, "Float");
         }
-        void visitInt(const std::string& key, const aron::data::VariantPtr& i) override
+        void visitInt(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& i) override
         {
             const auto x = *aron::data::Int::DynamicCastAndCheck(i);
             this->addValueRow(key, x, "Int");
         }
-        void visitLong(const std::string& key, const aron::data::VariantPtr& l) override
+        void visitLong(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& l) override
         {
             const auto x = *aron::data::Long::DynamicCastAndCheck(l);
             this->addValueRow(key, x, "Long");
         }
-        void visitString(const std::string& key, const aron::data::VariantPtr& string) override
+        void visitString(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& string) override
         {
             const auto x = *aron::data::String::DynamicCastAndCheck(string);
             this->addValueRow(key, x, "String");
         }
 
-        void visitNDArray(const std::string& key, const aron::data::VariantPtr& array) override
+        void visitNDArray(const std::string& key, const aron::data::VariantPtr&, const aron::data::VariantPtr& array) override
         {
             const auto x = *aron::data::NDArray::DynamicCastAndCheck(array);
             this->addValueRow(key, x, "ND Array");
diff --git a/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedDataVisitor.h b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedDataVisitor.h
index 1941fb5f7..72848d6ea 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedDataVisitor.h
+++ b/source/RobotAPI/libraries/armem_gui/instance/tree_visitors/TreeTypedDataVisitor.h
@@ -20,7 +20,7 @@ namespace armarx::armem::gui::instance
 {
 
     class TreeTypedDataVisitor :
-        public aron::data::RecursiveTypedVariantVisitor,
+        public aron::data::RecursiveConstTypedVariantVisitor,
         public TreeDataVisitorBase
     {
     public:
@@ -28,81 +28,81 @@ namespace armarx::armem::gui::instance
         using TreeDataVisitorBase::TreeDataVisitorBase;
 
 
-        void visitDictOnEnter(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitDictOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitEnter(key, sanitizeTypeName(type->getFullName()), data->childrenSize());
         }
-        void visitDictOnExit(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitDictOnExit(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitExit();
         }
 
-        void visitObjectOnEnter(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitObjectOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitEnter(key, sanitizeTypeName(type->getFullName()), data->childrenSize());
         }
-        void visitObjectOnExit(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitObjectOnExit(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitExit();
         }
 
-        void visitListOnEnter(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitListOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitEnter(key, sanitizeTypeName(type->getFullName()), data->childrenSize());
         }
-        void visitListOnExit(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitListOnExit(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitExit();
         }
 
-        void visitTupleOnEnter(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitTupleOnEnter(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitEnter(key, sanitizeTypeName(type->getFullName()), data->childrenSize());
         }
-        void visitTupleOnExit(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitTupleOnExit(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             _visitExit();
         }
         // What about Pair??
 
 
-        void visitBool(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitBool(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::Bool::DynamicCastAndCheck(data);
             auto t = *aron::type::Bool::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitDouble(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitDouble(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::Double::DynamicCastAndCheck(data);
             auto t = *aron::type::Double::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitFloat(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitFloat(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::Float::DynamicCastAndCheck(data);
             auto t = *aron::type::Float::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitInt(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitInt(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::Int::DynamicCastAndCheck(data);
             auto t = *aron::type::Int::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitLong(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitLong(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::Long::DynamicCastAndCheck(data);
             auto t = *aron::type::Long::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitString(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitString(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::String::DynamicCastAndCheck(data);
             auto t = *aron::type::String::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitTime(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitTime(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::Long::DynamicCastAndCheck(data);
             auto t = *aron::type::Time::DynamicCastAndCheck(type);
@@ -110,43 +110,43 @@ namespace armarx::armem::gui::instance
         }
 
 
-        void visitMatrix(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitMatrix(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::Matrix::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitQuaternion(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitQuaternion(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::Quaternion::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitPointCloud(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitPointCloud(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::PointCloud::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitPose(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitPose(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::Pose::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitPosition(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitPosition(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::Position::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitImage(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitImage(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::Image::DynamicCastAndCheck(type);
             this->addValueRow(key, d, t);
         }
-        void visitOrientation(const std::string& key, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
+        void visitOrientation(const std::string& key, const aron::data::VariantPtr&, const aron::type::VariantPtr&, const aron::data::VariantPtr& data, const aron::type::VariantPtr& type) override
         {
             auto d = *aron::data::NDArray::DynamicCastAndCheck(data);
             auto t = *aron::type::Orientation::DynamicCastAndCheck(type);
diff --git a/source/RobotAPI/libraries/aron/converter/opencv/OpenCVConverter.cpp b/source/RobotAPI/libraries/aron/converter/opencv/OpenCVConverter.cpp
index 7659581fc..6208bd9b4 100644
--- a/source/RobotAPI/libraries/aron/converter/opencv/OpenCVConverter.cpp
+++ b/source/RobotAPI/libraries/aron/converter/opencv/OpenCVConverter.cpp
@@ -40,7 +40,8 @@ namespace armarx::aron::converter
         auto dims = nav->getShape();
 
         cv::Mat ret(std::vector<int>({dims.begin(), std::prev(dims.end())}), std::stoi(nav->getType()));
-        memcpy(reinterpret_cast<unsigned char*>(ret.data), nav->getData(), std::accumulate(std::begin(dims), std::end(dims), 1, std::multiplies<int>()));
+        auto size = std::accumulate(std::begin(dims), std::end(dims), 1, std::multiplies<int>());
+        memcpy(reinterpret_cast<unsigned char*>(ret.data), nav->getData(), size);
         return ret;
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Image.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Image.cpp
index c994d831e..7d1226e52 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Image.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/generator/ndarray/Image.cpp
@@ -32,8 +32,8 @@ namespace armarx::aron::codegenerator::cpp::generator
 
     const std::map<type::image::PixelType, std::pair<std::string, int>> Image::PixelType2Cpp =
     {
-        { type::image::PixelType::rgb24,   {"CV_8UC3", 0}},
-        { type::image::PixelType::depth32, {"CV_32FC1", 0}},
+        { type::image::PixelType::rgb24,   {"CV_8UC3", 3}},
+        { type::image::PixelType::depth32, {"CV_32FC1", 4}},
     };
 
 
diff --git a/source/RobotAPI/libraries/aron/core/data/converter/nlohmannJSON/NlohmannJSONConverter.h b/source/RobotAPI/libraries/aron/core/data/converter/nlohmannJSON/NlohmannJSONConverter.h
index e7b423c39..25cd0dc57 100644
--- a/source/RobotAPI/libraries/aron/core/data/converter/nlohmannJSON/NlohmannJSONConverter.h
+++ b/source/RobotAPI/libraries/aron/core/data/converter/nlohmannJSON/NlohmannJSONConverter.h
@@ -33,7 +33,7 @@ namespace armarx::aron::data
     /// WriterImplementation is a writer class, TODO: add concept
     template <class WriterImplementation, class DerivedT>
     struct NlohmannJSONConverter :
-            virtual public NlohmannJSONVisitor,
+            virtual public ConstNlohmannJSONVisitor,
             virtual public Converter<aron::data::reader::NlohmannJSONReader, WriterImplementation, DerivedT>
     {
         virtual ~NlohmannJSONConverter() = default;
diff --git a/source/RobotAPI/libraries/aron/core/data/converter/variant/VariantConverter.h b/source/RobotAPI/libraries/aron/core/data/converter/variant/VariantConverter.h
index be8a7c670..4173e7143 100644
--- a/source/RobotAPI/libraries/aron/core/data/converter/variant/VariantConverter.h
+++ b/source/RobotAPI/libraries/aron/core/data/converter/variant/VariantConverter.h
@@ -34,7 +34,7 @@ namespace armarx::aron::data
     /// WriterImplementation is a writer class, TODO: add concept
     template <class WriterImplementation, class DerivedT>
     struct VariantConverter :
-            virtual public VariantVisitor,
+            virtual public ConstVariantVisitor,
             virtual public Converter<aron::data::reader::VariantReader, WriterImplementation, DerivedT>
     {
         virtual ~VariantConverter() = default;
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/Variant.h b/source/RobotAPI/libraries/aron/core/data/variant/Variant.h
index dc37a2d09..be3d93336 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/Variant.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/Variant.h
@@ -95,20 +95,6 @@ namespace armarx::aron::data
         /// return a list of dto objects from a list of variant objects
         static std::vector<data::dto::GenericDataPtr> ToAronDTO(const std::vector<VariantPtr>&);
 
-        /// Static cast an arbitrary variantptr (e.g. IntPtr) to VariantPtr
-        /// Trick for automatic template deduction
-        static const VariantPtr StaticCast(const VariantPtr& p)
-        {
-            return p;
-        }
-
-        /// Static cast an arbitrary variantptr (e.g. IntPtr) to VariantPtr
-        /// Trick for automatic template deduction
-        static VariantPtr StaticCast(VariantPtr& p)
-        {
-            return p;
-        }
-
         /// getter for the descriptor enum
         data::Descriptor getDescriptor() const
         {
@@ -128,6 +114,9 @@ namespace armarx::aron::data
         }
 
         // virtual definitions
+        /// get a pointer to a copy of this variant
+        virtual VariantPtr clone() const = 0;
+
         /// get the children of a data variant
         virtual std::vector<VariantPtr> getChildren() const = 0;
 
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h
index dab077188..31677060a 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h
@@ -84,6 +84,12 @@ namespace armarx::aron::data
         data::dto::NDArrayPtr toNDArrayDTO() const;
 
         // virtual implementations
+        virtual VariantPtr clone() const override
+        {
+            NDArrayPtr ret(new NDArray(getShape(), getType(), getDataAsVector(), getPath()));
+            return ret;
+        }
+
         virtual std::string getShortName() const override;
         virtual std::string getFullName() const override;
 
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
index 387a983fa..62fa05d24 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp
@@ -119,16 +119,11 @@ namespace armarx::aron::data
 
     void Dict::addElement(const std::string& key, const VariantPtr& data)
     {
-        if (data)
+        if (hasElement(key))
         {
-            this->childrenNavigators[key] = data;
-            this->aron->elements[key] = data->toAronDTO();
-        }
-        else
-        {
-            this->childrenNavigators[key] = nullptr;
-            this->aron->elements[key] = nullptr;
+            throw error::AronException(__PRETTY_FUNCTION__, "The key '"+key+"' already exists in a aron dict.");
         }
+        setElement(key, data);
     }
 
     bool Dict::hasElement(const std::string& key) const
@@ -156,6 +151,19 @@ namespace armarx::aron::data
         return childrenNavigators;
     }
 
+    void Dict::setElement(const std::string& key, const VariantPtr& data)
+    {
+        this->childrenNavigators[key] = data;
+        if (data)
+        {
+            this->aron->elements[key] = data->toAronDTO();
+        }
+        else
+        {
+            this->aron->elements[key] = nullptr;
+        }
+    }
+
     void Dict::removeElement(const std::string& key)
     {
         childrenNavigators.erase(key);
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h
index bd823a1bd..01842e78a 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h
@@ -62,14 +62,24 @@ namespace armarx::aron::data
 
         void addElement(const std::string& key, const VariantPtr&);
         bool hasElement(const std::string&) const;
+        void setElement(const std::string&, const VariantPtr&);
         VariantPtr getElement(const std::string&) const;
         std::map<std::string, VariantPtr> getElements() const;
 
         void removeElement(const std::string& key);
-
         void clear();
 
-        // virtual implementations
+        // virtual implementations        
+        virtual VariantPtr clone() const override
+        {
+            DictPtr ret(new Dict(getPath()));
+            for (const auto& [key, val] : getElements())
+            {
+                ret->addElement(key, val->clone());
+            }
+            return ret;
+        }
+
         virtual std::string getShortName() const override;
         virtual std::string getFullName() const override;
         virtual std::vector<VariantPtr> getChildren() const override;
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
index e144e9d6a..23cc7b8d2 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp
@@ -114,15 +114,39 @@ namespace armarx::aron::data
 
     void List::addElement(const VariantPtr& n)
     {
-        if (n)
+        setElement(aron->elements.size(), n);
+    }
+
+    void List::setElement(unsigned int i, const VariantPtr& n)
+    {
+        if (i > aron->elements.size())
+        {
+            error::AronException(__PRETTY_FUNCTION__, "Cannot set a listelement at index " + std::to_string(i) + " because this list has size " + std::to_string(aron->elements.size()));
+        }
+
+        if (i == aron->elements.size())
         {
             childrenNavigators.push_back(n);
-            aron->elements.push_back(n->toAronDTO());
+            if (n)
+            {
+                aron->elements.push_back(n->toAronDTO());
+            }
+            else
+            {
+                aron->elements.push_back(nullptr);
+            }
         }
         else
         {
-            childrenNavigators.push_back(nullptr);
-            aron->elements.push_back(nullptr);
+            childrenNavigators[i] = n;
+            if (n)
+            {
+                aron->elements[i] = (n->toAronDTO());
+            }
+            else
+            {
+                aron->elements[i] = nullptr;
+            }
         }
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/List.h b/source/RobotAPI/libraries/aron/core/data/variant/container/List.h
index ef36e026b..d70929e1f 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/container/List.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/container/List.h
@@ -63,6 +63,7 @@ namespace armarx::aron::data
         data::dto::ListPtr toAronListPtr() const;
 
         void addElement(const VariantPtr&);
+        void setElement(unsigned int, const VariantPtr&);
         VariantPtr getElement(unsigned int) const;
         bool hasElement(unsigned int) const;
         std::vector<VariantPtr> getElements() const;
@@ -72,6 +73,15 @@ namespace armarx::aron::data
         void clear();
 
         // virtual implementations
+        virtual VariantPtr clone() const override
+        {
+            ListPtr ret(new List(getPath()));
+            for (const auto& val : getElements())
+            {
+                ret->addElement(val->clone());
+            }
+            return ret;
+        }
         virtual std::string getShortName() const override;
         virtual std::string getFullName() const override;
         virtual std::vector<VariantPtr> getChildren() const override;
diff --git a/source/RobotAPI/libraries/aron/core/data/variant/detail/PrimitiveVariant.h b/source/RobotAPI/libraries/aron/core/data/variant/detail/PrimitiveVariant.h
index 8033edf4f..e2c479bbe 100644
--- a/source/RobotAPI/libraries/aron/core/data/variant/detail/PrimitiveVariant.h
+++ b/source/RobotAPI/libraries/aron/core/data/variant/detail/PrimitiveVariant.h
@@ -72,6 +72,12 @@ namespace armarx::aron::data::detail
         }*/
 
         // virtual implementations
+        virtual VariantPtr clone() const override
+        {
+            typename DerivedT::PointerType ret(new DerivedT(getValue(), this->getPath()));
+            return ret;
+        }
+
         virtual std::vector<VariantPtr> getChildren() const override
         {
             return {};
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
index 97280fb35..a46373175 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/RecursiveVisitor.h
@@ -34,49 +34,49 @@ namespace armarx::aron::data
      * @see type/visitor/RecursiveVisitor.h
      */
     template <class RecursiveVisitorImplementation>
-    void visitRecursive(RecursiveVisitorImplementation& v, const std::string& key, typename RecursiveVisitorImplementation::Input& o)
+    void visitRecursive(RecursiveVisitorImplementation& v, typename RecursiveVisitorImplementation::Input& o, const std::string& key, typename RecursiveVisitorImplementation::Input& po)
     {
         data::Descriptor descriptor = v.getDescriptor(o);
         switch (descriptor)
         {
             case data::Descriptor::eList:
             {
-                v.visitListOnEnter(key, o);
+                v.visitListOnEnter(key, po, o);
                 unsigned int i = 0;
-                for (const auto& value : v.getListElements(o))
+                for (auto& value : v.getListElements(o))
                 {
-                    visitRecursive(v, std::to_string(i), value);
+                    visitRecursive(v, value, std::to_string(i), o);
                     i++;
                 }
-                v.visitListOnExit(key, o);
+                v.visitListOnExit(key, po, o);
                 return;
             }
             case data::Descriptor::eDict:
             {
-                v.visitDictOnEnter(key, o);
-                for (const auto& [key, value] : v.getDictElements(o))
+                v.visitDictOnEnter(key, po, o);
+                for (auto& [key, value] : v.getDictElements(o))
                 {
-                    visitRecursive(v, key, value);
+                    visitRecursive(v, value, key, o);
                 }
-                v.visitDictOnExit(key, o);
+                v.visitDictOnExit(key, po, o);
                 return;
             }
             case data::Descriptor::eNDArray:
-                return v.visitNDArray(key, o);
+                return v.visitNDArray(key, po, o);
             case data::Descriptor::eInt:
-                return v.visitInt(key, o);
+                return v.visitInt(key, po, o);
             case data::Descriptor::eLong:
-                return v.visitLong(key, o);
+                return v.visitLong(key, po, o);
             case data::Descriptor::eFloat:
-                return v.visitFloat(key, o);
+                return v.visitFloat(key, po, o);
             case data::Descriptor::eDouble:
-                return v.visitDouble(key, o);
+                return v.visitDouble(key, po, o);
             case data::Descriptor::eString:
-                return v.visitString(key, o);
+                return v.visitString(key, po, o);
             case data::Descriptor::eBool:
-                return v.visitBool(key, o);
+                return v.visitBool(key, po, o);
             case data::Descriptor::eUnknown:
-                return v.visitUnknown(key, o);
+                return v.visitUnknown(key, po, o);
         }
     }
 
@@ -85,100 +85,100 @@ namespace armarx::aron::data
      * @see data/visitor/Visitor.h
      */
     template <class RecursiveVisitorImplementation>
-    void visitRecursive(RecursiveVisitorImplementation& v, const std::string& key, typename RecursiveVisitorImplementation::DataInput& o, typename RecursiveVisitorImplementation::TypeInput& t)
+    void visitRecursive(RecursiveVisitorImplementation& v, typename RecursiveVisitorImplementation::DataInput& o, typename RecursiveVisitorImplementation::TypeInput& t, const std::string& key, typename RecursiveVisitorImplementation::DataInput& po, typename RecursiveVisitorImplementation::TypeInput& pt)
     {
         type::Descriptor descriptor = v.getDescriptor(t);
         switch (descriptor)
         {
             case type::Descriptor::eList:
             {
-                v.visitListOnEnter(key, o, t);
+                v.visitListOnEnter(key, po, pt, o, t);
                 unsigned int i = 0;
-                for (const auto& [value, acceptedType] : v.getListElements(o, t))
+                for (auto& [value, acceptedType] : v.getListElements(o, t))
                 {
-                    visitRecursive(v, std::to_string(i), value, acceptedType);
+                    visitRecursive(v, value, acceptedType, std::to_string(i), o, t);
                     i++;
                 }
-                v.visitListOnExit(key, o, t);
+                v.visitListOnExit(key, po, pt, o, t);
                 return;
             }
             case type::Descriptor::ePair:
             {
-                v.visitPairOnEnter(key, o, t);
+                v.visitPairOnEnter(key, po, pt, o, t);
                 auto pair = v.getPairElements(o, t);
                 auto first = pair.first;
                 auto second = pair.second;
-                visitRecursive(v, "1", first.first, first.second);
-                visitRecursive(v, "2", second.first, second.second);
-                v.visitPairOnExit(key, o, t);
+                visitRecursive(v, first.first, first.second, "1", o, t);
+                visitRecursive(v, second.first, second.second, "2", o, t);
+                v.visitPairOnExit(key, po, pt, o, t);
                 return;
             }
             case type::Descriptor::eTuple:
             {
-                v.visitTupleOnEnter(key, o, t);
+                v.visitTupleOnEnter(key, po, pt, o, t);
                 unsigned int i = 0;
-                for (const auto& [value, acceptedType] : v.getTupleElements(o, t))
+                for (auto& [value, acceptedType] : v.getTupleElements(o, t))
                 {
-                    visitRecursive(v, std::to_string(i), value, acceptedType);
+                    visitRecursive(v, value, acceptedType, std::to_string(i), o, t);
                     i++;
                 }
-                v.visitTupleOnExit(key, o, t);
+                v.visitTupleOnExit(key, po, pt, o, t);
                 return;
             }
             case type::Descriptor::eDict:
             {
-                    v.visitDictOnEnter(key, o, t);
-                    for (const auto& [key, value, acceptedType] : v.getDictElements(o, t))
+                    v.visitDictOnEnter(key, po, pt, o, t);
+                    for (auto& [key, value, acceptedType] : v.getDictElements(o, t))
                     {
-                        visitRecursive(v, key, value, acceptedType);
+                        visitRecursive(v, value, acceptedType, key, o, t);
                     }
-                    v.visitDictOnExit(key, o, t);
+                    v.visitDictOnExit(key, po, pt, o, t);
                     return;
             }
             case type::Descriptor::eObject:
             {
-                v.visitObjectOnEnter(key, o, t);
-                for (const auto& [key, value, acceptedType] : v.getObjectElements(o, t))
+                v.visitObjectOnEnter(key, po, pt, o, t);
+                for (auto& [key, value, acceptedType] : v.getObjectElements(o, t))
                 {
-                    visitRecursive(v, key, value, acceptedType);
+                    visitRecursive(v, value, acceptedType, key, o, t);
                 }
-                v.visitObjectOnExit(key, o, t);
+                v.visitObjectOnExit(key, po, pt, o, t);
                 return;
             }
             case type::Descriptor::eNDArray:
-                return v.visitNDArray(key, o, t);
+                return v.visitNDArray(key, po, pt, o, t);
             case type::Descriptor::eMatrix:
-                return v.visitMatrix(key, o, t);
+                return v.visitMatrix(key, po, pt, o, t);
             case type::Descriptor::eOrientation:
-                return v.visitOrientation(key, o, t);
+                return v.visitOrientation(key, po, pt, o, t);
             case type::Descriptor::eImage:
-                return v.visitImage(key, o, t);
+                return v.visitImage(key, po, pt, o, t);
             case type::Descriptor::ePointCloud:
-                return v.visitPointCloud(key, o, t);
+                return v.visitPointCloud(key, po, pt, o, t);
             case type::Descriptor::ePosition:
-                return v.visitPosition(key, o, t);
+                return v.visitPosition(key, po, pt, o, t);
             case type::Descriptor::ePose:
-                return v.visitPose(key, o, t);
+                return v.visitPose(key, po, pt, o, t);
             case type::Descriptor::eQuaternion:
-                return v.visitQuaternion(key, o, t);
+                return v.visitQuaternion(key, po, pt, o, t);
             case type::Descriptor::eInt:
-                return v.visitInt(key, o, t);
+                return v.visitInt(key, po, pt, o, t);
             case type::Descriptor::eLong:
-                return v.visitLong(key, o, t);
+                return v.visitLong(key, po, pt, o, t);
             case type::Descriptor::eFloat:
-                return v.visitFloat(key, o, t);
+                return v.visitFloat(key, po, pt, o, t);
             case type::Descriptor::eDouble:
-                return v.visitDouble(key, o, t);
+                return v.visitDouble(key, po, pt, o, t);
             case type::Descriptor::eString:
-                return v.visitString(key, o, t);
+                return v.visitString(key, po, pt, o, t);
             case type::Descriptor::eBool:
-                return v.visitBool(key, o, t);
+                return v.visitBool(key, po, pt, o, t);
             case type::Descriptor::eTime:
-                return v.visitTime(key, o, t);
+                return v.visitTime(key, po, pt, o, t);
             case type::Descriptor::eIntEnum:
-                return v.visitIntEnum(key, o, t);
+                return v.visitIntEnum(key, po, pt, o, t);
             case type::Descriptor::eUnknown:
-                return v.visitUnknown(key, o, t);
+                return v.visitUnknown(key, po, pt, o, t);
         }
     }
 
@@ -194,19 +194,19 @@ namespace armarx::aron::data
         virtual std::map<std::string, InputNonConst> getDictElements(Input&) = 0;
         virtual std::vector<InputNonConst> getListElements(Input&) = 0;
 
-        virtual void visitDictOnEnter(const std::string& key, Input&) {};
-        virtual void visitDictOnExit(const std::string& key, Input&) {};
-        virtual void visitListOnEnter(const std::string& key, Input&) {};
-        virtual void visitListOnExit(const std::string& key, Input&) {};
+        virtual void visitDictOnEnter(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitDictOnExit(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitListOnEnter(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitListOnExit(const std::string& key, Input& parent, Input& element) {};
 
-        virtual void visitNDArray(const std::string& key, Input&) {};
-        virtual void visitInt(const std::string& key, Input&) {};
-        virtual void visitLong(const std::string& key, Input&) {};
-        virtual void visitFloat(const std::string& key, Input&) {};
-        virtual void visitDouble(const std::string& key, Input&) {};
-        virtual void visitBool(const std::string& key, Input&) {};
-        virtual void visitString(const std::string& key, Input&) {};
-        virtual void visitUnknown(const std::string&, Input&) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
+        virtual void visitNDArray(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitInt(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitLong(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitFloat(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitDouble(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitBool(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitString(const std::string& key, Input& parent, Input& element) {};
+        virtual void visitUnknown(const std::string& key, Input& parent, Input& element) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
         virtual ~RecursiveVisitor() = default;
     };
 
@@ -228,34 +228,34 @@ namespace armarx::aron::data
         virtual std::pair<std::pair<DataInputNonConst, TypeInputNonConst>, std::pair<DataInputNonConst, TypeInputNonConst>> getPairElements(DataInput&, TypeInput&) = 0;
         virtual std::vector<std::pair<DataInputNonConst, TypeInputNonConst>> getTupleElements(DataInput&, TypeInput&) = 0;
 
-        virtual void visitObjectOnEnter(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitObjectOnExit(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitDictOnEnter(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitDictOnExit(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitPairOnEnter(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitPairOnExit(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitTupleOnEnter(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitTupleOnExit(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitListOnEnter(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitListOnExit(const std::string& key, DataInput&, TypeInput&) {};
+        virtual void visitObjectOnEnter(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitObjectOnExit(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitDictOnEnter(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitDictOnExit(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPairOnEnter(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPairOnExit(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitTupleOnEnter(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitTupleOnExit(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitListOnEnter(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitListOnExit(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
 
-        virtual void visitMatrix(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitNDArray(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitQuaternion(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitOrientation(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitPosition(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitPose(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitImage(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitPointCloud(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitIntEnum(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitInt(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitLong(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitFloat(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitDouble(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitBool(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitString(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitTime(const std::string& key, DataInput&, TypeInput&) {};
-        virtual void visitUnknown(const std::string&, DataInput&, TypeInput&) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
+        virtual void visitMatrix(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitNDArray(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitQuaternion(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitOrientation(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPosition(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPose(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitImage(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitPointCloud(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitIntEnum(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitInt(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitLong(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitFloat(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitDouble(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitBool(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitString(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitTime(const std::string& key, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) {};
+        virtual void visitUnknown(const std::string&, DataInput& parentData, TypeInput& parentType, DataInput& elementData, TypeInput& elementType) { throw error::AronException(__PRETTY_FUNCTION__, "Unknown type in visitor."); }
         virtual ~RecursiveTypedVisitor() = default;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.h
index 4042cd195..7ff87236d 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/nlohmannJSON/NlohmannJSONVisitor.h
@@ -39,7 +39,7 @@ namespace armarx::aron::data
     /**
      * @see type/visitor/nlohmannJSON/NlohmannJSONVisitor.h
      */
-    struct NlohmannJSONVisitor : virtual public Visitor<const nlohmann::json>
+    struct ConstNlohmannJSONVisitor : virtual public Visitor<const nlohmann::json>
     {
         virtual data::Descriptor getDescriptor(Input& n) override
         {
@@ -51,7 +51,7 @@ namespace armarx::aron::data
             return armarx::aron::data::rw::json::conversion::String2Descriptor.at(t);
         }
 
-        virtual ~NlohmannJSONVisitor() = default;
+        virtual ~ConstNlohmannJSONVisitor() = default;
     };
 
     // TODO
diff --git a/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h b/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h
index b4faa7485..c0e3f66e6 100644
--- a/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h
+++ b/source/RobotAPI/libraries/aron/core/data/visitor/variant/VariantVisitor.h
@@ -35,7 +35,7 @@ namespace armarx::aron::data
     /**
      * @see type/visitor/variant/VariantVisitor.h
      */
-    struct VariantVisitor : virtual public Visitor<const data::VariantPtr>
+    struct ConstVariantVisitor : virtual public Visitor<const data::VariantPtr>
     {
         virtual data::Descriptor getDescriptor(Input& n) override
         {
@@ -46,13 +46,13 @@ namespace armarx::aron::data
             return n->getDescriptor();
         }
 
-        virtual ~VariantVisitor() = default;
+        virtual ~ConstVariantVisitor() = default;
     };
 
     /**
      * @see type/visitor/variant/VariantVisitor.h
      */
-    struct TypedVariantVisitor : virtual public TypedVisitor<const data::VariantPtr, const type::VariantPtr>
+    struct ConstTypedVariantVisitor : virtual public TypedVisitor<const data::VariantPtr, const type::VariantPtr>
     {
         virtual type::Descriptor getDescriptor(TypeInput& n) override
         {
@@ -63,13 +63,42 @@ namespace armarx::aron::data
             return n->getDescriptor();
         }
 
-        virtual ~TypedVariantVisitor() = default;
+        virtual ~ConstTypedVariantVisitor() = default;
     };
 
     /**
      * @see type/visitor/variant/VariantVisitor.h
      */
-    struct RecursiveVariantVisitor : virtual public RecursiveVisitor<const data::VariantPtr>
+    struct RecursiveConstVariantVisitor : virtual public RecursiveVisitor<const data::VariantPtr>
+    {
+        virtual data::Descriptor getDescriptor(Input& n) override
+        {
+            if (!n)
+            {
+                return data::Descriptor::eUnknown;
+            }
+            return n->getDescriptor();
+        }
+
+        virtual std::map<std::string, InputNonConst> getDictElements(Input& n) override
+        {
+            auto x = data::Dict::DynamicCastAndCheck(n);
+            return x->getElements();
+        }
+
+        virtual std::vector<InputNonConst> getListElements(Input& n) override
+        {
+            auto x = data::List::DynamicCastAndCheck(n);
+            return x->getElements();
+        }
+
+        virtual ~RecursiveConstVariantVisitor() = default;
+    };
+
+    /**
+     * @see type/visitor/variant/VariantVisitor.h
+     */
+    struct RecursiveVariantVisitor : virtual public RecursiveVisitor<data::VariantPtr>
     {
         virtual data::Descriptor getDescriptor(Input& n) override
         {
@@ -98,7 +127,7 @@ namespace armarx::aron::data
     /**
      * @see type/visitor/variant/VariantVisitor.h
      */
-    struct RecursiveTypedVariantVisitor : virtual public RecursiveTypedVisitor<const data::VariantPtr, const type::VariantPtr>
+    struct RecursiveConstTypedVariantVisitor : virtual public RecursiveTypedVisitor<const data::VariantPtr, const type::VariantPtr>
     {
         virtual type::Descriptor getDescriptor(TypeInput& n) override
         {
@@ -174,6 +203,6 @@ namespace armarx::aron::data
             return ret;
         }
 
-        virtual ~RecursiveTypedVariantVisitor() = default;
+        virtual ~RecursiveConstTypedVariantVisitor() = default;
     };
 }
-- 
GitLab