diff --git a/scenarios/ArMemExample/ArMemExample.scx b/scenarios/ArMemExample/ArMemExample.scx
index fc00a01308fd61be772d4b3362bca7656d66f34d..49d2a0a435b2f4fdb13424d5d0f20488922b3b3d 100644
--- a/scenarios/ArMemExample/ArMemExample.scx
+++ b/scenarios/ArMemExample/ArMemExample.scx
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <scenario name="ArMemExample" creation="2020-11-10.10:38:44" globalConfigName="./config/global.cfg" package="RobotAPI" deploymentType="local" nodeName="NodeMain">
-	<application name="ArMemExampleMemory" instance="" package="RobotAPI" nodeName="" enabled="true" iceAutoRestart="false"/>
-	<application name="ArMemExampleClient" instance="" package="RobotAPI" nodeName="" enabled="true" iceAutoRestart="false"/>
-	<application name="ArMemMemoryNameSystem" instance="" package="RobotAPI" nodeName="" enabled="true" iceAutoRestart="false"/>
+	<application name="ExampleMemory" instance="" package="RobotAPI" nodeName="" enabled="true" iceAutoRestart="false"/>
+	<application name="ExampleMemoryClient" instance="" package="RobotAPI" nodeName="" enabled="true" iceAutoRestart="false"/>
+	<application name="MemoryNameSystem" instance="" package="RobotAPI" nodeName="" enabled="true" iceAutoRestart="false"/>
 	<application name="RemoteGuiProviderApp" instance="" package="ArmarXGui" nodeName="" enabled="true" iceAutoRestart="false"/>
 	<application name="DebugObserver" instance="" package="ArmarXCore" nodeName="" enabled="true" iceAutoRestart="false"/>
 </scenario>
diff --git a/scenarios/ArMemExample/config/ArMemExampleMemory.cfg b/scenarios/ArMemExample/config/ExampleMemory.cfg
similarity index 79%
rename from scenarios/ArMemExample/config/ArMemExampleMemory.cfg
rename to scenarios/ArMemExample/config/ExampleMemory.cfg
index a7b234054d462683b2dd20aab5b0f08e23a9af69..d0a545f7a2a6c2d0fe730d3169b208760aec0abe 100644
--- a/scenarios/ArMemExample/config/ArMemExampleMemory.cfg
+++ b/scenarios/ArMemExample/config/ExampleMemory.cfg
@@ -1,5 +1,5 @@
 # ==================================================================
-# ArMemExampleMemory properties
+# ExampleMemory properties
 # ==================================================================
 
 # ArmarX.AdditionalPackages:  List of additional ArmarX packages which should be in the list of default packages. If you have custom packages, which should be found by the gui or other apps, specify them here. Comma separated List.
@@ -18,155 +18,163 @@
 # ArmarX.ApplicationName = ""
 
 
-# ArmarX.ArMemExampleMemory.EnableProfiling:  enable profiler which is used for logging performance events
+# ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener:  No Description
 #  Attributes:
-#  - Default:            false
+#  - Default:            MemoryUpdates
+#  - Case sensitivity:   no
+#  - Required:           no
+ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener = MemoryUpdates
+
+
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+#  Attributes:
+#  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ArMemExampleMemory.EnableProfiling = false
+# ArmarX.CachePath = mongo/.cache
 
 
-# ArmarX.ArMemExampleMemory.MinimumLoggingLevel:  Local logging level only for this component
+# ArmarX.Config:  Comma-separated list of configuration files 
 #  Attributes:
-#  - Default:            Undefined
+#  - Default:            ""
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
-# ArmarX.ArMemExampleMemory.MinimumLoggingLevel = Undefined
+# ArmarX.Config = ""
 
 
-# ArmarX.ArMemExampleMemory.ObjectName:  Name of IceGrid well-known object
+# ArmarX.DataPath:  Semicolon-separated search list for data files
 #  Attributes:
 #  - Default:            ""
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleMemory.ObjectName = ""
+# ArmarX.DataPath = ""
 
 
-# ArmarX.ArMemExampleMemory.RemoteGuiName:  Name of the remote gui provider
+# ArmarX.DefaultPackages:  List of ArmarX packages which are accessible by default. Comma separated List. If you want to add your own packages and use all default ArmarX packages, use the property 'AdditionalPackages'.
 #  Attributes:
-#  - Default:            RemoteGuiProvider
+#  - Default:            Default value not mapped.
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleMemory.RemoteGuiName = RemoteGuiProvider
+# ArmarX.DefaultPackages = Default value not mapped.
 
 
-# ArmarX.ArMemExampleMemory.core.AddOnUsage:  If enabled, core segments are added when required by a new provider segment.
+# ArmarX.DependenciesConfig:  Path to the (usually generated) config file containing all data paths of all dependent projects. This property usually does not need to be edited.
 #  Attributes:
-#  - Default:            false
+#  - Default:            ./config/dependencies.cfg
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ArMemExampleMemory.core.AddOnUsage = false
+# ArmarX.DependenciesConfig = ./config/dependencies.cfg
 
 
-# ArmarX.ArMemExampleMemory.core.DefaultSegments:  Core segments to add on start up.
+# ArmarX.DisableLogging:  Turn logging off in whole application
 #  Attributes:
-#  - Default:            ExampleModality, ExampleConcept
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleMemory.core.DefaultSegments = ExampleModality, ExampleConcept
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.DisableLogging = false
 
 
-# ArmarX.ArMemExampleMemory.memory.Name:  Name of this memory.
+# ArmarX.EnableProfiling:  Enable profiling of CPU load produced by this application
 #  Attributes:
-#  - Default:            Example
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleMemory.memory.Name = Example
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.EnableProfiling = false
 
 
-# ArmarX.ArMemExampleMemory.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
-# Set to false to use this memory as a stand-alone.
+# ArmarX.ExampleMemory.EnableProfiling:  enable profiler which is used for logging performance events
 #  Attributes:
-#  - Default:            true
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
 #  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ArMemExampleMemory.mns.MemoryNameSystemEnabled = true
+# ArmarX.ExampleMemory.EnableProfiling = false
 
 
-# ArmarX.ArMemExampleMemory.mns.MemoryNameSystemName:  Name of the Memory Name System (MNS) component.
+# ArmarX.ExampleMemory.MinimumLoggingLevel:  Local logging level only for this component
 #  Attributes:
-#  - Default:            ArMemMemoryNameSystem
+#  - Default:            Undefined
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleMemory.mns.MemoryNameSystemName = ArMemMemoryNameSystem
+#  - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
+# ArmarX.ExampleMemory.MinimumLoggingLevel = Undefined
 
 
-# ArmarX.ArMemExampleMemory.tpc.pub.DebugObserver:  Name of the `DebugObserver` topic to publish data to.
+# ArmarX.ExampleMemory.ObjectName:  Name of IceGrid well-known object
 #  Attributes:
-#  - Default:            DebugObserver
+#  - Default:            ""
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleMemory.tpc.pub.DebugObserver = DebugObserver
+# ArmarX.ExampleMemory.ObjectName = ""
 
 
-# ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener:  Name of the `MemoryListener` topic to publish data to.
+# ArmarX.ExampleMemory.RemoteGuiName:  Name of the remote gui provider
 #  Attributes:
-#  - Default:            MemoryUpdates
+#  - Default:            RemoteGuiProvider
 #  - Case sensitivity:   yes
 #  - Required:           no
-ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener = MemoryUpdates
+# ArmarX.ExampleMemory.RemoteGuiName = RemoteGuiProvider
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.ExampleMemory.core.AddOnUsage:  If enabled, core segments are added when required by a new provider segment.This will usually be off for most memory servers.
 #  Attributes:
-#  - Default:            mongo/.cache
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.CachePath = mongo/.cache
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.ExampleMemory.core.AddOnUsage = false
 
 
-# ArmarX.Config:  Comma-separated list of configuration files 
+# ArmarX.ExampleMemory.core.DefaultSegments:  Core segments to add on start up (just as example).
 #  Attributes:
-#  - Default:            ""
+#  - Default:            ExampleModality, ExampleConcept
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.Config = ""
+# ArmarX.ExampleMemory.core.DefaultSegments = ExampleModality, ExampleConcept
 
 
-# ArmarX.DataPath:  Semicolon-separated search list for data files
+# ArmarX.ExampleMemory.memory.Name:  Name of this memory (server).
 #  Attributes:
-#  - Default:            ""
+#  - Default:            Example
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.DataPath = ""
+# ArmarX.ExampleMemory.memory.Name = Example
 
 
-# ArmarX.DefaultPackages:  List of ArmarX packages which are accessible by default. Comma separated List. If you want to add your own packages and use all default ArmarX packages, use the property 'AdditionalPackages'.
+# ArmarX.ExampleMemory.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
+# Set to false to use this memory as a stand-alone.
 #  Attributes:
-#  - Default:            Default value not mapped.
+#  - Default:            true
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.DefaultPackages = Default value not mapped.
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.ExampleMemory.mns.MemoryNameSystemEnabled = true
 
 
-# ArmarX.DependenciesConfig:  Path to the (usually generated) config file containing all data paths of all dependent projects. This property usually does not need to be edited.
+# ArmarX.ExampleMemory.mns.MemoryNameSystemName:  Name of the Memory Name System (MNS) component.
 #  Attributes:
-#  - Default:            ./config/dependencies.cfg
+#  - Default:            ArMemMemoryNameSystem
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.DependenciesConfig = ./config/dependencies.cfg
+# ArmarX.ExampleMemory.mns.MemoryNameSystemName = ArMemMemoryNameSystem
 
 
-# ArmarX.DisableLogging:  Turn logging off in whole application
+# ArmarX.ExampleMemory.tpc.pub.DebugObserver:  Name of the `DebugObserver` topic to publish data to.
 #  Attributes:
-#  - Default:            false
+#  - Default:            DebugObserver
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.DisableLogging = false
+# ArmarX.ExampleMemory.tpc.pub.DebugObserver = DebugObserver
 
 
-# ArmarX.EnableProfiling:  Enable profiling of CPU load produced by this application
+# ArmarX.ExampleMemory.tpc.pub.MemoryListener:  Name of the `MemoryListener` topic to publish data to.
 #  Attributes:
-#  - Default:            false
+#  - Default:            MemoryUpdates
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.EnableProfiling = false
+# ArmarX.ExampleMemory.tpc.pub.MemoryListener = MemoryUpdates
 
 
 # ArmarX.LoadLibraries:  Libraries to load at start up of the application. Must be enabled by the Application with enableLibLoading(). Format: PackageName:LibraryName;... or /absolute/path/to/library;...
diff --git a/scenarios/ArMemExample/config/ArMemExampleClient.cfg b/scenarios/ArMemExample/config/ExampleMemoryClient.cfg
similarity index 81%
rename from scenarios/ArMemExample/config/ArMemExampleClient.cfg
rename to scenarios/ArMemExample/config/ExampleMemoryClient.cfg
index ceaa86ed36d6745a23d3fd00018e667d2cf289f4..76d3d877581dc891a0aa8a4092e1072d9d06dc87 100644
--- a/scenarios/ArMemExample/config/ArMemExampleClient.cfg
+++ b/scenarios/ArMemExample/config/ExampleMemoryClient.cfg
@@ -1,5 +1,5 @@
 # ==================================================================
-# ArMemExampleClient properties
+# ExampleMemoryClient properties
 # ==================================================================
 
 # ArmarX.AdditionalPackages:  List of additional ArmarX packages which should be in the list of default packages. If you have custom packages, which should be found by the gui or other apps, specify them here. Comma separated List.
@@ -18,138 +18,146 @@
 # ArmarX.ApplicationName = ""
 
 
-# ArmarX.ArMemExampleClient.EnableProfiling:  enable profiler which is used for logging performance events
+# ArmarX.ArMemExampleClient.tpc.sub.MemoryListener:  No Description
 #  Attributes:
-#  - Default:            false
+#  - Default:            MemoryUpdates
+#  - Case sensitivity:   no
+#  - Required:           no
+ArmarX.ArMemExampleClient.tpc.sub.MemoryListener = MemoryUpdates
+
+
+# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+#  Attributes:
+#  - Default:            mongo/.cache
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ArMemExampleClient.EnableProfiling = false
+# ArmarX.CachePath = mongo/.cache
 
 
-# ArmarX.ArMemExampleClient.MinimumLoggingLevel:  Local logging level only for this component
+# ArmarX.Config:  Comma-separated list of configuration files 
 #  Attributes:
-#  - Default:            Undefined
+#  - Default:            ""
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
-# ArmarX.ArMemExampleClient.MinimumLoggingLevel = Undefined
+# ArmarX.Config = ""
 
 
-# ArmarX.ArMemExampleClient.ObjectName:  Name of IceGrid well-known object
+# ArmarX.DataPath:  Semicolon-separated search list for data files
 #  Attributes:
 #  - Default:            ""
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleClient.ObjectName = ""
+# ArmarX.DataPath = ""
 
 
-# ArmarX.ArMemExampleClient.RemoteGuiName:  Name of the remote gui provider
+# ArmarX.DefaultPackages:  List of ArmarX packages which are accessible by default. Comma separated List. If you want to add your own packages and use all default ArmarX packages, use the property 'AdditionalPackages'.
 #  Attributes:
-#  - Default:            RemoteGuiProvider
+#  - Default:            Default value not mapped.
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleClient.RemoteGuiName = RemoteGuiProvider
+# ArmarX.DefaultPackages = Default value not mapped.
 
 
-# ArmarX.ArMemExampleClient.mem.MemoryName:  Name of the memory to use.
+# ArmarX.DependenciesConfig:  Path to the (usually generated) config file containing all data paths of all dependent projects. This property usually does not need to be edited.
 #  Attributes:
-#  - Default:            Example
+#  - Default:            ./config/dependencies.cfg
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleClient.mem.MemoryName = Example
+# ArmarX.DependenciesConfig = ./config/dependencies.cfg
 
 
-# ArmarX.ArMemExampleClient.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
-# Set to false to use this memory as a stand-alone.
+# ArmarX.DisableLogging:  Turn logging off in whole application
 #  Attributes:
-#  - Default:            true
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
 #  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ArMemExampleClient.mns.MemoryNameSystemEnabled = true
+# ArmarX.DisableLogging = false
 
 
-# ArmarX.ArMemExampleClient.mns.MemoryNameSystemName:  Name of the Memory Name System (MNS) component.
+# ArmarX.EnableProfiling:  Enable profiling of CPU load produced by this application
 #  Attributes:
-#  - Default:            ArMemMemoryNameSystem
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleClient.mns.MemoryNameSystemName = ArMemMemoryNameSystem
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.EnableProfiling = false
 
 
-# ArmarX.ArMemExampleClient.tpc.pub.DebugObserver:  Name of the `DebugObserver` topic to publish data to.
+# ArmarX.ExampleMemoryClient.EnableProfiling:  enable profiler which is used for logging performance events
 #  Attributes:
-#  - Default:            DebugObserver
+#  - Default:            false
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.ArMemExampleClient.tpc.pub.DebugObserver = DebugObserver
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.ExampleMemoryClient.EnableProfiling = false
 
 
-# ArmarX.ArMemExampleClient.tpc.sub.MemoryListener:  Name of the `MemoryListener` topic to subscribe to.
+# ArmarX.ExampleMemoryClient.MinimumLoggingLevel:  Local logging level only for this component
 #  Attributes:
-#  - Default:            MemoryUpdates
+#  - Default:            Undefined
 #  - Case sensitivity:   yes
 #  - Required:           no
-ArmarX.ArMemExampleClient.tpc.sub.MemoryListener = MemoryUpdates
+#  - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
+# ArmarX.ExampleMemoryClient.MinimumLoggingLevel = Undefined
 
 
-# ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
+# ArmarX.ExampleMemoryClient.ObjectName:  Name of IceGrid well-known object
 #  Attributes:
-#  - Default:            mongo/.cache
+#  - Default:            ""
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.CachePath = mongo/.cache
+# ArmarX.ExampleMemoryClient.ObjectName = ""
 
 
-# ArmarX.Config:  Comma-separated list of configuration files 
+# ArmarX.ExampleMemoryClient.RemoteGuiName:  Name of the remote gui provider
 #  Attributes:
-#  - Default:            ""
+#  - Default:            RemoteGuiProvider
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.Config = ""
+# ArmarX.ExampleMemoryClient.RemoteGuiName = RemoteGuiProvider
 
 
-# ArmarX.DataPath:  Semicolon-separated search list for data files
+# ArmarX.ExampleMemoryClient.mem.MemoryName:  Name of the memory to use.
 #  Attributes:
-#  - Default:            ""
+#  - Default:            Example
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.DataPath = ""
+# ArmarX.ExampleMemoryClient.mem.MemoryName = Example
 
 
-# ArmarX.DefaultPackages:  List of ArmarX packages which are accessible by default. Comma separated List. If you want to add your own packages and use all default ArmarX packages, use the property 'AdditionalPackages'.
+# ArmarX.ExampleMemoryClient.mns.MemoryNameSystemEnabled:  Whether to use (and depend on) the Memory Name System (MNS).
+# Set to false to use this memory as a stand-alone.
 #  Attributes:
-#  - Default:            Default value not mapped.
+#  - Default:            true
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.DefaultPackages = Default value not mapped.
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.ExampleMemoryClient.mns.MemoryNameSystemEnabled = true
 
 
-# ArmarX.DependenciesConfig:  Path to the (usually generated) config file containing all data paths of all dependent projects. This property usually does not need to be edited.
+# ArmarX.ExampleMemoryClient.mns.MemoryNameSystemName:  Name of the Memory Name System (MNS) component.
 #  Attributes:
-#  - Default:            ./config/dependencies.cfg
+#  - Default:            ArMemMemoryNameSystem
 #  - Case sensitivity:   yes
 #  - Required:           no
-# ArmarX.DependenciesConfig = ./config/dependencies.cfg
+# ArmarX.ExampleMemoryClient.mns.MemoryNameSystemName = ArMemMemoryNameSystem
 
 
-# ArmarX.DisableLogging:  Turn logging off in whole application
+# ArmarX.ExampleMemoryClient.tpc.pub.DebugObserver:  Name of the `DebugObserver` topic to publish data to.
 #  Attributes:
-#  - Default:            false
+#  - Default:            DebugObserver
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.DisableLogging = false
+# ArmarX.ExampleMemoryClient.tpc.pub.DebugObserver = DebugObserver
 
 
-# ArmarX.EnableProfiling:  Enable profiling of CPU load produced by this application
+# ArmarX.ExampleMemoryClient.tpc.sub.MemoryListener:  Name of the `MemoryListener` topic to subscribe to.
 #  Attributes:
-#  - Default:            false
+#  - Default:            MemoryUpdates
 #  - Case sensitivity:   yes
 #  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.EnableProfiling = false
+# ArmarX.ExampleMemoryClient.tpc.sub.MemoryListener = MemoryUpdates
 
 
 # ArmarX.LoadLibraries:  Libraries to load at start up of the application. Must be enabled by the Application with enableLibLoading(). Format: PackageName:LibraryName;... or /absolute/path/to/library;...
diff --git a/scenarios/ArMemExample/config/ArMemMemoryNameSystem.cfg b/scenarios/ArMemExample/config/MemoryNameSystem.cfg
similarity index 90%
rename from scenarios/ArMemExample/config/ArMemMemoryNameSystem.cfg
rename to scenarios/ArMemExample/config/MemoryNameSystem.cfg
index 194953115f319abc741ff5298186673ee668820e..869022057679ebbbe32a28eb4a9962b11239e6f7 100644
--- a/scenarios/ArMemExample/config/ArMemMemoryNameSystem.cfg
+++ b/scenarios/ArMemExample/config/MemoryNameSystem.cfg
@@ -1,5 +1,5 @@
 # ==================================================================
-# ArMemMemoryNameSystem properties
+# MemoryNameSystem properties
 # ==================================================================
 
 # ArmarX.AdditionalPackages:  List of additional ArmarX packages which should be in the list of default packages. If you have custom packages, which should be found by the gui or other apps, specify them here. Comma separated List.
@@ -18,40 +18,6 @@
 # ArmarX.ApplicationName = ""
 
 
-# ArmarX.ArMemMemoryNameSystem.EnableProfiling:  enable profiler which is used for logging performance events
-#  Attributes:
-#  - Default:            false
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {0, 1, false, no, true, yes}
-# ArmarX.ArMemMemoryNameSystem.EnableProfiling = false
-
-
-# ArmarX.ArMemMemoryNameSystem.MinimumLoggingLevel:  Local logging level only for this component
-#  Attributes:
-#  - Default:            Undefined
-#  - Case sensitivity:   yes
-#  - Required:           no
-#  - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
-# ArmarX.ArMemMemoryNameSystem.MinimumLoggingLevel = Undefined
-
-
-# ArmarX.ArMemMemoryNameSystem.ObjectName:  Name of IceGrid well-known object
-#  Attributes:
-#  - Default:            ""
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ArMemMemoryNameSystem.ObjectName = ""
-
-
-# ArmarX.ArMemMemoryNameSystem.RemoteGuiName:  Name of the remote gui provider
-#  Attributes:
-#  - Default:            RemoteGuiProvider
-#  - Case sensitivity:   yes
-#  - Required:           no
-# ArmarX.ArMemMemoryNameSystem.RemoteGuiName = RemoteGuiProvider
-
-
 # ArmarX.CachePath:  Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
 #  Attributes:
 #  - Default:            mongo/.cache
@@ -126,6 +92,40 @@
 # ArmarX.LoggingGroup = ""
 
 
+# ArmarX.MemoryNameSystem.EnableProfiling:  enable profiler which is used for logging performance events
+#  Attributes:
+#  - Default:            false
+#  - Case sensitivity:   yes
+#  - Required:           no
+#  - Possible values: {0, 1, false, no, true, yes}
+# ArmarX.MemoryNameSystem.EnableProfiling = false
+
+
+# ArmarX.MemoryNameSystem.MinimumLoggingLevel:  Local logging level only for this component
+#  Attributes:
+#  - Default:            Undefined
+#  - Case sensitivity:   yes
+#  - Required:           no
+#  - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
+# ArmarX.MemoryNameSystem.MinimumLoggingLevel = Undefined
+
+
+# ArmarX.MemoryNameSystem.ObjectName:  Name of IceGrid well-known object
+#  Attributes:
+#  - Default:            ""
+#  - Case sensitivity:   yes
+#  - Required:           no
+ArmarX.MemoryNameSystem.ObjectName = "ArMemMemoryNameSystem"
+
+
+# ArmarX.MemoryNameSystem.RemoteGuiName:  Name of the remote gui provider
+#  Attributes:
+#  - Default:            RemoteGuiProvider
+#  - Case sensitivity:   yes
+#  - Required:           no
+# ArmarX.MemoryNameSystem.RemoteGuiName = RemoteGuiProvider
+
+
 # ArmarX.RedirectStdout:  Redirect std::cout and std::cerr to ArmarXLog
 #  Attributes:
 #  - Default:            true
diff --git a/source/RobotAPI/components/armem/client/CMakeLists.txt b/source/RobotAPI/components/armem/client/CMakeLists.txt
index a8e816bf283467a0a0efbadf9fff40d555ec153b..4eda2528386b1edd333bab29f06480255434b69d 100644
--- a/source/RobotAPI/components/armem/client/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/client/CMakeLists.txt
@@ -1 +1 @@
-add_subdirectory(ExampleClient)
+add_subdirectory(ExampleMemoryClient)
diff --git a/source/RobotAPI/components/armem/client/ExampleClient/test/ArMemExampleClientTest.cpp b/source/RobotAPI/components/armem/client/ExampleClient/test/ArMemExampleClientTest.cpp
deleted file mode 100644
index 67269fecc99271fcc1f88ffb7eed89e07ae2b7a8..0000000000000000000000000000000000000000
--- a/source/RobotAPI/components/armem/client/ExampleClient/test/ArMemExampleClientTest.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * This file is part of ArmarX.
- *
- * ArmarX is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * ArmarX is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @package    RobotAPI::ArmarXObjects::ArMemExampleClient
- * @author     Rainer Kartmann ( rainer dot kartmann at kit dot edu )
- * @date       2020
- * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
- *             GNU General Public License
- */
-
-#define BOOST_TEST_MODULE RobotAPI::ArmarXObjects::ArMemExampleClient
-
-#define ARMARX_BOOST_TEST
-
-#include <RobotAPI/Test.h>
-#include "../ArMemExampleClient.h"
-
-#include <iostream>
-
-BOOST_AUTO_TEST_CASE(testExample)
-{
-    armarx::ArMemExampleClient instance;
-
-    BOOST_CHECK_EQUAL(true, true);
-}
diff --git a/source/RobotAPI/components/armem/client/ExampleClient/test/CMakeLists.txt b/source/RobotAPI/components/armem/client/ExampleClient/test/CMakeLists.txt
deleted file mode 100644
index 775fb5e2e01b19ab9996a6be1b7575fb53caade6..0000000000000000000000000000000000000000
--- a/source/RobotAPI/components/armem/client/ExampleClient/test/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-
-# Libs required for the tests
-SET(LIBS ${LIBS} ArmarXCore ArMemExampleClient)
- 
-armarx_add_test(ArMemExampleClientTest ArMemExampleClientTest.cpp "${LIBS}")
diff --git a/source/RobotAPI/components/armem/client/ExampleClient/CMakeLists.txt b/source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt
similarity index 84%
rename from source/RobotAPI/components/armem/client/ExampleClient/CMakeLists.txt
rename to source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt
index a6c8b9c637db73dc5cae91c430346542b834dec4..d699638cd0eb88c194fd66a9382968012ce40660 100644
--- a/source/RobotAPI/components/armem/client/ExampleClient/CMakeLists.txt
+++ b/source/RobotAPI/components/armem/client/ExampleMemoryClient/CMakeLists.txt
@@ -1,4 +1,4 @@
-armarx_component_set_name("ExampleClient")
+armarx_component_set_name("ExampleMemoryClient")
 
 find_package(IVT QUIET)
 armarx_build_if(IVT_FOUND "IVT not available")
@@ -11,11 +11,11 @@ set(COMPONENT_LIBS
 )
 
 set(SOURCES
-    ExampleClient.cpp
+    ExampleMemoryClient.cpp
 )
 
 set(HEADERS
-    ExampleClient.h
+    ExampleMemoryClient.h
 )
 
 armarx_add_component("${SOURCES}" "${HEADERS}")
diff --git a/source/RobotAPI/components/armem/client/ExampleClient/ExampleClient.cpp b/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp
similarity index 81%
rename from source/RobotAPI/components/armem/client/ExampleClient/ExampleClient.cpp
rename to source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp
index b69d0aa5380712e216996be6f69b0a8b0c28b39d..5ed005e7a82c5c5eb24b056d0f5d71e10ebcf380 100644
--- a/source/RobotAPI/components/armem/client/ExampleClient/ExampleClient.cpp
+++ b/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.cpp
@@ -13,14 +13,14 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  *
- * @package    RobotAPI::ArmarXObjects::ExampleClient
+ * @package    RobotAPI::ArmarXObjects::ExampleMemoryClient
  * @author     Rainer Kartmann ( rainer dot kartmann at kit dot edu )
  * @date       2020
  * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
  *             GNU General Public License
  */
 
-#include "ExampleClient.h"
+#include "ExampleMemoryClient.h"
 
 #include <SimoxUtility/color/cmaps.h>
 
@@ -30,21 +30,21 @@
 #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 
 #include <RobotAPI/components/armem/server/ExampleMemory/aron/ExampleData.aron.generated.h>
 
 
 namespace armarx
 {
-    ExampleClientPropertyDefinitions::ExampleClientPropertyDefinitions(std::string prefix) :
+    ExampleMemoryClientPropertyDefinitions::ExampleMemoryClientPropertyDefinitions(std::string prefix) :
         armarx::ComponentPropertyDefinitions(prefix)
     {
     }
 
-    armarx::PropertyDefinitionsPtr ExampleClient::createPropertyDefinitions()
+    armarx::PropertyDefinitionsPtr ExampleMemoryClient::createPropertyDefinitions()
     {
-        armarx::PropertyDefinitionsPtr defs = new ExampleClientPropertyDefinitions(getConfigIdentifier());
+        armarx::PropertyDefinitionsPtr defs = new ExampleMemoryClientPropertyDefinitions(getConfigIdentifier());
 
         defs->topic(debugObserver);
 
@@ -53,18 +53,18 @@ namespace armarx
         return defs;
     }
 
-    std::string ExampleClient::getDefaultName() const
+    std::string ExampleMemoryClient::getDefaultName() const
     {
-        return "ExampleClient";
+        return "ExampleMemoryClient";
     }
 
 
-    void ExampleClient::onInitComponent()
+    void ExampleMemoryClient::onInitComponent()
     {
     }
 
 
-    void ExampleClient::onConnectComponent()
+    void ExampleMemoryClient::onConnectComponent()
     {
         createRemoteGuiTab();
         RemoteGui_startRunningTask();
@@ -90,26 +90,26 @@ namespace armarx
             ARMARX_INFO << "Entity " << entityID << " was updated by " << snapshotIDs.size() << " snapshots.";
         });
         // Using a member function:
-        memoryReader.subscribe(entityID, this, &ExampleClient::example_entityUpdated);
+        memoryReader.subscribe(entityID, this, &ExampleMemoryClient::example_entityUpdated);
 
 
-        task = new RunningTask<ExampleClient>(this, &ExampleClient::run);
+        task = new RunningTask<ExampleMemoryClient>(this, &ExampleMemoryClient::run);
         task->start();
     }
 
 
-    void ExampleClient::onDisconnectComponent()
+    void ExampleMemoryClient::onDisconnectComponent()
     {
         task->stop();
     }
 
 
-    void ExampleClient::onExitComponent()
+    void ExampleMemoryClient::onExitComponent()
     {
     }
 
 
-    void ExampleClient::run()
+    void ExampleMemoryClient::run()
     {
         ARMARX_IMPORTANT << "Running example.";
 
@@ -142,7 +142,7 @@ namespace armarx
     }
 
 
-    armem::MemoryID ExampleClient::addProviderSegment()
+    armem::MemoryID ExampleMemoryClient::addProviderSegment()
     {
         armem::data::AddSegmentInput input;
         input.coreSegmentName = "ExampleModality";
@@ -155,7 +155,7 @@ namespace armarx
         return armem::MemoryID(result.segmentID);
     }
 
-    armem::MemoryID ExampleClient::commitSingleSnapshot(const armem::MemoryID& entityID)
+    armem::MemoryID ExampleMemoryClient::commitSingleSnapshot(const armem::MemoryID& entityID)
     {
         // Prepare the update with some empty instances.
         armem::EntityUpdate update;
@@ -178,7 +178,7 @@ namespace armarx
         return updateResult.snapshotID;
     }
 
-    void ExampleClient::commitMultipleSnapshots(const armem::MemoryID& entityID, int num)
+    void ExampleMemoryClient::commitMultipleSnapshots(const armem::MemoryID& entityID, int num)
     {
         // Commit a number of updates with different timestamps and number of instances.
         armem::Commit commit;
@@ -202,7 +202,7 @@ namespace armarx
     }
 
 
-    void ExampleClient::queryLatestSnapshot(const armem::MemoryID& entityID)
+    void ExampleMemoryClient::queryLatestSnapshot(const armem::MemoryID& entityID)
     {
         ARMARX_IMPORTANT
                 << "Querying latest snapshot: "
@@ -221,19 +221,19 @@ namespace armarx
 
         if (qResult.success)
         {
-            armem::Memory& memory = qResult.memory;
+            armem::wm::Memory& memory = qResult.memory;
 
-            ARMARX_CHECK_EQUAL(memory.coreSegments.size(), 1);
-            armem::CoreSegment& coreSeg = memory.coreSegments.begin()->second;
+            ARMARX_CHECK_EQUAL(memory.coreSegments().size(), 1);
+            armem::wm::CoreSegment& coreSeg = memory.coreSegments().begin()->second;
 
-            ARMARX_CHECK_EQUAL(coreSeg.providerSegments.size(), 1);
-            armem::ProviderSegment& provSeg = coreSeg.providerSegments.begin()->second;
+            ARMARX_CHECK_EQUAL(coreSeg.providerSegments().size(), 1);
+            armem::wm::ProviderSegment& provSeg = coreSeg.providerSegments().begin()->second;
 
-            ARMARX_CHECK_EQUAL(provSeg.entities.size(), 1);
-            armem::Entity& entity = provSeg.entities.begin()->second;
+            ARMARX_CHECK_EQUAL(provSeg.entities().size(), 1);
+            armem::wm::Entity& entity = provSeg.entities().begin()->second;
 
-            ARMARX_CHECK_GREATER_EQUAL(entity.history.size(), 1);
-            armem::EntitySnapshot& snapshot = entity.history.begin()->second;
+            ARMARX_CHECK_GREATER_EQUAL(entity.history().size(), 1);
+            armem::wm::EntitySnapshot& snapshot = entity.history().begin()->second;
 
             ARMARX_INFO << "Result: "
                         << "\n- memory:       \t" << memory.name()
@@ -245,7 +245,7 @@ namespace armarx
                         ;
 
             ARMARX_IMPORTANT << "Getting entity via ID";
-            const armem::Entity& e = memory.getEntity(entityID);
+            const armem::wm::Entity& e = memory.getEntity(entityID);
             ARMARX_INFO << "Result: "
                         << "\n- entity:       \t" << e.name()
                         << "\n- snapshot:     \t" << e.getLatestSnapshot().time()
@@ -262,10 +262,10 @@ namespace armarx
         }
     }
 
-    void ExampleClient::queryExactSnapshot(const armem::MemoryID& snapshotID)
+    void ExampleMemoryClient::queryExactSnapshot(const armem::MemoryID& snapshotID)
     {
         ARMARX_IMPORTANT
-                << "Querying exact smapshot: "
+                << "Querying exact snapshot: "
                 << "\n- snapshotID:     \t'" << snapshotID << "'"
                 ;
 
@@ -282,8 +282,8 @@ namespace armarx
 
         if (qResult.success)
         {
-            armem::Memory memory = std::move(qResult.memory);
-            armem::EntitySnapshot& entitySnapshot = memory.getEntity(snapshotID).getLatestSnapshot();
+            armem::wm::Memory memory = std::move(qResult.memory);
+            const armem::wm::EntitySnapshot& entitySnapshot = memory.getEntity(snapshotID).getLatestSnapshot();
 
             ARMARX_INFO << "Result snapshot: "
                         << "\n- time:        \t" << entitySnapshot.time()
@@ -297,7 +297,7 @@ namespace armarx
     }
 
 
-    void ExampleClient::commitExampleData()
+    void ExampleMemoryClient::commitExampleData()
     {
         ARMARX_IMPORTANT << "Adding segment " << "ExampleData" << "/" << getName();
 
@@ -376,7 +376,7 @@ namespace armarx
         }
     }
 
-    void ExampleClient::queryExampleData()
+    void ExampleMemoryClient::queryExampleData()
     {
         // Query all entities from provider.
         armem::client::query::Builder qb;
@@ -400,7 +400,7 @@ namespace armarx
 
 
 
-    void ExampleClient::example_entityUpdated(const armem::MemoryID& subscriptionID, const std::vector<armem::MemoryID>& snapshotIDs)
+    void ExampleMemoryClient::example_entityUpdated(const armem::MemoryID& subscriptionID, const std::vector<armem::MemoryID>& snapshotIDs)
     {
         std::stringstream ss;
         ss << "example_entity got updated: " << subscriptionID << "\n";
@@ -414,7 +414,7 @@ namespace armarx
     }
 
 
-    void ExampleClient::createRemoteGuiTab()
+    void ExampleMemoryClient::createRemoteGuiTab()
     {
         using namespace armarx::RemoteGui::Client;
 
@@ -427,7 +427,7 @@ namespace armarx
         RemoteGui_createTab(getName(), root, &tab);
     }
 
-    void ExampleClient::RemoteGui_update()
+    void ExampleMemoryClient::RemoteGui_update()
     {
         if (tab.rebuild.exchange(false))
         {
diff --git a/source/RobotAPI/components/armem/client/ExampleClient/ExampleClient.h b/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.h
similarity index 91%
rename from source/RobotAPI/components/armem/client/ExampleClient/ExampleClient.h
rename to source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.h
index 3ee6d82e44f6efa8feb62b504d3d966ac23387fb..e2e975c4a5450fa614cf0020b1e21a09fabbdb4f 100644
--- a/source/RobotAPI/components/armem/client/ExampleClient/ExampleClient.h
+++ b/source/RobotAPI/components/armem/client/ExampleMemoryClient/ExampleMemoryClient.h
@@ -34,7 +34,7 @@
 #include <RobotAPI/interface/armem/server/MemoryInterface.h>
 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
 #include <RobotAPI/libraries/armem/client/ComponentPlugin.h>
-#include <RobotAPI/libraries/armem/core/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
 
 
 namespace armarx
@@ -43,11 +43,11 @@ namespace armarx
      * @class ExampleClientPropertyDefinitions
      * @brief Property definitions of `ExampleClient`.
      */
-    class ExampleClientPropertyDefinitions :
+    class ExampleMemoryClientPropertyDefinitions :
         public armarx::ComponentPropertyDefinitions
     {
     public:
-        ExampleClientPropertyDefinitions(std::string prefix);
+        ExampleMemoryClientPropertyDefinitions(std::string prefix);
     };
 
 
@@ -62,7 +62,7 @@ namespace armarx
      *
      * Detailed description of class ExampleClient.
      */
-    class ExampleClient :
+    class ExampleMemoryClient :
         virtual public armarx::Component,
         virtual public armarx::armem::client::ComponentPluginUser,
         virtual public LightweightRemoteGuiComponentPluginUser
@@ -114,7 +114,7 @@ namespace armarx
 
     private:
 
-        armarx::RunningTask<ExampleClient>::pointer_type task;
+        armarx::RunningTask<ExampleMemoryClient>::pointer_type task;
 
         armarx::DebugObserverInterfacePrx debugObserver;
 
@@ -124,7 +124,7 @@ namespace armarx
         {
             std::atomic_bool rebuild = false;
 
-            std::optional<armem::Memory> queryResult;
+            std::optional<armem::wm::Memory> queryResult;
             RemoteGui::Client::GroupBox queryResultGroup;
         };
         RemoteGuiTab tab;
diff --git a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
index 19b547583a3678d9b244e8fa4b13b48730229033..a3c7f7bc8c31e0c6c8ff2af96ebd36412521ee00 100644
--- a/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
+++ b/source/RobotAPI/components/armem/server/ExampleMemory/ExampleMemory.cpp
@@ -60,16 +60,16 @@ namespace armarx
 
     void ExampleMemory::onInitComponent()
     {
-        memory.name() = p.memoryName;
+        workingmemory.name() = p.memoryName;
 
         // Usually, the memory server will specify a number of core segments with a specific aron type.
-        memory.addCoreSegment("ExampleData", armem::example::ExampleData::toInitialAronType());
+        workingmemory.addCoreSegment("ExampleData", armem::example::ExampleData::toInitialAronType());
 
         // For illustration purposes, we add more segments (without types).
         bool trim = true;
         p.core.defaultCoreSegments = simox::alg::split(p.core._defaultSegmentsStr, ",", trim);
         p.core._defaultSegmentsStr.clear();
-        memory.addCoreSegments(p.core.defaultCoreSegments);
+        workingmemory.addCoreSegments(p.core.defaultCoreSegments);
     }
 
     void ExampleMemory::onConnectComponent()
@@ -121,8 +121,8 @@ namespace armarx
         using namespace armarx::RemoteGui::Client;
 
         {
-            std::scoped_lock lock(memoryMutex);
-            tab.memoryGroup = armem::server::MemoryRemoteGui().makeGroupBox(memory);
+            std::scoped_lock lock(workingmemoryMutex);
+            tab.memoryGroup = armem::server::MemoryRemoteGui().makeGroupBox(workingmemory);
         }
 
         VBoxLayout root = {tab.memoryGroup, VSpacer()};
diff --git a/source/RobotAPI/components/armem/server/ExampleMemory/test/ExampleMemoryTest.cpp b/source/RobotAPI/components/armem/server/ExampleMemory/test/ExampleMemoryTest.cpp
index 6cc16927355f90c56f99ea9552bb356581a492bc..b269993f79bd5c5d39c590e1359cb5790fd9b4dc 100644
--- a/source/RobotAPI/components/armem/server/ExampleMemory/test/ExampleMemoryTest.cpp
+++ b/source/RobotAPI/components/armem/server/ExampleMemory/test/ExampleMemoryTest.cpp
@@ -36,14 +36,6 @@
 using armarx::armem::example::ExampleData;
 namespace armem = armarx::armem;
 
-/*
-BOOST_AUTO_TEST_CASE(test_ExampleData)
-{
-    ExampleData data;
-    BOOST_CHECK(true);
-}
-*/
-
 
 BOOST_AUTO_TEST_CASE(test_ExampleData_type)
 {
@@ -51,9 +43,9 @@ BOOST_AUTO_TEST_CASE(test_ExampleData_type)
 
     BOOST_CHECK_EQUAL(type->childrenSize(), 15);
 
-    armem::Memory memory;
-    armem::CoreSegment& core = memory.addCoreSegment("ExampleData", type);
-    armem::ProviderSegment& prov = core.addProviderSegment("Provider");
+    armem::wm::Memory memory;
+    armem::wm::CoreSegment& core = memory.addCoreSegment("ExampleData", type);
+    armem::wm::ProviderSegment& prov = core.addProviderSegment("Provider");
 
     BOOST_CHECK_EQUAL(core.aronType(), prov.aronType());
 }
diff --git a/source/RobotAPI/components/armem/server/GeneralPurposeMemory/GeneralPurposeMemory.cpp b/source/RobotAPI/components/armem/server/GeneralPurposeMemory/GeneralPurposeMemory.cpp
index 7cc9356831b2da36ee8facfb55c777722fa47350..8247ab6f9d1ff22baecefb6146a14ea6866c8d93 100644
--- a/source/RobotAPI/components/armem/server/GeneralPurposeMemory/GeneralPurposeMemory.cpp
+++ b/source/RobotAPI/components/armem/server/GeneralPurposeMemory/GeneralPurposeMemory.cpp
@@ -50,7 +50,7 @@ namespace armarx
 
     void GeneralPurposeMemory::onInitComponent()
     {
-        memory.name() = memoryName;
+        workingmemory.name() = memoryName;
     }
 
 
diff --git a/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.cpp b/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.cpp
index fd1987ee72282d4fdf1c99e6229c9b1fdf1b7637..2293364c6cf55555b40c86b3b9d1490783112e09 100644
--- a/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.cpp
+++ b/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.cpp
@@ -71,7 +71,7 @@ namespace armarx
         robotStateComponentMemoryBatchSize = std::max((unsigned int) 1, robotStateComponentMemoryBatchSize);
         robotStateComponentPollFrequency = std::clamp(robotStateComponentPollFrequency, 1, ROBOT_STATE_COMPONENT_MAXIMUM_FREQUENCY);
 
-        memory.name() = memoryName;
+        workingmemory.name() = workingMemoryName;
     }
 
 
@@ -114,7 +114,7 @@ namespace armarx
     void RobotSensorMemory::setupRobotUnitSegment()
     {
         ARMARX_INFO << "Adding core segment " << robotUnitCoreSegmentName;
-        memory.addCoreSegments({robotUnitCoreSegmentName});
+        workingmemory.addCoreSegments({robotUnitCoreSegmentName});
 
         ARMARX_INFO << "Adding provider segment " << robotUnitCoreSegmentName << "/" << robotUnitProviderSegmentName;
         armem::data::AddSegmentInput input;
@@ -136,7 +136,7 @@ namespace armarx
             ARMARX_ERROR << "Could not add segment " << robotUnitCoreSegmentName << "/" << robotUnitProviderSegmentName << ". The error message is: " << result.errorMessage;
         }
 
-        robotUnitProviderID.memoryName = memoryName;
+        robotUnitProviderID.memoryName = workingMemoryName;
         robotUnitProviderID.coreSegmentName = robotUnitCoreSegmentName;
         robotUnitProviderID.providerSegmentName = robotUnitProviderSegmentName;
     }
@@ -379,7 +379,7 @@ namespace armarx
     void RobotSensorMemory::setupRobotStateComponentSegment()
     {
         ARMARX_INFO << "Adding core segment " << robotStateComponentCoreSegmentName;
-        memory.addCoreSegments({robotStateComponentCoreSegmentName});
+        workingmemory.addCoreSegments({robotStateComponentCoreSegmentName});
 
         ARMARX_INFO << "Adding provider segment " << robotStateComponentCoreSegmentName << "/" << robotStateComponentProviderSegmentName;
         armem::data::AddSegmentInput input;
@@ -395,7 +395,7 @@ namespace armarx
             ARMARX_ERROR << "Could not add segment " << robotStateComponentCoreSegmentName << "/" << robotStateComponentProviderSegmentName << ". The error message is: " << result.errorMessage;
         }
 
-        robotStateComponentProviderID.memoryName = memoryName;
+        robotStateComponentProviderID.memoryName = workingMemoryName;
         robotStateComponentProviderID.coreSegmentName = robotStateComponentCoreSegmentName;
         robotStateComponentProviderID.providerSegmentName = robotStateComponentProviderSegmentName;
     }
diff --git a/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.h b/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.h
index 6b6ea32c9ce4b8faa790f2c5158213e7c516b52c..b16ee1296319b386ee77760a2c81df53019e37c4 100644
--- a/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.h
+++ b/source/RobotAPI/components/armem/server/RobotSensorMemory/RobotSensorMemory.h
@@ -104,7 +104,7 @@ namespace armarx
         void stopRobotStateComponentPoll();
 
     private:
-        std::string memoryName = "RobotSensorMemory";
+        std::string workingMemoryName = "RobotStateMemory";
         bool addCoreSegmentOnUsage = false;
 
         mutable std::recursive_mutex startStopMutex;
@@ -114,6 +114,7 @@ namespace armarx
         std::string robotUnitProviderSegmentName = "RobotUnit"; // get robot name?
         armem::data::MemoryID robotUnitProviderID;
 
+        // TODO: Remove the whole connection to the RSC since this memory will replace it?
         std::string robotStateComponentCoreSegmentName = "Localization";
         std::string robotStateComponentProviderSegmentName = "RobotStateComponent"; // get robot name?
         armem::data::MemoryID robotStateComponentProviderID;
diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
index 14dd8887985350929b4a729a4387a5ba448c68f9..4efdcbff7b43ca8a168ba17d0970b1b6a5781d10 100644
--- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
+++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp
@@ -50,7 +50,7 @@ namespace armarx
 
     void SkillsMemory::onInitComponent()
     {
-        memory.name() = memoryName;
+        workingmemory.name() = memoryName;
     }
 
 
diff --git a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidget.ui b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidget.ui
index a972b97b164a83ef25695aaf618e790f250ac09a..3e94dc5e5c3e13bd866c92c428f5d619317806ac 100644
--- a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidget.ui
+++ b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidget.ui
@@ -14,6 +14,26 @@
    <string>ArMemMemoryViewerWidget</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="ltmControlWidgetLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
    <item>
     <layout class="QHBoxLayout" name="updateWidgetLayout">
      <item>
diff --git a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.cpp b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.cpp
index efe81d7170e97515f8bf39e692a16bcd68f1a6fe..f313b6951c2f201251787ec6a6e6b4b5b0026e4c 100644
--- a/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/ArMemMemoryViewer/ArMemMemoryViewerWidgetController.cpp
@@ -41,6 +41,8 @@ namespace armarx
         widget.setupUi(getWidget());
 
         viewer = std::make_unique<MemoryViewer>(
+                     widget.ltmControlWidgetLayout,
+
                      widget.updateWidgetLayout,
 
                      widget.memoryGroupBox,
diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt
index a92282c4cb3a86aa0be07af3c1f26e0b6477eca2..b2913fb4c0f39035f94b284a52ac7f32295f73b8 100644
--- a/source/RobotAPI/interface/CMakeLists.txt
+++ b/source/RobotAPI/interface/CMakeLists.txt
@@ -115,7 +115,8 @@ set(SLICE_FILES
     armem/client/MemoryListenerInterface.ice
 
     armem/server.ice
-    armem/server/LongTermMemoryInterface.ice
+    armem/server/StoringMemoryInterface.ice
+    armem/server/LoadingMemoryInterface.ice
     armem/server/MemoryInterface.ice
     armem/server/MemoryPredictorInterface.ice
     armem/server/ReadingMemoryInterface.ice
diff --git a/source/RobotAPI/interface/armem/io.ice b/source/RobotAPI/interface/armem/io.ice
index cccea43c0b749441c30bc1834f3c86ce690b7195..f721edfad97923d8615d956bf1d93788ae0e16c3 100644
--- a/source/RobotAPI/interface/armem/io.ice
+++ b/source/RobotAPI/interface/armem/io.ice
@@ -2,6 +2,7 @@
 
 #include <ArmarXCore/interface/core/PackagePath.ice>
 #include <RobotAPI/interface/armem/memory.ice>
+#include <RobotAPI/interface/armem/query.ice>
 
 module armarx
 {
@@ -9,31 +10,11 @@ module armarx
     {
         module data
         {
-            struct LoadInput
-            {
-                armarx::data::PackagePath path;
-                armem::data::MemoryID entityID;
-            };
-
-            struct LoadResult
-            {
-                bool success = false;
-                long timeStartedMicroSeconds;
-                long timeFinishedMicroSeconds;
-
-                long numLoadedCoreSegments;
-                long numLoadedProviderSegments;
-                long numLoadedEntities;
-                long numLoadedEntitySnapshots;
-
-                string errorMessage;
-            };
-
             struct StoreInput
             {
-                armarx::data::PackagePath path;
-                armem::data::MemoryID entityID;
+                armem::query::data::Input query;
             };
+            sequence<StoreInput> StoreInputSeq;
 
             struct StoreResult
             {
@@ -41,11 +22,6 @@ module armarx
                 long timeStartedMicroSeconds;
                 long timeFinishedMicroSeconds;
 
-                long numStoredCoreSegments;
-                long numStoredLoadedProviderSegments;
-                long numStoredLoadedEntities;
-                long numStoredLoadedEntitySnapshots;
-
                 string errorMessage;
             };
         };
diff --git a/source/RobotAPI/interface/armem/server/LoadingMemoryInterface.ice b/source/RobotAPI/interface/armem/server/LoadingMemoryInterface.ice
new file mode 100644
index 0000000000000000000000000000000000000000..bb1e7f221856b4505184fdeb380683c6f8cb917b
--- /dev/null
+++ b/source/RobotAPI/interface/armem/server/LoadingMemoryInterface.ice
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/io.ice>
+
+
+module armarx
+{
+    module armem
+    {        
+        module server
+        {
+            interface LoadingMemoryInterface
+            {
+                armem::query::data::Result load(armem::query::data::Input query);
+            };
+        };
+    };
+};
diff --git a/source/RobotAPI/interface/armem/server/MemoryInterface.ice b/source/RobotAPI/interface/armem/server/MemoryInterface.ice
index 93213eed1d85269c83cfcd2547908e2be61f2d2a..a4c8ba2f7602be3eccf333584cffe7a773486f03 100644
--- a/source/RobotAPI/interface/armem/server/MemoryInterface.ice
+++ b/source/RobotAPI/interface/armem/server/MemoryInterface.ice
@@ -1,9 +1,11 @@
 #pragma once
 
+#include <RobotAPI/interface/armem/server/LoadingMemoryInterface.ice>
+#include <RobotAPI/interface/armem/server/StoringMemoryInterface.ice>
+
 #include <RobotAPI/interface/armem/server/ReadingMemoryInterface.ice>
 #include <RobotAPI/interface/armem/server/WritingMemoryInterface.ice>
 
-#include <RobotAPI/interface/armem/server/LongTermMemoryInterface.ice>
 
 module armarx
 {
@@ -11,7 +13,15 @@ module armarx
     {
         module server
         {
-            interface MemoryInterface extends ReadingMemoryInterface, WritingMemoryInterface
+            interface LongTermMemoryInterface extends LoadingMemoryInterface, StoringMemoryInterface
+            {
+            };
+
+            interface WorkingMemoryInterface extends ReadingMemoryInterface, WritingMemoryInterface
+            {
+            };
+
+            interface MemoryInterface extends WorkingMemoryInterface, LongTermMemoryInterface
             {
             };
         };
diff --git a/source/RobotAPI/interface/armem/server/LongTermMemoryInterface.ice b/source/RobotAPI/interface/armem/server/StoringMemoryInterface.ice
similarity index 70%
rename from source/RobotAPI/interface/armem/server/LongTermMemoryInterface.ice
rename to source/RobotAPI/interface/armem/server/StoringMemoryInterface.ice
index ba64d626c1c156c3820a508625d1c3a3b36ec847..4e369bf259f24eccb36bcd1a2a58373da0fec442 100644
--- a/source/RobotAPI/interface/armem/server/LongTermMemoryInterface.ice
+++ b/source/RobotAPI/interface/armem/server/StoringMemoryInterface.ice
@@ -9,9 +9,8 @@ module armarx
     {        
         module server
         {
-            interface LongTermMemoryInterface
+            interface StoringMemoryInterface
             {
-                data::LoadResult load(data::LoadInput input);
                 data::StoreResult store(data::StoreInput input);
             };
         };
diff --git a/source/RobotAPI/interface/aron/Aron.ice b/source/RobotAPI/interface/aron/Aron.ice
index 50e821e1b4d794906f353d30623f904d21266098..d01b0d60aa39d65b39d14fbc1abb8100a9ec0014 100644
--- a/source/RobotAPI/interface/aron/Aron.ice
+++ b/source/RobotAPI/interface/aron/Aron.ice
@@ -51,7 +51,7 @@ module armarx
             class AronList extends AronType { AronType acceptedType; };
             class AronTuple extends AronType { AronTypeList elementTypes; };
             class AronPair extends AronType { AronType acceptedType1; AronType acceptedType2; };
-            class AronObject extends AronType { AronObject parent; string objectName; AronTypeDict elementTypes;};
+            class AronObject extends AronType { AronObject parent; string objectName; AronTypeDict elementTypes; };
             class AronDict extends AronType { AronType acceptedType; };
 
             // Complex Types (serialize to ndarray)
diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 4fef1082d1919af56746dd4320fbbe63defafca3..13db1d957c63f5a504992ee071e6ce2e9dc126b3 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -3,11 +3,12 @@ set(LIB_NAME armem)
 armarx_component_set_name("${LIB_NAME}")
 armarx_set_target("Library: ${LIB_NAME}")
 
-
 set(LIBS
     ArmarXCoreInterfaces ArmarXCore
     RemoteGui
     aron
+    ${LIBMONGOCXX_LIBRARIES}
+    ${LIBBSONCXX_LIBRARIES}
 )
 
 set(LIB_FILES
@@ -17,29 +18,49 @@ set(LIB_FILES
     core/Time.cpp
     core/ice_conversions.cpp
     core/aron_conversions.cpp
-
-    core/CoreSegment.cpp
-    core/Entity.cpp
-    core/EntityInstance.cpp
-    core/EntitySnapshot.cpp
-    core/ice_conversions.cpp
-    core/Memory.cpp
-    core/ProviderSegment.cpp
     core/Visitor.cpp
 
-    core/detail/MemoryItem.cpp
-    core/detail/MaxHistorySize.cpp
+    core/base/detail/MemoryItem.cpp
+    core/base/detail/MaxHistorySize.cpp
+    core/base/detail/MemoryContainerBase.cpp
+    core/base/detail/EntityContainerBase.cpp
+    core/base/detail/TypedEntityContainerBase.cpp
+
+    core/base/CoreSegmentBase.cpp
+    core/base/EntityBase.cpp
+    core/base/EntityInstanceBase.cpp
+    core/base/EntitySnapshotBase.cpp
+    core/base/MemoryBase.cpp
+    core/base/ProviderSegmentBase.cpp
+
+    core/workingmemory/ice_conversions.cpp
+    core/workingmemory/detail/MemoryContainer.cpp
+    core/workingmemory/detail/EntityContainer.cpp
+    core/workingmemory/detail/TypedEntityContainer.cpp
+    core/workingmemory/CoreSegment.cpp
+    core/workingmemory/Entity.cpp
+    core/workingmemory/EntityInstance.cpp
+    core/workingmemory/EntitySnapshot.cpp
+    core/workingmemory/Memory.cpp
+    core/workingmemory/ProviderSegment.cpp
+    core/workingmemory/ice_conversions.cpp
+
+    core/longtermmemory/CoreSegment.cpp
+    core/longtermmemory/Entity.cpp
+    core/longtermmemory/EntityInstance.cpp
+    core/longtermmemory/EntitySnapshot.cpp
+    core/longtermmemory/Memory.cpp
+    core/longtermmemory/ProviderSegment.cpp
+
+    core/diskmemory/CoreSegment.cpp
+    core/diskmemory/Entity.cpp
+    core/diskmemory/EntityInstance.cpp
+    core/diskmemory/EntitySnapshot.cpp
+    core/diskmemory/Memory.cpp
+    core/diskmemory/ProviderSegment.cpp
 
     core/error/ArMemError.cpp
 
-    core/io/DiskReaderWriter.cpp
-    core/io/FileSystemLookupMemory.cpp
-    core/io/MemoryFileSystemStorage.cpp
-    core/io/DiskWriter/DiskWriter.cpp
-    core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.cpp
-    core/io/DiskReader/DiskReader.cpp
-    core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.cpp
-
     client/ComponentPlugin.cpp
     client/Reader.cpp
     client/ReaderComponentPlugin.cpp
@@ -55,11 +76,23 @@ set(LIB_FILES
     server/MemoryRemoteGui.cpp
     server/RemoteGuiAronDataVisitor.cpp
 
-    server/query_proc/BaseQueryProcessor.cpp
-    server/query_proc/EntityQueryProcessor.cpp
-    server/query_proc/ProviderSegmentQueryProcessor.cpp
-    server/query_proc/CoreSegmentQueryProcessor.cpp
-    server/query_proc/MemoryQueryProcessor.cpp
+    server/query_proc/base/BaseQueryProcessorBase.cpp
+    server/query_proc/base/EntityQueryProcessorBase.cpp
+    server/query_proc/base/ProviderSegmentQueryProcessorBase.cpp
+    server/query_proc/base/CoreSegmentQueryProcessorBase.cpp
+    server/query_proc/base/MemoryQueryProcessorBase.cpp
+
+    server/query_proc/workingmemory/BaseQueryProcessor.cpp
+    server/query_proc/workingmemory/EntityQueryProcessor.cpp
+    server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp
+    server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp
+    server/query_proc/workingmemory/MemoryQueryProcessor.cpp
+
+    server/query_proc/longtermmemory/BaseQueryProcessor.cpp
+    server/query_proc/longtermmemory/EntityQueryProcessor.cpp
+    server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp
+    server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp
+    server/query_proc/longtermmemory/MemoryQueryProcessor.cpp
 
     mns/MemoryNameSystem.cpp
     mns/ClientPlugin.cpp
@@ -82,28 +115,49 @@ set(LIB_HEADERS
     core/error.h
     core/error/ArMemError.h
 
-    core/CoreSegment.h
-    core/Entity.h
-    core/EntityInstance.h
-    core/EntitySnapshot.h
+    core/base/detail/MemoryItem.h
+    core/base/detail/MaxHistorySize.h
+    core/base/detail/MemoryContainerBase.h
+    core/base/detail/EntityContainerBase.h
+    core/base/detail/TypedEntityContainerBase.h
+
+    core/base/CoreSegmentBase.h
+    core/base/EntityBase.h
+    core/base/EntityInstanceBase.h
+    core/base/EntitySnapshotBase.h
+    core/base/MemoryBase.h
+    core/base/ProviderSegmentBase.h
+
+    core/workingmemory/detail/MemoryContainer.h
+    core/workingmemory/detail/EntityContainer.h
+    core/workingmemory/detail/TypedEntityContainer.h
+    core/workingmemory/CoreSegment.h
+    core/workingmemory/Entity.h
+    core/workingmemory/EntityInstance.h
+    core/workingmemory/EntitySnapshot.h
+    core/workingmemory/Memory.h
+    core/workingmemory/ProviderSegment.h
+    core/workingmemory/ice_conversions.h
+
+    core/longtermmemory/CoreSegment.h
+    core/longtermmemory/Entity.h
+    core/longtermmemory/EntityInstance.h
+    core/longtermmemory/EntitySnapshot.h
+    core/longtermmemory/Memory.h
+    core/longtermmemory/ProviderSegment.h
+    core/longtermmemory/mongodb/MongoDBConnectionManager.h
+
+    core/diskmemory/detail/TypedEntityContainer.h
+    core/diskmemory/CoreSegment.h
+    core/diskmemory/Entity.h
+    core/diskmemory/EntityInstance.h
+    core/diskmemory/EntitySnapshot.h
+    core/diskmemory/Memory.h
+    core/diskmemory/ProviderSegment.h
+
+    core/ice_conversions_templates.h
     core/ice_conversions.h
-    core/Memory.h
     core/Visitor.h
-    core/ProviderSegment.h
-
-    core/detail/EntityContainer.h
-    core/detail/MaxHistorySize.h
-    core/detail/MemoryContainer.h
-    core/detail/MemoryItem.h
-    core/detail/TypedEntityContainer.h
-
-    core/io/FileSystemLookupMemory.h
-    core/io/MemoryFileSystemStorage.h
-    core/io/DiskReaderWriter.h
-    core/io/DiskWriter/DiskWriter.h
-    core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.h
-    core/io/DiskReader/DiskReader.h
-    core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.h
 
     client.h
     client/ComponentPlugin.h
@@ -126,11 +180,23 @@ set(LIB_HEADERS
     server/RemoteGuiAronDataVisitor.h
 
     server/query_proc.h
-    server/query_proc/BaseQueryProcessor.h
-    server/query_proc/EntityQueryProcessor.h
-    server/query_proc/ProviderSegmentQueryProcessor.h
-    server/query_proc/CoreSegmentQueryProcessor.h
-    server/query_proc/MemoryQueryProcessor.h
+    server/query_proc/base/BaseQueryProcessorBase.h
+    server/query_proc/base/EntityQueryProcessorBase.h
+    server/query_proc/base/ProviderSegmentQueryProcessorBase.h
+    server/query_proc/base/CoreSegmentQueryProcessorBase.h
+    server/query_proc/base/MemoryQueryProcessorBase.h
+
+    server/query_proc/workingmemory/BaseQueryProcessor.h
+    server/query_proc/workingmemory/EntityQueryProcessor.h
+    server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h
+    server/query_proc/workingmemory/CoreSegmentQueryProcessor.h
+    server/query_proc/workingmemory/MemoryQueryProcessor.h
+
+    server/query_proc/longtermmemory/BaseQueryProcessor.h
+    server/query_proc/longtermmemory/EntityQueryProcessor.h
+    server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h
+    server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h
+    server/query_proc/longtermmemory/MemoryQueryProcessor.h
 
     mns.h
     mns/MemoryNameSystem.h
@@ -154,5 +220,6 @@ armarx_enable_aron_file_generation_for_target(
 
 add_library(RobotAPI::libraries::armem ALIAS "${LIB_NAME}")
 
+
 # add unit tests
 add_subdirectory(test)
diff --git a/source/RobotAPI/libraries/armem/client/Query.cpp b/source/RobotAPI/libraries/armem/client/Query.cpp
index 1c649e3405316704c4df8f652ee37ec893a77bca..1777839f24e6f2522e7f0efb9670f79ff463231b 100644
--- a/source/RobotAPI/libraries/armem/client/Query.cpp
+++ b/source/RobotAPI/libraries/armem/client/Query.cpp
@@ -1,7 +1,6 @@
 #include "Query.h"
 
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 
 namespace armarx::armem::client
 {
@@ -52,13 +51,13 @@ namespace armarx::armem
     void client::toIce(armem::query::data::Result& ice, const QueryResult& result)
     {
         toIce(ice, dynamic_cast<const detail::SuccessHeader&>(result));
-        toIce(ice.memory, result.memory);
+        armarx::armem::toIce(ice.memory, result.memory);
     }
 
     void client::fromIce(const armem::query::data::Result& ice, QueryResult& result)
     {
         fromIce(ice, dynamic_cast<detail::SuccessHeader&>(result));
-        fromIce(ice.memory, result.memory);
+        armarx::armem::fromIce(ice.memory, result.memory);
     }
 
 }
diff --git a/source/RobotAPI/libraries/armem/client/Query.h b/source/RobotAPI/libraries/armem/client/Query.h
index 06379aff71b04c8e5bacfce866a53a494d8ac1b5..b22c880013ad594acad439f3941eaff324763287 100644
--- a/source/RobotAPI/libraries/armem/client/Query.h
+++ b/source/RobotAPI/libraries/armem/client/Query.h
@@ -3,10 +3,10 @@
 // RobotAPI
 #include <RobotAPI/interface/armem/query.h>
 
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 #include <RobotAPI/libraries/armem/core/SuccessHeader.h>
 #include <RobotAPI/libraries/armem/core/DataMode.h>
-#include <RobotAPI/libraries/armem/core/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
 
 
 namespace armarx::armem::client
@@ -31,7 +31,7 @@ namespace armarx::armem::client
      */
     struct QueryResult : public detail::SuccessHeader
     {
-        Memory memory;
+        wm::Memory memory;
 
 
         static QueryResult fromIce(const armem::query::data::Result& ice);
diff --git a/source/RobotAPI/libraries/armem/client/Reader.cpp b/source/RobotAPI/libraries/armem/client/Reader.cpp
index 8c336da2fcee343364e479734203a63cfef55625..d9cf1e4f39d48bbc6f4aeb1dd39bc448c3cd6cbf 100644
--- a/source/RobotAPI/libraries/armem/client/Reader.cpp
+++ b/source/RobotAPI/libraries/armem/client/Reader.cpp
@@ -9,7 +9,7 @@
 namespace armarx::armem::client
 {
 
-    Reader::Reader(server::ReadingMemoryInterfacePrx memory) : memory(memory)
+    Reader::Reader(server::ReadingMemoryInterfacePrx memory) : memoryPrx(memory)
     {
     }
 
@@ -33,7 +33,7 @@ namespace armarx::armem::client
         armem::query::data::Result result;
         try
         {
-            result = memory->query(input);
+            result = memoryPrx->query(input);
         }
         catch (const Ice::ConnectionRefusedException& e)
         {
@@ -63,7 +63,7 @@ namespace armarx::armem::client
         return this->query(input);
     }
 
-    QueryResult Reader::getAll(DataMode dataMode)
+    QueryResult Reader::getAll(DataMode dataMode) const
     {
         using namespace client::query_fns;
 
@@ -73,7 +73,7 @@ namespace armarx::armem::client
         return this->query(qb.buildQueryInput());
     }
 
-    QueryResult Reader::getLatestSnapshots(DataMode dataMode)
+    QueryResult Reader::getLatestSnapshots(DataMode dataMode) const
     {
         using namespace client::query_fns;
 
@@ -84,7 +84,7 @@ namespace armarx::armem::client
     }
 
     void
-    Reader::updated(const std::vector<MemoryID>& updatedSnapshotIDs)
+    Reader::updated(const std::vector<MemoryID>& updatedSnapshotIDs) const
     {
         for (const auto& [subscription, callback] : callbacks)
         {
@@ -105,6 +105,21 @@ namespace armarx::armem::client
         }
     }
 
+    data::StoreResult
+    Reader::readAndStore(const data::StoreInput& input) const
+    {
+        server::StoringMemoryInterfacePrx storingMemoryPrx = server::StoringMemoryInterfacePrx::checkedCast(memoryPrx);
+        if (storingMemoryPrx)
+        {
+            return storingMemoryPrx->store(input);
+        }
+        else
+        {
+            ARMARX_WARNING << "Could not store a query into the LTM. It seems like the Memory does not implement the StoringMemoryInterface.";
+            return {};
+        }
+    }
+
 
     void
     Reader::subscribe(const MemoryID& id, callback callback)
@@ -116,7 +131,7 @@ namespace armarx::armem::client
     void
     Reader::setReadingMemory(server::ReadingMemoryInterfacePrx memory)
     {
-        this->memory = memory;
+        this->memoryPrx = memory;
     }
 
 }
diff --git a/source/RobotAPI/libraries/armem/client/Reader.h b/source/RobotAPI/libraries/armem/client/Reader.h
index 26237f31b832057908823152057bc5d1f360df97..cf0adbb45b087faf16188cb89a45bd22839dda97 100644
--- a/source/RobotAPI/libraries/armem/client/Reader.h
+++ b/source/RobotAPI/libraries/armem/client/Reader.h
@@ -8,9 +8,11 @@
 
 // RobotAPI
 #include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
+#include <RobotAPI/interface/armem/server/StoringMemoryInterface.h>
 #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-#include <RobotAPI/libraries/armem/core/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
 
 #include "Query.h"
 
@@ -38,7 +40,6 @@ namespace armarx::armem::client
 
         void setReadingMemory(server::ReadingMemoryInterfacePrx memory);
 
-
         QueryResult query(const QueryInput& input) const;
         armem::query::data::Result query(const armem::query::data::Input& input) const;
 
@@ -46,9 +47,11 @@ namespace armarx::armem::client
         QueryResult query(const armem::query::data::MemoryQuerySeq& queries, DataMode dataMode = DataMode::WithData) const;
 
 
-        QueryResult getAll(DataMode dataMode = DataMode::WithData);
-        QueryResult getLatestSnapshots(DataMode dataMode = DataMode::WithData);
+        QueryResult getAll(DataMode dataMode = DataMode::WithData) const;
+        QueryResult getLatestSnapshots(DataMode dataMode = DataMode::WithData) const;
 
+        //data::StoreResult readAndStore(data::StoreInputSeq& input);
+        data::StoreResult readAndStore(const data::StoreInput& input) const;
 
         void subscribe(const MemoryID& subscriptionID, callback callback);
         /**
@@ -67,17 +70,17 @@ namespace armarx::armem::client
             subscribe(subscriptionID, cb);
         }
         /// Function handling updates from the MemoryListener ice topic.
-        void updated(const std::vector<MemoryID>& updatedIDs);
+        void updated(const std::vector<MemoryID>& updatedIDs) const;
 
 
         inline operator bool() const
         {
-            return bool(memory);
+            return bool(memoryPrx);
         }
 
     public:
 
-        server::ReadingMemoryInterfacePrx memory;
+        server::ReadingMemoryInterfacePrx memoryPrx;
 
     private:
 
diff --git a/source/RobotAPI/libraries/armem/client/Writer.h b/source/RobotAPI/libraries/armem/client/Writer.h
index f4c0754a10c129062f482d581d3d81f5bc0977ce..9c6e8851e4fe3792ad728e90eaa9319a88568e0c 100644
--- a/source/RobotAPI/libraries/armem/client/Writer.h
+++ b/source/RobotAPI/libraries/armem/client/Writer.h
@@ -2,7 +2,7 @@
 
 #include <RobotAPI/interface/armem/server/WritingMemoryInterface.h>
 
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 
 
 namespace armarx::armem::client
diff --git a/source/RobotAPI/libraries/armem/client/query/selectors.cpp b/source/RobotAPI/libraries/armem/client/query/selectors.cpp
index 13d4e14c87054ce1010c81957563965d70c2b3e6..f2bae712818b566ef51444aafb84af6031d338d0 100644
--- a/source/RobotAPI/libraries/armem/client/query/selectors.cpp
+++ b/source/RobotAPI/libraries/armem/client/query/selectors.cpp
@@ -1,6 +1,6 @@
 #include "selectors.h"
 
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 
 
 namespace dq = ::armarx::armem::query::data;
diff --git a/source/RobotAPI/libraries/armem/core.h b/source/RobotAPI/libraries/armem/core.h
index 8e0a1ea2280a128fac3339fbdfdc1da39c8cfdbb..c8ddee31ce054decbc8fdc33edf7959502601da7 100644
--- a/source/RobotAPI/libraries/armem/core.h
+++ b/source/RobotAPI/libraries/armem/core.h
@@ -1,18 +1,18 @@
 #pragma once
 
 #include "core/error.h"
-#include "core/ice_conversions.h"
 #include "core/Commit.h"
 #include "core/DataMode.h"
 #include "core/MemoryID.h"
 #include "core/Time.h"
 
-#include "core/Memory.h"
-#include "core/CoreSegment.h"
-#include "core/ProviderSegment.h"
-#include "core/Entity.h"
-#include "core/EntitySnapshot.h"
-#include "core/EntityInstance.h"
+#include "core/workingmemory/Memory.h"
+#include "core/workingmemory/CoreSegment.h"
+#include "core/workingmemory/ProviderSegment.h"
+#include "core/workingmemory/Entity.h"
+#include "core/workingmemory/EntitySnapshot.h"
+#include "core/workingmemory/EntityInstance.h"
+#include "core/workingmemory/ice_conversions.h"
 
 
 namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem/core/Commit.h b/source/RobotAPI/libraries/armem/core/Commit.h
index 6a25f7a7c0e362dbf25ba9ee4a895724bea50a05..ff3215ab7ea6d01de892eec9f99ec911e6e667b8 100644
--- a/source/RobotAPI/libraries/armem/core/Commit.h
+++ b/source/RobotAPI/libraries/armem/core/Commit.h
@@ -10,7 +10,6 @@
 
 namespace armarx::armem
 {
-
     /**
      * @brief An update of an entity for a specific point in time.
      */
diff --git a/source/RobotAPI/libraries/armem/core/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/CoreSegment.cpp
deleted file mode 100644
index 61098ee9a268d6bd06748c02878cc70e013e72af..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/CoreSegment.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "CoreSegment.h"
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "error.h"
-
-
-namespace armarx::armem
-{
-
-    CoreSegment::CoreSegment()
-    {
-    }
-
-    CoreSegment::CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
-        CoreSegment(name, MemoryID(), aronType)
-    {
-    }
-
-    CoreSegment::CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
-        CoreSegment(parentID.getMemoryID().withCoreSegmentName(name), aronType)
-    {
-    }
-
-    CoreSegment::CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType) :
-        Base(id, aronType)
-    {
-    }
-
-    CoreSegment::CoreSegment(const CoreSegment& other) : Base(other)
-    {
-        *this = other;
-    }
-
-    CoreSegment& CoreSegment::operator=(const CoreSegment& other)
-    {
-        other._copySelf(*this);
-        other._copyElements(*this, true);
-        return *this;
-    }
-
-    bool CoreSegment::equalsDeep(const CoreSegment& other) const
-    {
-        if (size() != other.size())
-        {
-            return false;
-        }
-        for (const auto& [key, provider] : providerSegments)
-        {
-            if (not other.hasProviderSegment(key))
-            {
-                return false;
-            }
-            if (not provider.equalsDeep(other.getProviderSegment(key)))
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    CoreSegment::~CoreSegment()
-    {
-    }
-
-    const std::string& CoreSegment::name() const
-    {
-        return id().coreSegmentName;
-    }
-
-    void CoreSegment::_copyElements(CoreSegment& other, bool withData) const
-    {
-        other.providerSegments.clear();
-        for (const auto& [name, providerSegment] : this->providerSegments)
-        {
-            other.addProviderSegment(providerSegment.copy(withData));
-        }
-    }
-
-
-    bool CoreSegment::hasProviderSegment(const std::string& name) const
-    {
-        return providerSegments.count(name) > 0;
-    }
-
-    ProviderSegment& CoreSegment::getProviderSegment(const std::string& name)
-    {
-        return const_cast<ProviderSegment&>(const_cast<const CoreSegment*>(this)->getProviderSegment(name));
-    }
-
-    const ProviderSegment& CoreSegment::getProviderSegment(const std::string& name) const
-    {
-        auto it = this->providerSegments.find(name);
-        if (it != providerSegments.end())
-        {
-            return it->second;
-        }
-        else
-        {
-            throw armem::error::MissingEntry("provider segment", name, getLevelName(), this->name());
-        }
-    }
-
-    const Entity& CoreSegment::getEntity(const MemoryID& id) const
-    {
-        _checkContainerName(id.coreSegmentName, this->name());
-        return getProviderSegment(id.providerSegmentName).getEntity(id);
-    }
-
-
-    ProviderSegment& CoreSegment::addProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr providerSegmentType)
-    {
-        aron::typenavigator::ObjectNavigatorPtr type = providerSegmentType ? providerSegmentType : this->aronType();
-        return addProviderSegment(ProviderSegment(name, type));
-    }
-
-    ProviderSegment& CoreSegment::addProviderSegment(const ProviderSegment& providerSegment)
-    {
-        return addProviderSegment(ProviderSegment(providerSegment));
-    }
-
-    ProviderSegment& CoreSegment::addProviderSegment(ProviderSegment&& providerSegment)
-    {
-        if (hasProviderSegment(providerSegment.name()))
-        {
-            throw armem::error::ContainerEntryAlreadyExists(
-                providerSegment.getLevelName(), providerSegment.name(), getLevelName(), this->name());
-        }
-
-        auto it = providerSegments.emplace(providerSegment.name(), std::move(providerSegment)).first;
-        it->second.id().setCoreSegmentID(id());
-        it->second.setMaxHistorySize(maxHistorySize);
-        return it->second;
-    }
-
-    void CoreSegment::setMaxHistorySize(long maxSize)
-    {
-        MaxHistorySize::setMaxHistorySize(maxSize);
-        for (auto& [name, seg] : providerSegments)
-        {
-            seg.setMaxHistorySize(maxSize);
-        }
-    }
-
-    std::string CoreSegment::getLevelName() const
-    {
-        return "core segment";
-    }
-
-    CoreSegment::ContainerT& CoreSegment::_underlyingContainer()
-    {
-        return providerSegments;
-    }
-
-
-    MemoryID CoreSegment::update(const EntityUpdate& update)
-    {
-        _checkContainerName(update.entityID.coreSegmentName, this->name());
-
-        auto it = this->providerSegments.find(update.entityID.providerSegmentName);
-        if (it != providerSegments.end())
-        {
-            return it->second.update(update);
-        }
-        else
-        {
-            throw armem::error::MissingEntry("provider segment", update.entityID.providerSegmentName,
-                                             getLevelName(), name());
-        }
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/CoreSegment.h b/source/RobotAPI/libraries/armem/core/CoreSegment.h
deleted file mode 100644
index f492c0f1a735bd8c7343bfb503bc66f3add11908..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/CoreSegment.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#pragma once
-
-#include <map>
-#include <string>
-
-#include "ProviderSegment.h"
-#include "detail/TypedEntityContainer.h"
-#include "detail/MaxHistorySize.h"
-
-
-namespace armarx::armem
-{
-
-    /**
-     * @brief Data of a core segment containing multiple provider segments.
-     */
-    class CoreSegment :
-        public detail::TypedEntityContainer<ProviderSegment, CoreSegment>
-        , public detail::MaxHistorySize
-    {
-        using Base = detail::TypedEntityContainer<ProviderSegment, CoreSegment>;
-
-    public:
-
-        CoreSegment();
-        CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-        CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-        CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-
-        CoreSegment(const CoreSegment& other);
-        CoreSegment& operator=(const CoreSegment& other);
-
-        ~CoreSegment() override;
-
-
-        using Base::name;
-        const std::string& name() const override;
-
-
-        bool hasProviderSegment(const std::string& name) const;
-        ProviderSegment& getProviderSegment(const std::string& name);
-        const ProviderSegment& getProviderSegment(const std::string& name) const;
-
-
-        using Base::getEntity;
-        const Entity& getEntity(const MemoryID& id) const override;
-
-
-        using Base::update;
-        virtual MemoryID update(const EntityUpdate& update) override;
-
-        /**
-         * @brief Add an empty provider segment with the given name and optional provider segment type.
-         * @param name The segment name.
-         * @param providerSegmentType The provider type. If nullptr, the core segment type is used.
-         * @return The added provider segment.
-         */
-        ProviderSegment& addProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr providerSegmentType = nullptr);
-        /// Copy and insert a provider segment.
-        ProviderSegment& addProviderSegment(const ProviderSegment& providerSegment);
-        /// Move and insert a provider segment.
-        ProviderSegment& addProviderSegment(ProviderSegment&& providerSegment);
-
-
-        /**
-         * @brief Sets the maximum history size of entities in this segment.
-         * This affects all current entities as well as new ones.
-         * @see Entity::setMaxHistorySize()
-         */
-        void setMaxHistorySize(long maxSize) override;
-
-
-        bool equalsDeep(const CoreSegment& other) const;
-
-
-        // MemoryItem interface
-    public:
-        std::string getLevelName() const override;
-
-        // MemoryContainer interface
-    protected:
-        ContainerT& _underlyingContainer() override;
-        void _copyElements(CoreSegment& other, bool withData) const override;
-
-
-    public:
-
-        /// The provider segments.
-        std::map<std::string, ProviderSegment> providerSegments;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/Entity.cpp b/source/RobotAPI/libraries/armem/core/Entity.cpp
deleted file mode 100644
index 876f5a19b63f6667c6e591644eef0ed2c5b71e09..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/Entity.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-#include "Entity.h"
-
-#include <SimoxUtility/algorithm/get_map_keys_values.h>
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "error.h"
-
-
-namespace armarx::armem
-{
-
-    Entity::Entity()
-    {
-    }
-
-    Entity::Entity(const std::string& name, const MemoryID& parentID) :
-        Entity(parentID.withEntityName(name))
-    {
-    }
-
-    Entity::Entity(const MemoryID& id) : Base(id)
-    {
-    }
-
-    Entity::Entity(const Entity& other) : Base(other)
-    {
-        *this = other;
-    }
-
-    Entity& Entity::operator=(const Entity& other)
-    {
-        other._copySelf(*this);
-        other._copyElements(*this, true);
-        return *this;
-    }
-
-    bool Entity::equalsDeep(const Entity& other) const
-    {
-        if (size() != other.size())
-        {
-            return false;
-        }
-        for (const auto& [key, snapshot] : history)
-        {
-            if (not other.hasSnapshot(key))
-            {
-                return false;
-            }
-            if (not snapshot.equalsDeep(other.getSnapshot(key)))
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-
-    void Entity::_copySelf(Entity& other) const
-    {
-        Base::_copySelf(other);
-        other.maxHistorySize = this->maxHistorySize;
-    }
-
-    void Entity::_copyElements(Entity& other, bool withData) const
-    {
-        other.history.clear();
-        for (const auto& [time, snapshot] : this->history)
-        {
-            other.addSnapshot(snapshot.copy(withData));
-        }
-    }
-
-
-    bool Entity::hasSnapshot(Time time) const
-    {
-        return history.count(time) > 0;
-    }
-
-    bool Entity::hasSnapshotData(Time time) const
-    {
-        return history.count(time) > 0;
-    }
-
-    EntitySnapshot& Entity::getSnapshot(Time time)
-    {
-        return const_cast<EntitySnapshot&>(const_cast<const Entity*>(this)->getSnapshot(time));
-    }
-
-    const EntitySnapshot& Entity::getSnapshot(Time time) const
-    {
-        auto it = history.find(time);
-        if (it != history.end())
-        {
-            return it->second;
-        }
-        else
-        {
-            throw error::MissingEntry("entity snapshot", toDateTimeMilliSeconds(time),
-                                      getLevelName(), this->id().str());
-        }
-    }
-
-    EntitySnapshot& Entity::getSnapshot(const MemoryID& id)
-    {
-        return const_cast<EntitySnapshot&>(const_cast<const Entity*>(this)->getSnapshot(id));
-    }
-
-    const EntitySnapshot& Entity::getSnapshot(const MemoryID& id) const
-    {
-        checkEntityName(id.entityName);
-        return getSnapshot(id.timestamp);
-    }
-
-    EntitySnapshot& Entity::getLatestSnapshot()
-    {
-        return const_cast<EntitySnapshot&>(const_cast<const Entity*>(this)->getLatestSnapshot());
-    }
-
-    const EntitySnapshot& Entity::getLatestSnapshot() const
-    {
-        return getLatestItem().second;
-    }
-
-    Time Entity::getLatestTimestamp() const
-    {
-        return getLatestItem().first;
-    }
-
-    std::vector<Time> Entity::getTimestamps() const
-    {
-        return simox::alg::get_keys(history);
-    }
-
-
-    EntitySnapshot& Entity::addSnapshot(const EntitySnapshot& snapshot)
-    {
-        return addSnapshot(EntitySnapshot(snapshot));
-    }
-
-
-    EntitySnapshot& Entity::addSnapshot(EntitySnapshot&& snapshot)
-    {
-        auto it = history.emplace(snapshot.time(), std::move(snapshot)).first;
-        it->second.id().setEntityID(id());
-        return it->second;
-    }
-
-    EntitySnapshot& Entity::addSnapshot(const Time& timestamp)
-    {
-        return addSnapshot(EntitySnapshot(timestamp));
-    }
-
-    MemoryID Entity::update(const EntityUpdate& update)
-    {
-        checkEntityName(update.entityID.entityName);
-        id() = update.entityID;
-
-        EntitySnapshot* snapshot;
-
-        auto it = history.find(update.timeCreated);
-        if (it == history.end())
-        {
-            // Insert into history.
-            snapshot = &addSnapshot(update.timeCreated);
-            truncateHistoryToSize();
-        }
-        else
-        {
-            snapshot = &it->second;
-        }
-        // Update entry.
-        snapshot->update(update);
-
-        return snapshot->id();
-    }
-
-
-    void Entity::setMaxHistorySize(long maxSize)
-    {
-        this->maxHistorySize = maxSize;
-        truncateHistoryToSize();
-    }
-
-
-    void Entity::truncateHistoryToSize()
-    {
-        if (maxHistorySize >= 0)
-        {
-            while (history.size() > size_t(maxHistorySize))
-            {
-                history.erase(history.begin());
-            }
-            ARMARX_CHECK_LESS_EQUAL(history.size(), maxHistorySize);
-        }
-    }
-
-    void Entity::checkEntityName(const std::string& name) const
-    {
-        if (name != this->name())
-        {
-            throw armem::error::ContainerNameMismatch(name, getLevelName(), this->name());
-        }
-    }
-
-    const std::map<Time, EntitySnapshot>::value_type& Entity::getLatestItem() const
-    {
-        if (history.empty())
-        {
-            throw armem::error::EntityHistoryEmpty(name(), "when getting the latest snapshot.");
-        }
-        return *history.rbegin();
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/Entity.h b/source/RobotAPI/libraries/armem/core/Entity.h
deleted file mode 100644
index b81ffe76199f7a978d822a4d91cc421b48537682..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/Entity.h
+++ /dev/null
@@ -1,192 +0,0 @@
-#pragma once
-
-#include <map>
-#include <string>
-
-#include "../core/Time.h"
-#include "../core/MemoryID.h"
-
-#include "EntitySnapshot.h"
-#include "detail/MemoryContainer.h"
-
-
-namespace armarx::armem
-{
-
-    /**
-     * @brief An entity over a period of time.
-     *
-     * An entity should be a physical thing or abstract concept existing
-     * (and potentially evolving) over some time.
-     *
-     * Examples are:
-     * - objects (the green box)
-     * - agents (robot, human)
-     * - locations (frige, sink)
-     * - grasp affordances (general, or for a specific object)
-     * - images
-     * - point clouds
-     * - other sensory values
-     *
-     * At each point in time (`EntitySnapshot`), the entity can have a
-     * (potentially variable) number of instances (`EntityInstance`),
-     * each containing a single `AronData` object of a specific `AronType`.
-     */
-    class Entity :
-        public detail::MemoryContainer<std::map<Time, EntitySnapshot>, Entity>
-    {
-        using Base = detail::MemoryContainer<std::map<Time, EntitySnapshot>, Entity>;
-
-
-    public:
-
-        Entity();
-        Entity(const std::string& name, const MemoryID& parentID = {});
-        Entity(const MemoryID& id);
-
-        /// Copy the history from `other` to this.
-        Entity(const Entity& other);
-        /// Copy the history from `other` to this.
-        Entity& operator=(const Entity& other);
-
-
-        inline const std::string& name() const
-        {
-            return id().entityName;
-        }
-        inline std::string& name()
-        {
-            return id().entityName;
-        }
-
-
-        /**
-         * @brief Indicates whether a history entry for the given time exists.
-         */
-        bool hasSnapshot(Time time) const;
-        /**
-         * @brief Indicates whether a history entry for the given time exists
-         * and its data is not null.
-         */
-        bool hasSnapshotData(Time time) const;
-
-
-        /**
-         * @brief Get the latest timestamp.
-         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
-         */
-        Time getLatestTimestamp() const;
-        /**
-         * @brief Get all timestamps in the history.
-         */
-        std::vector<Time> getTimestamps() const;
-
-
-        /**
-         * @brief Get a snapshot.
-         * @param time The time.
-         * @return The snapshot, if it exists.
-         *
-         * @throws `armem::error::MissingEntry` If there is no such entry.
-         * @throws `armem::error::MissingData` If the entry has no data.
-         */
-        EntitySnapshot& getSnapshot(Time time);
-        const EntitySnapshot& getSnapshot(Time time) const;
-
-        EntitySnapshot& getSnapshot(const MemoryID& id);
-        const EntitySnapshot& getSnapshot(const MemoryID& id) const;
-
-        /**
-         * @brief Return the snapshot with the most recent timestamp.
-         * @return The latest snapshot.
-         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
-         * @throw `armem::error::MissingData` If the latest snapshot has no data.
-         */
-        EntitySnapshot& getLatestSnapshot();
-        const EntitySnapshot& getLatestSnapshot() const;
-
-
-        /**
-         * @brief Add the given update to this entity's history.
-         * @param update The update.
-         * @return The snapshot ID of the update.
-         */
-        MemoryID update(const EntityUpdate& update);
-
-        /**
-         * @brief Add a single snapshot with data.
-         * @param snapshot The snapshot.
-         * @return The stored snapshot.
-         */
-        EntitySnapshot& addSnapshot(const EntitySnapshot& snapshot);
-        EntitySnapshot& addSnapshot(EntitySnapshot&& snapshot);
-        EntitySnapshot& addSnapshot(const Time& timestamp);
-
-
-        /**
-         * @brief Sets the maximum history size.
-         *
-         * The current history is truncated if necessary.
-         */
-        void setMaxHistorySize(long maxSize);
-
-
-        bool equalsDeep(const Entity& other) const;
-
-
-    protected:
-
-        void _copySelf(Entity& other) const override;
-        void _copyElements(Entity& other, bool withData) const override;
-
-
-
-    private:
-
-        /// If maximum size is set, ensure `history`'s is not higher.
-        void truncateHistoryToSize();
-        void checkEntityName(const std::string& name) const;
-        ContainerT::iterator _addSnapshot();
-
-        /**
-         * @brief Return the snapshot with the most recent timestamp.
-         * @return The latest snapshot.
-         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
-         */
-        const std::map<Time, EntitySnapshot>::value_type& getLatestItem() const;
-
-
-    public:
-
-        std::map<Time, EntitySnapshot> history;
-
-        /**
-         * @brief Maximum size of `history`
-         *
-         * If negative, the size of `history` is not limited.
-         */
-        long maxHistorySize = -1;
-        // ToDo: Add max age;
-        // ToDo in future: keep/remove predicate
-
-        // MemoryItem interface
-    public:
-        std::string getKeyString() const override
-        {
-            return id().entityName;
-        }
-        std::string getLevelName() const override
-        {
-            return "entity";
-        }
-
-        // MemoryContainer interface
-    protected:
-        ContainerT& _underlyingContainer() override
-        {
-            return history;
-        }
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/EntitySnapshot.cpp
deleted file mode 100644
index 7a53400f9c75849c805e443e61afafc83f43e7c0..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/EntitySnapshot.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "EntitySnapshot.h"
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "error.h"
-
-
-namespace armarx::armem
-{
-
-
-    EntitySnapshot::EntitySnapshot()
-    {
-    }
-
-    EntitySnapshot::EntitySnapshot(Time time, const MemoryID& parentID) :
-        EntitySnapshot(parentID.withTimestamp(time))
-    {
-    }
-
-    EntitySnapshot::EntitySnapshot(const MemoryID& id) : Base(id)
-    {
-    }
-
-    EntitySnapshot::EntitySnapshot(const EntitySnapshot& other) : Base(other)
-    {
-        *this = other;
-    }
-
-    EntitySnapshot& EntitySnapshot::operator=(const EntitySnapshot& other)
-    {
-        other._copySelf(*this);
-        other._copyElements(*this, true);
-        return *this;
-    }
-
-    bool EntitySnapshot::equalsDeep(const EntitySnapshot& other) const
-    {
-        if (size() != other.size())
-        {
-            return false;
-        }
-        int i = 0;
-        for (const auto& instance : instances)
-        {
-            if (not instance.equalsDeep(other.getInstance(i)))
-            {
-                return false;
-            }
-            i++;
-        }
-        return true;
-    }
-
-
-    void EntitySnapshot::_copyElements(EntitySnapshot& other, bool withData) const
-    {
-        other.instances.clear();
-        other.instances.reserve(this->instances.size());
-        for (const auto& data : this->instances)
-        {
-            other.instances.emplace_back(data.copy(withData));
-        }
-    }
-
-
-    void EntitySnapshot::update(const EntityUpdate& update,
-                                std::optional<MemoryID> parentID)
-    {
-        if (parentID)
-        {
-            id() = *parentID;
-        }
-        time() = update.timeCreated;
-
-        instances.clear();
-        for (int i = 0; i < int(update.instancesData.size()); ++i)
-        {
-            EntityInstance& data = instances.emplace_back(i, id());
-            data.update(update, i);
-        }
-    }
-
-    bool EntitySnapshot::hasInstance(int index) const
-    {
-        size_t si = size_t(index);
-        return index >= 0 && si < instances.size();
-    }
-
-
-    EntityInstance& EntitySnapshot::getInstance(int index)
-    {
-        return const_cast<EntityInstance&>(const_cast<const EntitySnapshot*>(this)->getInstance(index));
-    }
-
-    const EntityInstance& EntitySnapshot::getInstance(int index) const
-    {
-        if (hasInstance(index))
-        {
-            size_t si = size_t(index);
-            return instances[si];
-        }
-        else
-        {
-            throw armem::error::MissingEntry(EntityInstance().getLevelName(), std::to_string(index),
-                                             getLevelName(), toDateTimeMilliSeconds(time()));
-        }
-    }
-
-
-    EntityInstance& EntitySnapshot::getInstance(const MemoryID& id)
-    {
-        return const_cast<EntityInstance&>(const_cast<const EntitySnapshot*>(this)->getInstance(id));
-    }
-
-    const EntityInstance& EntitySnapshot::getInstance(const MemoryID& id) const
-    {
-        if (!id.hasInstanceIndex())
-        {
-            throw armem::error::InvalidMemoryID(id, "ID has no instance index.");
-        }
-        return getInstance(id.instanceIndex);
-    }
-
-    EntityInstance& EntitySnapshot::addInstance(const EntityInstance& instance)
-    {
-        return addInstance(EntityInstance(instance));
-    }
-
-
-    EntityInstance& EntitySnapshot::addInstance(EntityInstance&& instance)
-    {
-        if (instance.index() > 0 && (size_t) instance.index() < instances.size())
-        {
-            throw error::InvalidArgument(std::to_string(instance.index()), "EntitySnapshot::addInstance",
-                                         "Cannot add an EntityInstance because its index already exists.");
-        }
-        if (instance.index() > 0 && (size_t) instance.index() > instances.size())
-        {
-            throw error::InvalidArgument(std::to_string(instance.index()), "EntitySnapshot::addInstance",
-                                         "Cannot add an EntityInstance because its index is too big.");
-        }
-
-        int new_index = instances.size();
-        auto& it = instances.emplace_back(std::move(instance));
-        it.index() = new_index;
-        return it;
-    }
-
-    std::string EntitySnapshot::getKeyString() const
-    {
-        return toDateTimeMilliSeconds(this->time());
-    }
-
-    std::string EntitySnapshot::getLevelName() const
-    {
-        return "entity snapshot";
-    }
-
-    EntitySnapshot::ContainerT& EntitySnapshot::_underlyingContainer()
-    {
-        return instances;
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/EntitySnapshot.h
deleted file mode 100644
index da1301ccfaf08701358c7c912dfd617ee7e7a67b..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/EntitySnapshot.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#pragma once
-
-#include <memory>
-#include <vector>
-
-#include "../core/MemoryID.h"
-#include "../core/Time.h"
-
-#include "EntityInstance.h"
-#include "detail/MemoryItem.h"
-#include "detail/MemoryContainer.h"
-
-
-namespace armarx::armem
-{
-
-    /**
-     * @brief Data of an entity at one point in time.
-     */
-    class EntitySnapshot :
-        public detail::MemoryContainer<std::vector<EntityInstance>, EntitySnapshot>
-    {
-        using Base = detail::MemoryContainer<std::vector<EntityInstance>, EntitySnapshot>;
-
-    public:
-
-        EntitySnapshot();
-        EntitySnapshot(Time time, const MemoryID& parentID = {});
-        EntitySnapshot(const MemoryID& id);
-
-        /// Copy the instances from `other` to this.
-        EntitySnapshot(const EntitySnapshot& other);
-        /// Copy the instances from `other` to this.
-        EntitySnapshot& operator=(const EntitySnapshot& other);
-
-
-        inline Time& time()
-        {
-            return id().timestamp;
-        }
-        inline const Time& time() const
-        {
-            return id().timestamp;
-        }
-
-
-        void update(const EntityUpdate& update,
-                    std::optional<MemoryID> parentID = std::nullopt);
-
-
-        bool hasInstance(int index) const;
-
-        /**
-         * @brief Get the given instance.
-         * @param index The instance's index.
-         * @return The instance.
-         * @throw `armem::error::MissingEntry` If the given index is invalid.
-         */
-        EntityInstance& getInstance(int index);
-        const EntityInstance& getInstance(int index) const;
-        /**
-         * @brief Get the given instance.
-         * @param index The instance's index.
-         * @return The instance.
-         * @throw `armem::error::MissingEntry` If the given index is invalid.
-         * @throw `armem::error::InvalidMemoryID` If memory ID does not have an instance index.
-         */
-        EntityInstance& getInstance(const MemoryID& id);
-        const EntityInstance& getInstance(const MemoryID& id) const;
-
-
-        /**
-         * @brief Add a single instance with data.
-         * @param instance The instance.
-         * @return The stored instance.
-         * @throw `armem::error::InvalidArgument` If the given index is invalid. Must be equal to instances.size() or -1 (meaning push_back)
-         */
-        EntityInstance& addInstance(const EntityInstance& instance);
-        EntityInstance& addInstance(EntityInstance&& instance);
-
-
-        bool equalsDeep(const EntitySnapshot& other) const;
-
-
-        // MemoryItem interface
-    public:
-        std::string getKeyString() const override;
-        std::string getLevelName() const override;
-
-
-        // MemoryContainer interface
-    protected:
-        ContainerT& _underlyingContainer() override;
-        void _copyElements(EntitySnapshot& other, bool withData) const override;
-
-
-    public:
-
-        std::vector<EntityInstance> instances;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/Memory.cpp b/source/RobotAPI/libraries/armem/core/Memory.cpp
deleted file mode 100644
index 3d218f0b098670cbc6e704e9e500ffecd752c2ac..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/Memory.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "Memory.h"
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "error.h"
-
-
-namespace armarx::armem
-{
-
-    Memory::Memory()
-    {
-    }
-
-    Memory::Memory(const std::string& name) : Memory(MemoryID().withMemoryName(name))
-    {
-    }
-
-    Memory::Memory(const MemoryID& id) : EntityContainer(id)
-    {
-    }
-
-    Memory::Memory(const Memory& other) : EntityContainer(other)
-    {
-        *this = other;
-    }
-
-    Memory& Memory::operator=(const Memory& other)
-    {
-        other._copySelf(*this);
-        other._copyElements(*this, true);
-        return *this;
-    }
-
-    Memory::~Memory()
-    {
-    }
-
-
-    const std::string& Memory::name() const
-    {
-        return id().memoryName;
-    }
-
-    void Memory::_copyElements(Memory& other, bool withData) const
-    {
-        other.coreSegments.clear();
-        for (const auto& [name, coreSegment] : this->coreSegments)
-        {
-            other.coreSegments.emplace(name, coreSegment.copy(withData));
-        }
-    }
-
-
-    bool Memory::hasCoreSegment(const std::string& name) const
-    {
-        return coreSegments.count(name) > 0;
-    }
-
-    CoreSegment& Memory::getCoreSegment(const std::string& name)
-    {
-        return const_cast<CoreSegment&>(const_cast<const Memory*>(this)->getCoreSegment(name));
-    }
-    const CoreSegment& Memory::getCoreSegment(const std::string& name) const
-    {
-        auto it = this->coreSegments.find(name);
-        if (it != coreSegments.end())
-        {
-            return it->second;
-        }
-        else
-        {
-            throw armem::error::MissingEntry(CoreSegment().getLevelName(), name, getLevelName(), this->name());
-        }
-    }
-
-
-    const Entity& Memory::getEntity(const MemoryID& id) const
-    {
-        _checkContainerName(id.memoryName, this->name());
-        return getCoreSegment(id.coreSegmentName).getEntity(id);
-    }
-
-
-    CoreSegment& Memory::addCoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType)
-    {
-        return addCoreSegment(CoreSegment(name, coreSegmentType));
-    }
-
-    CoreSegment& Memory::addCoreSegment(const CoreSegment& coreSegment)
-    {
-        return addCoreSegment(CoreSegment(coreSegment));
-    }
-
-    CoreSegment& Memory::addCoreSegment(CoreSegment&& coreSegment)
-    {
-        if (coreSegments.count(coreSegment.name()) > 0)
-        {
-            throw armem::error::ContainerEntryAlreadyExists(coreSegment.getLevelName(), coreSegment.name(),
-                    this->getLevelName(), this->name());
-        }
-        auto it = coreSegments.emplace(coreSegment.name(), std::move(coreSegment)).first;
-        it->second.id().setMemoryID(id());
-        return it->second;
-    }
-
-    std::vector<CoreSegment*> Memory::addCoreSegments(const std::vector<std::string>& names)
-    {
-        std::vector<CoreSegment*> segments;
-        for (const auto& name : names)
-        {
-            try
-            {
-                segments.push_back(&addCoreSegment(name));
-            }
-            catch (const armem::error::ContainerEntryAlreadyExists& e)
-            {
-                ARMARX_INFO << e.what() << "\nIgnoring multiple addition.";
-            }
-        }
-        return segments;
-    }
-
-
-    MemoryID Memory::update(const EntityUpdate& update)
-    {
-        _checkContainerName(update.entityID.memoryName, this->name());
-
-        auto it = this->coreSegments.find(update.entityID.coreSegmentName);
-        if (it != coreSegments.end())
-        {
-            return it->second.update(update);
-        }
-        else
-        {
-            throw armem::error::MissingEntry(CoreSegment().getLevelName(), update.entityID.coreSegmentName,
-                                             getLevelName(), this->name());
-        }
-    }
-
-    std::string Memory::getLevelName() const
-    {
-        return "memory";
-    }
-
-    Memory::ContainerT& Memory::_underlyingContainer()
-    {
-        return coreSegments;
-    }
-
-
-    bool Memory::equalsDeep(const Memory& other) const
-    {
-        if (size() != other.size())
-        {
-            return false;
-        }
-        for (const auto& [key, core] : coreSegments)
-        {
-            if (not other.hasCoreSegment(key))
-            {
-                return false;
-            }
-            if (not core.equalsDeep(other.getCoreSegment(key)))
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/Memory.h b/source/RobotAPI/libraries/armem/core/Memory.h
deleted file mode 100644
index 2059d0c0dcdc13e683e20fd9c4646bb499b6d1ce..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/Memory.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma once
-
-#include <map>
-#include <string>
-
-#include "CoreSegment.h"
-#include "detail/EntityContainer.h"
-
-namespace armarx::armem
-{
-
-    /**
-     * @brief Data of a memory consisting of multiple core segments.
-     */
-    class Memory : public detail::EntityContainer<CoreSegment, Memory>
-    {
-        using Base = detail::EntityContainer<CoreSegment, Memory>;
-
-    public:
-
-        Memory();
-        Memory(const std::string& name);
-        Memory(const MemoryID& id);
-
-        Memory(const Memory& other);
-        Memory& operator=(const Memory& other);
-
-        ~Memory() override;
-
-
-        using Base::name;
-        const std::string& name() const override;
-
-
-        bool hasCoreSegment(const std::string& name) const;
-
-        CoreSegment& getCoreSegment(const std::string& name);
-        const CoreSegment& getCoreSegment(const std::string& name) const;
-
-
-        using Base::getEntity;
-        const Entity& getEntity(const MemoryID& id) const override;
-
-        /**
-         * @brief Add an empty core segment with the given name.
-         * @param name The core segment name.
-         * @param coreSegmentType The core segment type (optional).
-         * @return The added core segment.
-         */
-        CoreSegment& addCoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType = nullptr);
-        /// Copy and insert a core segment.
-        CoreSegment& addCoreSegment(const CoreSegment& coreSegment);
-        /// Move and insert a core segment.
-        CoreSegment& addCoreSegment(CoreSegment&& coreSegment);
-
-        /**
-         * @brief Add multiple core segments.
-         * @param The core segment names.
-         * @return The core segments. The contained pointers are never null.
-         */
-        std::vector<CoreSegment*> addCoreSegments(const std::vector<std::string>& names);
-
-        virtual MemoryID update(const EntityUpdate& update) override;
-        using Base::update;
-
-
-        bool equalsDeep(const Memory& other) const;
-
-
-        // MemoryItem interface
-    public:
-        std::string getLevelName() const override;
-
-        // MemoryContainer interface
-    protected:
-        ContainerT& _underlyingContainer() override;
-        void _copyElements(Memory& other, bool withData) const override;
-
-
-    public:
-        std::map<std::string, CoreSegment> coreSegments;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/ProviderSegment.cpp
deleted file mode 100644
index 879932739ff86a8a9b091d561053f0f76ca08be0..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/ProviderSegment.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "ProviderSegment.h"
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "error.h"
-
-
-namespace armarx::armem
-{
-
-    ProviderSegment::ProviderSegment()
-    {
-    }
-
-    ProviderSegment::ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
-        ProviderSegment(name, MemoryID(), aronType)
-    {
-    }
-
-    ProviderSegment::ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
-        ProviderSegment(parentID.withProviderSegmentName(name), aronType)
-    {
-    }
-
-    ProviderSegment::ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType) :
-        Base(id, aronType)
-    {
-    }
-
-    ProviderSegment::ProviderSegment(const ProviderSegment& other) : Base(other)
-    {
-        *this = other;
-    }
-
-    ProviderSegment& ProviderSegment::operator=(const ProviderSegment& other)
-    {
-        other._copySelf(*this);
-        other._copyElements(*this, true);
-        return *this;
-    }
-
-    bool ProviderSegment::equalsDeep(const ProviderSegment& other) const
-    {
-        if (size() != other.size())
-        {
-            return false;
-        }
-        for (const auto& [key, value] : entities)
-        {
-            if (not other.hasEntity(key))
-            {
-                return false;
-            }
-
-            if (not value.equalsDeep(other.getEntity(key)))
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    ProviderSegment::~ProviderSegment()
-    {
-    }
-
-    const std::string& ProviderSegment::name() const
-    {
-        return id().providerSegmentName;
-    }
-
-
-    void ProviderSegment::_copySelf(ProviderSegment& other) const
-    {
-        Base::_copySelf(other);
-        other.maxHistorySize = this->maxHistorySize;
-    }
-
-    void ProviderSegment::_copyElements(ProviderSegment& other, bool withData) const
-    {
-        other.entities.clear();
-        for (const auto& [name, entity] : this->entities)
-        {
-            other.addEntity(entity.copy(withData));
-        }
-    }
-
-
-    bool ProviderSegment::hasEntity(const std::string& name) const
-    {
-        return entities.count(name) > 0;
-    }
-
-    Entity& ProviderSegment::getEntity(const std::string& name)
-    {
-        return const_cast<Entity&>(const_cast<const ProviderSegment*>(this)->getEntity(name));
-    }
-
-    const Entity& ProviderSegment::getEntity(const std::string& name) const
-    {
-        auto it = this->entities.find(name);
-        if (it != entities.end())
-        {
-            return it->second;
-        }
-        else
-        {
-            throw error::MissingEntry("entity", name, getLevelName(), this->name());
-        }
-    }
-
-    const Entity& ProviderSegment::getEntity(const MemoryID& id) const
-    {
-        _checkContainerName(id.providerSegmentName, this->name());
-        return getEntity(id.entityName);
-    }
-
-    MemoryID ProviderSegment::update(const EntityUpdate& update)
-    {
-        _checkContainerName(update.entityID.providerSegmentName, this->name());
-
-        Entity* entity;
-        auto it = this->entities.find(update.entityID.providerSegmentName);
-        if (it == entities.end())
-        {
-            // Add entity entry.
-            entity = &addEntity(update.entityID.entityName);
-            entity->setMaxHistorySize(maxHistorySize);
-        }
-        else
-        {
-            entity = &it->second;
-        }
-        // Update entity.
-        return entity->update(update);
-    }
-
-    Entity& ProviderSegment::addEntity(const std::string& name)
-    {
-        return addEntity(Entity(name));
-    }
-
-    Entity& ProviderSegment::addEntity(const Entity& entity)
-    {
-        return addEntity(Entity(entity));
-    }
-
-    Entity& ProviderSegment::addEntity(Entity&& entity)
-    {
-        auto it = entities.emplace(entity.name(), std::move(entity)).first;
-        it->second.id().setProviderSegmentID(id());
-        return it->second;
-    }
-
-    void ProviderSegment::setMaxHistorySize(long maxSize)
-    {
-        MaxHistorySize::setMaxHistorySize(maxSize);
-        for (auto& [name, entity] : entities)
-        {
-            entity.setMaxHistorySize(maxSize);
-        }
-    }
-
-    std::string ProviderSegment::getLevelName() const
-    {
-        return "provider segment";
-    }
-
-    ProviderSegment::ContainerT& ProviderSegment::_underlyingContainer()
-    {
-        return entities;
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/ProviderSegment.h b/source/RobotAPI/libraries/armem/core/ProviderSegment.h
deleted file mode 100644
index cbb2080de0af157cb45f9d938edcde62315f7483..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/ProviderSegment.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#pragma once
-
-#include <map>
-#include <string>
-
-#include "Entity.h"
-#include "detail/TypedEntityContainer.h"
-#include "detail/MaxHistorySize.h"
-
-
-namespace armarx::armem
-{
-
-    /**
-     * @brief Data of a provider segment containing multiple entities.
-     */
-    class ProviderSegment :
-        public detail::TypedEntityContainer<Entity, ProviderSegment>
-        , public detail::MaxHistorySize
-
-    {
-        using Base = detail::TypedEntityContainer<Entity, ProviderSegment>;
-
-
-    public:
-
-        ProviderSegment();
-        ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-        ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-        ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-
-        ProviderSegment(const ProviderSegment& other);
-        ProviderSegment& operator=(const ProviderSegment& other);
-
-        ~ProviderSegment() override;
-
-
-        using Base::name;
-        const std::string& name() const override;
-
-
-        bool hasEntity(const std::string& name) const;
-
-        using Base::getEntity;
-        const Entity& getEntity(const MemoryID& id) const override;
-
-        Entity& getEntity(const std::string& name);
-        const Entity& getEntity(const std::string& name) const;
-
-
-
-        using Base::update;
-        /**
-         * @brief Updates an entity's history.
-         *
-         * Missing entity entries are added before updating.
-         */
-        virtual MemoryID update(const EntityUpdate& update) override;
-
-        /// Add an empty entity with the given name.
-        Entity& addEntity(const std::string& name);
-        /// Copy and insert an entity.
-        Entity& addEntity(const Entity& entity);
-        /// Move and insert an entity.
-        Entity& addEntity(Entity&& entity);
-
-
-        /**
-         * @brief Sets the maximum history size of entities in this segment.
-         * This affects all current entities as well as new ones.
-         * @see Entity::setMaxHistorySize()
-         */
-        void setMaxHistorySize(long maxSize) override;
-
-
-        bool equalsDeep(const ProviderSegment& other) const;
-
-
-        // MemoryItem interface
-    public:
-        std::string getLevelName() const override;
-
-        // MemoryContainer interface
-    protected:
-        ContainerT& _underlyingContainer() override;
-        void _copySelf(ProviderSegment& other) const override;
-        void _copyElements(ProviderSegment& other, bool withData) const override;
-
-
-    public:
-
-        /// The entities.
-        std::map<std::string, Entity> entities;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.cpp b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2958547f4f410b7027de8d263a77d90ba4621bf1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.cpp
@@ -0,0 +1 @@
+#include "CoreSegmentBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..609920d1e6e80054f4526fffe4e76eca2c4a43a5
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/CoreSegmentBase.h
@@ -0,0 +1,194 @@
+#pragma once
+
+#include <map>
+#include <string>
+
+#include "ProviderSegmentBase.h"
+#include "detail/MaxHistorySize.h"
+#include "detail/TypedEntityContainerBase.h"
+
+
+namespace armarx::armem::base
+{
+
+    /**
+     * @brief Data of a core segment containing multiple provider segments.
+     */
+    template <class _ProviderSegmentT, class _Derived>
+    class CoreSegmentBase :
+        virtual public detail::TypedEntityContainerBase<_ProviderSegmentT, typename _ProviderSegmentT::EntityT, _Derived>,
+        virtual public detail::MaxHistorySize
+    {
+        using Base = detail::TypedEntityContainerBase<_ProviderSegmentT, typename _ProviderSegmentT::EntityT, _Derived>;
+
+    public:
+
+        using typename Base::DerivedT;
+        using typename Base::ContainerT;
+
+        using ProviderSegmentT = _ProviderSegmentT;
+        using EntityT = typename ProviderSegmentT::EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+        using EntityInstanceT = typename EntitySnapshotT::EntityInstanceT;
+
+
+    public:
+
+        CoreSegmentBase& operator=(const CoreSegmentBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+        inline const std::string& name() const
+        {
+            return this->id().coreSegmentName;
+        }
+        inline std::string& name()
+        {
+            return const_cast<std::string&>(const_cast<const CoreSegmentBase*>(this)->name());
+        }
+
+
+        inline const std::map<std::string, ProviderSegmentT>& providerSegments() const
+        {
+            return _container;
+        }
+        inline std::map<std::string, ProviderSegmentT>& providerSegments()
+        {
+            return const_cast<std::map<std::string, ProviderSegmentT>&>(const_cast<const CoreSegmentBase*>(this)->providerSegments());
+        }
+
+
+        bool hasProviderSegment(const std::string& name) const
+        {
+            return _container.count(name) > 0;
+        }
+
+        ProviderSegmentT& getProviderSegment(const std::string& name)
+        {
+            return const_cast<ProviderSegmentT&>(const_cast<const CoreSegmentBase*>(this)->getProviderSegment(name));
+        }
+
+        const ProviderSegmentT& getProviderSegment(const std::string& name) const
+        {
+            auto it = this->_container.find(name);
+            if (it != _container.end())
+            {
+                return it->second;
+            }
+            else
+            {
+                throw armem::error::MissingEntry("provider segment", name, getLevelName(), this->getKeyString());
+            }
+        }
+
+        using Base::_checkContainerName;
+        const EntityT& getEntity(const MemoryID& id) const override
+        {
+            _checkContainerName(id.coreSegmentName, this->getKeyString());
+            return getProviderSegment(id.providerSegmentName).getEntity(id);
+        }
+
+        virtual MemoryID update(const EntityUpdate& update) override
+        {
+            _checkContainerName(update.entityID.coreSegmentName, this->name());
+
+            auto it = this->_container.find(update.entityID.providerSegmentName);
+            if (it != _container.end())
+            {
+                return it->second.update(update);
+            }
+            else
+            {
+                throw armem::error::MissingEntry("provider segment", update.entityID.providerSegmentName, getLevelName(), this->getKeyString());
+            }
+        }
+
+        /**
+         * @brief Add an empty provider segment with the given name and optional provider segment type.
+         * @param name The segment name.
+         * @param providerSegmentType The provider type. If nullptr, the core segment type is used.
+         * @return The added provider segment.
+         */
+        ProviderSegmentT& addProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr providerSegmentType = nullptr)
+        {
+            aron::typenavigator::ObjectNavigatorPtr type = providerSegmentType ? providerSegmentType : this->aronType();
+            return addProviderSegment(ProviderSegmentT(name, type));
+        }
+
+        /// Copy and insert a provider segment.
+        ProviderSegmentT& addProviderSegment(const ProviderSegmentT& providerSegment)
+        {
+            return addProviderSegment(ProviderSegment(providerSegment));
+        }
+
+        /// Move and insert a provider segment.
+        ProviderSegmentT& addProviderSegment(ProviderSegmentT&& providerSegment)
+        {
+            if (hasProviderSegment(providerSegment.name()))
+            {
+                throw armem::error::ContainerEntryAlreadyExists(
+                    providerSegment.getLevelName(), providerSegment.name(), getLevelName(), this->getKeyString());
+            }
+
+            auto it = _container.emplace(providerSegment.name(), std::move(providerSegment)).first;
+            it->second.id().setCoreSegmentID(this->id());
+            it->second.setMaxHistorySize(_maxHistorySize);
+            return it->second;
+        }
+
+
+        /**
+         * @brief Sets the maximum history size of entities in this segment.
+         * This affects all current entities as well as new ones.
+         * @see Entity::setMaxHistorySize()
+         */
+        void setMaxHistorySize(long maxSize) override
+        {
+            MaxHistorySize::setMaxHistorySize(maxSize);
+            for (auto& [name, seg] : _container)
+            {
+                seg.setMaxHistorySize(maxSize);
+            }
+        }
+
+        virtual bool equalsDeep(const CoreSegmentBase& other) const
+        {
+            //std::cout << "CoreSegment::equalsDeep" << std::endl;
+            if (this->size() != other.size())
+            {
+                return false;
+            }
+            for (const auto& [key, provider] : _container)
+            {
+                if (not other.hasProviderSegment(key))
+                {
+                    return false;
+                }
+                if (not provider.equalsDeep(other.getProviderSegment(key)))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        std::string getLevelName() const override
+        {
+            return "core segment";
+        }
+
+        std::string getKeyString() const override
+        {
+            return this->name();
+        }
+
+
+    protected:
+
+        using Base::_container;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp b/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0d2c67b63d566f7170bd9b31cfaf18785b85f87b
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.cpp
@@ -0,0 +1 @@
+#include "EntityBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.h b/source/RobotAPI/libraries/armem/core/base/EntityBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa884ee115624b437182f35df5744863f206ddb2
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.h
@@ -0,0 +1,331 @@
+#pragma once
+
+#include <map>
+#include <string>
+
+#include <SimoxUtility/algorithm/get_map_keys_values.h>
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "../../core/Time.h"
+#include "../../core/MemoryID.h"
+
+#include "EntitySnapshotBase.h"
+#include "detail/MaxHistorySize.h"
+#include "detail/MemoryContainerBase.h"
+
+
+namespace armarx::armem::base
+{
+
+    /**
+     * @brief An entity over a period of time.
+     *
+     * An entity should be a physical thing or abstract concept existing
+     * (and potentially evolving) over some time.
+     *
+     * Examples are:
+     * - objects (the green box)
+     * - agents (robot, human)
+     * - locations (frige, sink)
+     * - grasp affordances (general, or for a specific object)
+     * - images
+     * - point clouds
+     * - other sensory values
+     *
+     * At each point in time (`EntitySnapshot`), the entity can have a
+     * (potentially variable) number of instances (`EntityInstance`),
+     * each containing a single `AronData` object of a specific `AronType`.
+     */
+    template <class _EntitySnapshotT, class _Derived>
+    class EntityBase :
+        virtual public detail::MemoryContainerBase<std::map<Time, _EntitySnapshotT>, _Derived>,
+        virtual public detail::MaxHistorySize
+    {
+        using Base = detail::MemoryContainerBase<std::map<Time, _EntitySnapshotT>, _Derived>;
+
+    public:
+
+        using typename Base::DerivedT;
+        using typename Base::ContainerT;
+
+        using EntitySnapshotT = _EntitySnapshotT;
+        using EntityInstanceT = typename EntitySnapshotT::EntityInstanceT;
+
+
+    public:
+
+        EntityBase& operator=(const EntityBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+
+        virtual bool equalsDeep(const EntityBase& other) const
+        {
+            //std::cout << "Entity::equalsDeep" << std::endl;
+            if (this->size() != other.size())
+            {
+                return false;
+            }
+            for (const auto& [key, snapshot] : _container)
+            {
+                if (not other.hasSnapshot(key))
+                {
+                    return false;
+                }
+                if (not snapshot.equalsDeep(other.getSnapshot(key)))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+
+        inline const std::string& name() const
+        {
+            return this->id().entityName;
+        }
+        inline std::string& name()
+        {
+            return const_cast<std::string&>(const_cast<const EntityBase*>(this)->name());
+        }
+
+
+        inline const std::map<Time, EntitySnapshotT>& history() const
+        {
+            return _container;
+        }
+        inline std::map<Time, EntitySnapshotT>& history()
+        {
+            return const_cast<std::map<Time, EntitySnapshotT>&>(const_cast<const EntityBase*>(this)->history());
+        }
+
+
+        /**
+         * @brief Indicates whether a history entry for the given time exists.
+         */
+        bool hasSnapshot(Time time) const
+        {
+            return _container.count(time) > 0;
+        }
+
+        /**
+         * @brief Get the latest timestamp.
+         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
+         */
+        Time getLatestTimestamp() const
+        {
+            return getLatestItem().first;
+        }
+
+        /**
+         * @brief Get all timestamps in the history.
+         */
+        std::vector<Time> getTimestamps() const
+        {
+            return simox::alg::get_keys(_container);
+        }
+
+
+        /**
+         * @brief Get a snapshot.
+         * @param time The time.
+         * @return The snapshot, if it exists.
+         *
+         * @throws `armem::error::MissingEntry` If there is no such entry.
+         * @throws `armem::error::MissingData` If the entry has no data.
+         */
+        EntitySnapshotT& getSnapshot(Time time)
+        {
+            return const_cast<EntitySnapshotT&>(const_cast<const EntityBase*>(this)->getSnapshot(time));
+        }
+
+        const EntitySnapshotT& getSnapshot(Time time) const
+        {
+            auto it = _container.find(time);
+            if (it != _container.end())
+            {
+                return it->second;
+            }
+            else
+            {
+                throw error::MissingEntry("entity snapshot", toDateTimeMilliSeconds(time), getLevelName(), this->id().str());
+            }
+        }
+
+        EntitySnapshotT& getSnapshot(const MemoryID& id)
+        {
+            return const_cast<EntitySnapshotT&>(const_cast<const EntityBase*>(this)->getSnapshot(id));
+        }
+
+        const EntitySnapshotT& getSnapshot(const MemoryID& id) const
+        {
+            checkEntityName(id.entityName);
+            return getSnapshot(id.timestamp);
+        }
+
+        /**
+         * @brief Return the snapshot with the most recent timestamp.
+         * @return The latest snapshot.
+         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
+         * @throw `armem::error::MissingData` If the latest snapshot has no data.
+         */
+        EntitySnapshotT& getLatestSnapshot()
+        {
+            return const_cast<EntitySnapshotT&>(const_cast<const EntityBase*>(this)->getLatestSnapshot());
+        }
+
+        const EntitySnapshotT& getLatestSnapshot() const
+        {
+            return getLatestItem().second;
+        }
+
+
+        /**
+         * @brief Add the given update to this entity's history.
+         * @param update The update.
+         * @return The snapshot ID of the update.
+         */
+        virtual MemoryID update(const EntityUpdate& update)
+        {
+            checkEntityName(update.entityID.entityName);
+            this->id() = update.entityID;
+
+            EntitySnapshotT* snapshot;
+
+            auto it = _container.find(update.timeCreated);
+            if (it == _container.end())
+            {
+                // Insert into history.
+                snapshot = &addSnapshot(update.timeCreated);
+                truncateHistoryToSize();
+            }
+            else
+            {
+                snapshot = &it->second;
+            }
+            // Update entry.
+            snapshot->update(update);
+
+            return snapshot->id();
+        }
+
+        /**
+         * @brief Add a single snapshot with data.
+         * @param snapshot The snapshot.
+         * @return The stored snapshot.
+         */
+        EntitySnapshotT& addSnapshot(const EntitySnapshotT& snapshot)
+        {
+            return addSnapshot(EntitySnapshotT(snapshot));
+        }
+
+        EntitySnapshotT& addSnapshot(EntitySnapshotT&& snapshot)
+        {
+            auto it = _container.emplace(snapshot.time(), std::move(snapshot)).first;
+            it->second.id().setEntityID(this->id());
+            return it->second;
+        }
+
+        EntitySnapshotT& addSnapshot(const Time& timestamp)
+        {
+            return addSnapshot(EntitySnapshotT(timestamp));
+        }
+
+
+        /**
+         * @brief Sets the maximum history size.
+         *
+         * The current history is truncated if necessary.
+         */
+        void setMaxHistorySize(long maxSize) override
+        {
+            MaxHistorySize::setMaxHistorySize(maxSize);
+            truncateHistoryToSize();
+        }
+
+        std::string getKeyString() const override
+        {
+            return this->id().entityName;
+        }
+        std::string getLevelName() const override
+        {
+            return "entity";
+        }
+
+        virtual _Derived copy() const override
+        {
+            _Derived d;
+            this->_copySelf(d);
+            return d;
+        }
+
+        virtual _Derived copyEmpty() const override
+        {
+            _Derived d;
+            this->_copySelfEmpty(d);
+            return d;
+        }
+
+
+    protected:
+
+        virtual void _copySelf(DerivedT& other) const override
+        {
+            Base::_copySelf(other);
+        }
+
+        virtual void _copySelfEmpty(DerivedT& other) const override
+        {
+            Base::_copySelfEmpty(other);
+        }
+
+
+    private:
+
+        /// If maximum size is set, ensure `history`'s is not higher.
+        void truncateHistoryToSize()
+        {
+            if (_maxHistorySize >= 0)
+            {
+                while (_container.size() > size_t(_maxHistorySize))
+                {
+                    _container.erase(_container.begin());
+                }
+                ARMARX_CHECK_LESS_EQUAL(_container.size(), _maxHistorySize);
+            }
+        }
+
+        void checkEntityName(const std::string& name) const
+        {
+            if (name != this->name())
+            {
+                throw armem::error::ContainerNameMismatch(name, getLevelName(), getKeyString());
+            }
+        }
+
+        /**
+         * @brief Return the snapshot with the most recent timestamp.
+         * @return The latest snapshot.
+         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
+         */
+        const typename std::map<Time, EntitySnapshotT>::value_type& getLatestItem() const
+        {
+            if (_container.empty())
+            {
+                throw armem::error::EntityHistoryEmpty(name(), "when getting the latest snapshot.");
+            }
+            return *_container.rbegin();
+        }
+
+
+    protected:
+
+        using Base::_container;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.cpp b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6cfc7103728d5a81fecefe4ade6c96efef2814e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.cpp
@@ -0,0 +1 @@
+#include "EntityInstanceBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..d385ee26bb9a17f73535d15b68822c17c5bfd278
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/EntityInstanceBase.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "../../core/Time.h"
+
+#include "../Commit.h"
+#include "detail/MemoryItem.h"
+
+
+namespace armarx::armem::base
+{
+    /**
+     * @brief Data of a single entity instance.
+     */
+    template <class _DerivedT>
+    class EntityInstanceBase :
+        virtual public detail::MemoryItem
+    {
+        using Base = detail::MemoryItem;
+
+    public:
+
+        using DerivedT = _DerivedT;
+
+
+    public:
+
+        EntityInstanceBase& operator=(const EntityInstanceBase& other)
+        {
+            //other._copySelf(*this);
+            return *this;
+        }
+
+
+        inline int& index()
+        {
+            return id().instanceIndex;
+        }
+        inline int index() const
+        {
+            return id().instanceIndex;
+        }
+
+        // Copying
+        virtual DerivedT copy() const
+        {
+            DerivedT d;
+            this->_copySelf(d);
+            return d;
+        }
+
+        /**
+         * @brief Fill `*this` with the update's values.
+         * @param update The update.
+         * @param index The instances index.
+         */
+        virtual void update(const EntityUpdate& update, int index) = 0;
+
+
+        virtual bool equalsDeep(const DerivedT& other) const = 0;
+
+
+        std::string getLevelName() const override
+        {
+            return "entity instance";
+        }
+
+        std::string getKeyString() const override
+        {
+            return std::to_string(index());
+        }
+
+
+    protected:
+
+        virtual void _copySelf(DerivedT& other) const
+        {
+            Base::_copySelf(other);
+        }
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.cpp b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f7899f50d954f16b2d9c0a9569519529895eb20
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.cpp
@@ -0,0 +1 @@
+#include "EntitySnapshotBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..094608e2927991f5593922887ec17e11fe6ce440
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h
@@ -0,0 +1,195 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include "../MemoryID.h"
+#include "../Time.h"
+
+#include "EntityInstanceBase.h"
+#include "detail/MemoryContainerBase.h"
+
+
+namespace armarx::armem::base
+{
+    /**
+     * @brief Data of an entity at one point in time.
+     */
+    template <class _EntityInstanceT, class _Derived>
+    class EntitySnapshotBase :
+        virtual public detail::MemoryContainerBase<std::vector<_EntityInstanceT>, _Derived>
+    {
+        using Base = detail::MemoryContainerBase<std::vector<_EntityInstanceT>, _Derived>;
+
+    public:
+
+        using typename Base::DerivedT;
+        using typename Base::ContainerT;
+
+        using EntityInstanceT = _EntityInstanceT;
+
+
+    public:
+
+        EntitySnapshotBase& operator=(const EntitySnapshotBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+        virtual bool equalsDeep(const EntitySnapshotBase& other) const
+        {
+            //std::cout << "EntitySnapshot::equalsDeep" << std::endl;
+            if (this->size() != other.size())
+            {
+                return false;
+            }
+            int i = 0;
+            for (const auto& instance : _container)
+            {
+                if (not instance.equalsDeep(other.getInstance(i)))
+                {
+                    return false;
+                }
+                i++;
+            }
+            return true;
+        }
+
+        inline Time& time()
+        {
+            return this->id().timestamp;
+        }
+
+        inline const Time& time() const
+        {
+            return this->id().timestamp;
+        }
+
+
+        inline const std::vector<EntityInstanceT>& instances() const
+        {
+            return _container;
+        }
+        inline std::vector<EntityInstanceT>& instances()
+        {
+            return const_cast<std::vector<EntityInstanceT>&>(const_cast<const EntitySnapshotBase*>(this)->instances());
+        }
+
+
+        void update(const EntityUpdate& update, std::optional<MemoryID> parentID = std::nullopt)
+        {
+            if (parentID)
+            {
+                this->id() = *parentID;
+            }
+            time() = update.timeCreated;
+
+            _container.clear();
+            for (int i = 0; i < int(update.instancesData.size()); ++i)
+            {
+                EntityInstanceT& data = _container.emplace_back(i, this->id());
+                data.update(update, i);
+            }
+        }
+
+
+        bool hasInstance(int index) const
+        {
+            size_t si = size_t(index);
+            return index >= 0 && si < _container.size();
+        }
+
+        /**
+         * @brief Get the given instance.
+         * @param index The instance's index.
+         * @return The instance.
+         * @throw `armem::error::MissingEntry` If the given index is invalid.
+         */
+        EntityInstanceT& getInstance(int index)
+        {
+            return const_cast<EntityInstanceT&>(const_cast<const EntitySnapshotBase*>(this)->getInstance(index));
+        }
+
+        const EntityInstanceT& getInstance(int index) const
+        {
+            if (hasInstance(index))
+            {
+                return _container[static_cast<size_t>(index)];
+            }
+            else
+            {
+                throw armem::error::MissingEntry(EntityInstanceT().getLevelName(), std::to_string(index), getLevelName(), toDateTimeMilliSeconds(time()));
+            }
+        }
+
+        /**
+         * @brief Get the given instance.
+         * @param index The instance's index.
+         * @return The instance.
+         * @throw `armem::error::MissingEntry` If the given index is invalid.
+         * @throw `armem::error::InvalidMemoryID` If memory ID does not have an instance index.
+         */
+        EntityInstanceT& getInstance(const MemoryID& id)
+        {
+            return const_cast<EntityInstanceT&>(const_cast<const EntitySnapshotBase*>(this)->getInstance(id));
+        }
+
+        const EntityInstanceT& getInstance(const MemoryID& id) const
+        {
+            if (!id.hasInstanceIndex())
+            {
+                throw armem::error::InvalidMemoryID(id, "ID has no instance index.");
+            }
+            return getInstance(id.instanceIndex);
+        }
+
+
+        /**
+         * @brief Add a single instance with data.
+         * @param instance The instance.
+         * @return The stored instance.
+         * @throw `armem::error::InvalidArgument` If the given index is invalid. Must be equal to container.size() or -1 (meaning push_back)
+         */
+        EntityInstanceT& addInstance(const EntityInstanceT& instance)
+        {
+            return addInstance(EntityInstanceT(instance));
+        }
+
+        EntityInstanceT& addInstance(EntityInstanceT&& instance)
+        {
+            if (instance.index() > 0 && static_cast<size_t>(instance.index()) < _container.size())
+            {
+                throw error::InvalidArgument(std::to_string(instance.index()), "EntitySnapshot::addInstance",
+                                             "Cannot add an EntityInstance because its index already exists.");
+            }
+            if (instance.index() > 0 && static_cast<size_t>(instance.index()) > _container.size())
+            {
+                throw error::InvalidArgument(std::to_string(instance.index()), "EntitySnapshot::addInstance",
+                                             "Cannot add an EntityInstance because its index is too big.");
+            }
+
+            int new_index = _container.size();
+            auto& it = _container.emplace_back(std::move(instance));
+            it.index() = new_index;
+            return it;
+        }
+
+        std::string getKeyString() const override
+        {
+            return toDateTimeMilliSeconds(this->time());
+        }
+
+        std::string getLevelName() const override
+        {
+            return "entity snapshot";
+        }
+
+
+    protected:
+
+        using Base::_container;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.cpp b/source/RobotAPI/libraries/armem/core/base/MemoryBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..42ab1cf226c35715139a1e2fbcd5a9c69430e20a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.cpp
@@ -0,0 +1 @@
+#include "MemoryBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/MemoryBase.h b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d4c8020910ac140e61df0540136f2bcb0094e43
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/MemoryBase.h
@@ -0,0 +1,197 @@
+#pragma once
+
+#include <map>
+#include <string>
+
+#include <ArmarXCore/core/logging/Logging.h>
+
+#include "CoreSegmentBase.h"
+#include "detail/EntityContainerBase.h"
+
+
+namespace armarx::armem::base
+{
+
+    /**
+     * @brief Data of a memory consisting of multiple core segments.
+     */
+    template <class _CoreSegmentT, class _Derived>
+    class MemoryBase :
+        virtual public detail::EntityContainerBase<_CoreSegmentT, typename _CoreSegmentT::ProviderSegmentT::EntityT, _Derived>
+    {
+        using Base = detail::EntityContainerBase<_CoreSegmentT, typename _CoreSegmentT::ProviderSegmentT::EntityT, _Derived>;
+
+    public:
+
+        using typename Base::DerivedT;
+        using typename Base::ContainerT;
+
+        using CoreSegmentT = _CoreSegmentT;
+        using ProviderSegmentT = typename CoreSegmentT::ProviderSegmentT;
+        using EntityT = typename ProviderSegmentT::EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+        using EntityInstanceT = typename EntitySnapshotT::EntityInstanceT;
+
+
+    public:
+
+        MemoryBase& operator=(const MemoryBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+
+        inline const std::string& name() const
+        {
+            return this->id().memoryName;
+        }
+        inline std::string& name()
+        {
+            return const_cast<std::string&>(const_cast<const MemoryBase*>(this)->name());
+        }
+
+
+        inline const std::map<std::string, CoreSegmentT>& coreSegments() const
+        {
+            return _container;
+        }
+        inline std::map<std::string, CoreSegmentT>& coreSegments()
+        {
+            return const_cast<std::map<std::string, CoreSegmentT>&>(const_cast<const MemoryBase*>(this)->coreSegments());
+        }
+
+
+        bool hasCoreSegment(const std::string& name) const
+        {
+            return _container.count(name) > 0;
+        }
+
+        CoreSegmentT& getCoreSegment(const std::string& name)
+        {
+            return const_cast<CoreSegmentT&>(const_cast<const MemoryBase*>(this)->getCoreSegment(name));
+        }
+
+        const CoreSegmentT& getCoreSegment(const std::string& name) const
+        {
+            auto it = this->_container.find(name);
+            if (it != _container.end())
+            {
+                return it->second;
+            }
+            else
+            {
+                throw armem::error::MissingEntry(CoreSegmentT().getLevelName(), name, getLevelName(), this->name());
+            }
+        }
+
+        using Base::_checkContainerName;
+        const EntityT& getEntity(const MemoryID& id) const override
+        {
+            _checkContainerName(id.memoryName, this->name());
+            return getCoreSegment(id.coreSegmentName).getEntity(id);
+        }
+
+        /**
+         * @brief Add an empty core segment with the given name.
+         * @param name The core segment name.
+         * @param coreSegmentType The core segment type (optional).
+         * @return The added core segment.
+         */
+        CoreSegmentT& addCoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr coreSegmentType = nullptr)
+        {
+            return addCoreSegment(CoreSegmentT(name, coreSegmentType));
+        }
+        /// Copy and insert a core segment.
+        CoreSegmentT& addCoreSegment(const CoreSegmentT& coreSegment)
+        {
+            return addCoreSegment(CoreSegmentT(coreSegment));
+        }
+        /// Move and insert a core segment.
+        CoreSegmentT& addCoreSegment(CoreSegmentT&& coreSegment)
+        {
+            if (_container.count(coreSegment.name()) > 0)
+            {
+                throw armem::error::ContainerEntryAlreadyExists(coreSegment.getLevelName(), coreSegment.name(),
+                        this->getLevelName(), this->name());
+            }
+            auto it = _container.emplace(coreSegment.name(), std::move(coreSegment)).first;
+            it->second.id().setMemoryID(this->id());
+            return it->second;
+        }
+
+        /**
+         * @brief Add multiple core segments.
+         * @param The core segment names.
+         * @return The core segments. The contained pointers are never null.
+         */
+        std::vector<CoreSegmentT*> addCoreSegments(const std::vector<std::string>& names)
+        {
+            std::vector<CoreSegmentT*> segments;
+            for (const auto& name : names)
+            {
+                try
+                {
+                    segments.push_back(&addCoreSegment(name));
+                }
+                catch (const armem::error::ContainerEntryAlreadyExists& e)
+                {
+                    ARMARX_INFO << e.what() << "\nIgnoring multiple addition.";
+                }
+            }
+            return segments;
+        }
+
+        virtual MemoryID update(const EntityUpdate& update) override
+        {
+            _checkContainerName(update.entityID.memoryName, this->name());
+
+            auto it = _container.find(update.entityID.coreSegmentName);
+            if (it != _container.end())
+            {
+                return it->second.update(update);
+            }
+            else
+            {
+                throw armem::error::MissingEntry(CoreSegmentT().getLevelName(), update.entityID.coreSegmentName, getLevelName(), this->name());
+            }
+        }
+
+        virtual bool equalsDeep(const MemoryBase& other) const
+        {
+            //std::cout << "Memory::equalsDeep" << std::endl;
+            if (this->size() != other.size())
+            {
+                return false;
+            }
+            for (const auto& [key, core] : _container)
+            {
+                if (not other.hasCoreSegment(key))
+                {
+                    return false;
+                }
+                if (not core.equalsDeep(other.getCoreSegment(key)))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        std::string getLevelName() const override
+        {
+            return "memory";
+        }
+
+        std::string getKeyString() const override
+        {
+            return this->name();
+        }
+
+
+    protected:
+
+        using Base::_container;
+
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.cpp b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..92538a7b9c82e653c9138deb4b1ca766eb3b218f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.cpp
@@ -0,0 +1 @@
+#include "ProviderSegmentBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6f760bc6976c165399cfeeb57f7ebd19cf0a91c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/ProviderSegmentBase.h
@@ -0,0 +1,191 @@
+#pragma once
+
+#include <map>
+#include <string>
+
+#include "EntityBase.h"
+#include "detail/TypedEntityContainerBase.h"
+#include "detail/MaxHistorySize.h"
+
+
+namespace armarx::armem::base
+{
+
+    /**
+     * @brief Data of a provider segment containing multiple entities.
+     */
+    template <class _EntityT, class _Derived>
+    class ProviderSegmentBase :
+        virtual public detail::TypedEntityContainerBase<_EntityT, _EntityT, _Derived>,
+        virtual public detail::MaxHistorySize
+    {
+        using Base = detail::TypedEntityContainerBase<_EntityT, _EntityT, _Derived>;
+
+    public:
+
+        using typename Base::DerivedT;
+        using typename Base::ContainerT;
+
+        using EntityT = _EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+        using EntityInstanceT = typename EntitySnapshotT::EntityInstanceT;
+
+
+    public:
+
+        ProviderSegmentBase& operator=(const ProviderSegmentBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+
+        inline const std::string& name() const
+        {
+            return this->id().providerSegmentName;
+        }
+        inline std::string& name()
+        {
+            return const_cast<std::string&>(const_cast<const ProviderSegmentBase*>(this)->name());
+        }
+
+
+        inline const std::map<std::string, EntityT>& entities() const
+        {
+            return _container;
+        }
+        inline std::map<std::string, EntityT>& entities()
+        {
+            return const_cast<std::map<std::string, EntityT>&>(const_cast<const ProviderSegmentBase*>(this)->entities());
+        }
+
+
+        bool hasEntity(const std::string& name) const
+        {
+            return _container.count(name) > 0;
+        }
+
+        using Base::_checkContainerName;
+        const EntityT& getEntity(const MemoryID& id) const override
+        {
+            _checkContainerName(id.providerSegmentName, this->getKeyString());
+            return getEntity(id.entityName);
+        }
+
+        EntityT& getEntity(const std::string& name)
+        {
+            return const_cast<EntityT&>(const_cast<const ProviderSegmentBase*>(this)->getEntity(name));
+        }
+
+        const EntityT& getEntity(const std::string& name) const
+        {
+            auto it = this->_container.find(name);
+            if (it != _container.end())
+            {
+                return it->second;
+            }
+            else
+            {
+                throw error::MissingEntry("entity", name, getLevelName(), this->name());
+            }
+        }
+
+        /**
+         * @brief Updates an entity's history.
+         *
+         * Missing entity entries are added before updating.
+         */
+        virtual MemoryID update(const EntityUpdate& update) override
+        {
+            _checkContainerName(update.entityID.providerSegmentName, this->name());
+
+            EntityT* entity;
+            auto it = this->_container.find(update.entityID.providerSegmentName);
+            if (it == _container.end())
+            {
+                // Add entity entry.
+                entity = &addEntity(update.entityID.entityName);
+                entity->setMaxHistorySize(_maxHistorySize);
+            }
+            else
+            {
+                entity = &it->second;
+            }
+            // Update entity.
+            return entity->update(update);
+        }
+
+        /// Add an empty entity with the given name.
+        EntityT& addEntity(const std::string& name)
+        {
+            return addEntity(EntityT(name));
+        }
+        /// Copy and insert an entity.
+        EntityT& addEntity(const EntityT& entity)
+        {
+            return addEntity(EntityT(entity));
+        }
+        /// Move and insert an entity.
+        EntityT& addEntity(EntityT&& entity)
+        {
+            auto it = _container.emplace(entity.name(), std::move(entity)).first;
+            it->second.id().setProviderSegmentID(this->id());
+            return it->second;
+        }
+
+
+        /**
+         * @brief Sets the maximum history size of container in this segment.
+         * This affects all current container as well as new ones.
+         * @see Entity::setMaxHistorySize()
+         */
+        void setMaxHistorySize(long maxSize) override
+        {
+            MaxHistorySize::setMaxHistorySize(maxSize);
+            for (auto& [name, entity] : _container)
+            {
+                entity.setMaxHistorySize(maxSize);
+            }
+        }
+
+
+        virtual bool equalsDeep(const ProviderSegmentBase& other) const
+        {
+            //std::cout << "ProviderSegment::equalsDeep" << std::endl;
+            if (this->size() != other.size())
+            {
+                return false;
+            }
+            for (const auto& [key, value] : _container)
+            {
+                if (not other.hasEntity(key))
+                {
+                    return false;
+                }
+
+                if (not value.equalsDeep(other.getEntity(key)))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        std::string getLevelName() const override
+        {
+            return "provider segment";
+        }
+
+        std::string getKeyString() const override
+        {
+            return this->name();
+        }
+
+
+    protected:
+
+        using Base::_container;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/EntityContainerBase.cpp b/source/RobotAPI/libraries/armem/core/base/detail/EntityContainerBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05a23bc12fea34e175218498beca73e01b6f1b13
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/EntityContainerBase.cpp
@@ -0,0 +1 @@
+#include "EntityContainerBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/EntityContainerBase.h b/source/RobotAPI/libraries/armem/core/base/detail/EntityContainerBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba4f8cf9b7d3d975a63eff763c49f546dcae6ac7
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/EntityContainerBase.h
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "../../Commit.h"
+#include "../../error/ArMemError.h"
+
+#include "MemoryContainerBase.h"
+
+#include "../EntityBase.h"
+#include "../EntitySnapshotBase.h"
+
+
+namespace armarx::armem::base::detail
+{
+
+    /**
+     * @brief A container of entities at some point in the hierarchy.
+     *
+     * Can be updated by multiple entity updates.
+     */
+    template <class _ValueT, class _EntityT, class _Derived>
+    class EntityContainerBase :
+        virtual public MemoryContainerBase<std::map<std::string, _ValueT>, _Derived>
+    {
+        using Base = MemoryContainerBase<std::map<std::string, _ValueT>, _Derived>;
+
+    public:
+
+        using DerivedT = _Derived;
+        using ValueT = _ValueT;
+
+        using EntityT = _EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+        using EntityInstanceT = typename EntitySnapshotT::EntityInstanceT;
+
+
+    public:
+
+        EntityContainerBase& operator=(const EntityContainerBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+        /**
+         * @brief Store all updates in `commit`.
+         * @param commit The commit.
+         * @return The resulting memory IDs.
+         */
+        std::vector<MemoryID> update(const Commit& commit)
+        {
+            std::vector<MemoryID> ids;
+            for (const auto& update : commit.updates)
+            {
+                ids.push_back(this->update(update));
+            }
+            return ids;
+        }
+        /**
+         * @brief Store the given update.
+         * @param update The update.
+         * @return The resulting entity snapshot's ID.
+         */
+        virtual MemoryID update(const EntityUpdate& update) = 0;
+
+
+        /**
+         * @brief Retrieve an entity.
+         * @param id The entity ID.
+         * @return The entity.
+         * @throw An exception deriving from `armem::error::ArMemError` if the entity is missing.
+         */
+        virtual _EntityT& getEntity(const MemoryID& id)
+        {
+            return const_cast<_EntityT&>(const_cast<const EntityContainerBase*>(this)->getEntity(id));
+        }
+        virtual const _EntityT& getEntity(const MemoryID& id) const = 0;
+
+        /**
+         * @brief Retrieve an entity snapshot.
+         *
+         * Uses `getEntity()` to retrieve the respective entity.
+         *
+         * @param id The snapshot ID.
+         * @return The entity snapshot.
+         * @throw An exception deriving from `armem::error::ArMemError` if the snapshot is missing.
+         */
+        virtual EntitySnapshotT& getEntitySnapshot(const MemoryID& id)
+        {
+            return const_cast<EntitySnapshotT&>(const_cast<const EntityContainerBase*>(this)->getEntitySnapshot(id));
+        }
+
+        virtual const EntitySnapshotT& getEntitySnapshot(const MemoryID& id) const
+        {
+            const _EntityT& entity = getEntity(id);
+
+            if (id.hasTimestamp())
+            {
+                return entity.getSnapshot(id);
+            }
+            else
+            {
+                return entity.getLatestSnapshot();
+            }
+        }
+
+        virtual EntityInstanceT& getEntityInstance(const MemoryID& id)
+        {
+            return getEntitySnapshot(id).getInstance(id);
+        }
+
+        virtual const EntityInstanceT& getEntityInstance(const MemoryID& id) const
+        {
+            return getEntitySnapshot(id).getInstance(id);
+        }
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/detail/MaxHistorySize.cpp b/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp
similarity index 66%
rename from source/RobotAPI/libraries/armem/core/detail/MaxHistorySize.cpp
rename to source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp
index cdd34e3be26351bab89ad6b712026769057f8b0e..2c3b0554c65523826db0a7709599ed8e5140e0a1 100644
--- a/source/RobotAPI/libraries/armem/core/detail/MaxHistorySize.cpp
+++ b/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.cpp
@@ -1,7 +1,7 @@
 #include "MaxHistorySize.h"
 
 
-namespace armarx::armem::detail
+namespace armarx::armem::base::detail
 {
     MaxHistorySize::~MaxHistorySize()
     {
@@ -9,11 +9,11 @@ namespace armarx::armem::detail
 
     void MaxHistorySize::setMaxHistorySize(long maxSize)
     {
-        this->maxHistorySize = maxSize;
+        this->_maxHistorySize = maxSize;
     }
 
     long MaxHistorySize::getMaxHistorySize() const
     {
-        return maxHistorySize;
+        return _maxHistorySize;
     }
 }
diff --git a/source/RobotAPI/libraries/armem/core/detail/MaxHistorySize.h b/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h
similarity index 77%
rename from source/RobotAPI/libraries/armem/core/detail/MaxHistorySize.h
rename to source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h
index d96e732964103c93987708e2b1d5dbaf9377640a..69539df5c4063b8d27cd751b79ee82eb90ff5b7e 100644
--- a/source/RobotAPI/libraries/armem/core/detail/MaxHistorySize.h
+++ b/source/RobotAPI/libraries/armem/core/base/detail/MaxHistorySize.h
@@ -2,7 +2,7 @@
 
 
 
-namespace armarx::armem::detail
+namespace armarx::armem::base::detail
 {
     class MaxHistorySize
     {
@@ -23,9 +23,12 @@ namespace armarx::armem::detail
 
         /**
          * @brief Maximum size of entity histories.
+         *
+         * If negative, the size of `history` is not limited.
+         *
          * @see Entity::maxHstorySize
          */
-        long maxHistorySize = -1;
+        long _maxHistorySize = -1;
 
     };
 }
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.cpp b/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6a3706b50bfc3e0f0e96b1d5182a0c7fb9f3a3be
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.cpp
@@ -0,0 +1 @@
+#include "MemoryContainerBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h b/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..233985ebab9bee9353fd23f1b5e92ed570b0ccd2
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/MemoryContainerBase.h
@@ -0,0 +1,134 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/error/ArMemError.h>
+
+#include "MemoryItem.h"
+
+
+namespace armarx::armem::base::detail
+{
+
+    /**
+     * @class Provides default implmentations of `MemoryContainer`, as well as
+     * iterators (which requires a template).
+     */
+    template <class _ContainerT, class _DerivedT>
+    class MemoryContainerBase :
+        virtual public MemoryItem
+    {
+        using Base = MemoryItem;
+
+    public:
+
+        using DerivedT = _DerivedT;
+        using ContainerT = _ContainerT;
+
+
+    public:
+
+        MemoryContainerBase()
+        {}
+        MemoryContainerBase(const MemoryContainerBase<ContainerT, DerivedT>& o) :
+            MemoryItem(o.id),
+            _container(o._container)
+        {}
+
+
+        MemoryContainerBase& operator=(const MemoryContainerBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+
+        // Container methods
+        virtual bool empty() const
+        {
+            return _container.empty();
+        }
+        virtual std::size_t size() const
+        {
+            return _container.size();
+        }
+        virtual void clear()
+        {
+            return _container.clear();
+        }
+
+        typename ContainerT::const_iterator begin() const
+        {
+            return _container.begin();
+        }
+        typename ContainerT::iterator begin()
+        {
+            return _container.begin();
+        }
+        typename ContainerT::const_iterator end() const
+        {
+            return _container.end();
+        }
+        typename ContainerT::iterator end()
+        {
+            return _container.end();
+        }
+
+        const ContainerT& container() const
+        {
+            return _container;
+        }
+        ContainerT& container()
+        {
+            return _container;
+        }
+
+
+        // Copying
+        virtual DerivedT copy() const
+        {
+            DerivedT d;
+            this->_copySelf(d);
+            return d;
+        }
+
+        /// Make a copy not containing any elements.
+        virtual DerivedT copyEmpty() const
+        {
+            DerivedT d;
+            this->_copySelfEmpty(d);
+            return d;
+        }
+
+
+    protected:
+
+        /**
+         * @throw `armem::error::ContainerNameMismatch` if `gottenName` does not match `actualName`.
+         */
+        void _checkContainerName(const std::string& gottenName, const std::string& actualName,
+                                 bool emptyOk = true) const
+        {
+            if (!((emptyOk && gottenName.empty()) || gottenName == actualName))
+            {
+                throw armem::error::ContainerNameMismatch(gottenName, this->getLevelName(), actualName);
+            }
+        }
+
+        virtual void _copySelf(DerivedT& other) const
+        {
+            Base::_copySelf(other);
+            other.container() = _container;
+        }
+
+        virtual void _copySelfEmpty(DerivedT& other) const
+        {
+            Base::_copySelf(other);
+        }
+
+
+    protected:
+
+        ContainerT _container;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/MemoryItem.cpp b/source/RobotAPI/libraries/armem/core/base/detail/MemoryItem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..76cb4215475417ec15345067f5eab980bca96887
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/MemoryItem.cpp
@@ -0,0 +1,36 @@
+#include "MemoryItem.h"
+
+
+namespace armarx::armem::base::detail
+{
+
+    MemoryItem::MemoryItem()
+    {
+    }
+
+    MemoryItem::MemoryItem(const MemoryID& id) :
+        _id(id)
+    {
+    }
+
+    MemoryItem::MemoryItem(const MemoryItem& other) :
+        _id(other.id())
+    {}
+
+
+    MemoryItem::~MemoryItem()
+    {
+    }
+
+    MemoryItem& MemoryItem::operator=(const MemoryItem& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    void MemoryItem::_copySelf(MemoryItem& other) const
+    {
+        other.id() = id();
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/detail/MemoryItem.h b/source/RobotAPI/libraries/armem/core/base/detail/MemoryItem.h
similarity index 72%
rename from source/RobotAPI/libraries/armem/core/detail/MemoryItem.h
rename to source/RobotAPI/libraries/armem/core/base/detail/MemoryItem.h
index 534b631274eae77b597387fb8b8b3ea26dafe515..7867f645e39b9c6fca6ba7a92def993bb2f3fc40 100644
--- a/source/RobotAPI/libraries/armem/core/detail/MemoryItem.h
+++ b/source/RobotAPI/libraries/armem/core/base/detail/MemoryItem.h
@@ -2,10 +2,10 @@
 
 #include <string>
 
-#include "../../core/MemoryID.h"
+#include "../../MemoryID.h"
 
 
-namespace armarx::armem::detail
+namespace armarx::armem::base::detail
 {
 
     /**
@@ -17,10 +17,14 @@ namespace armarx::armem::detail
 
         MemoryItem();
         MemoryItem(const MemoryID& id);
+        MemoryItem(const MemoryItem& other);
 
         virtual ~MemoryItem();
 
 
+        MemoryItem& operator=(const MemoryItem& other);
+
+
         inline MemoryID& id()
         {
             return _id;
@@ -42,7 +46,12 @@ namespace armarx::armem::detail
 
     protected:
 
-        /// The memory ID.
+        /// Copy `*this` to `other`.
+        virtual void _copySelf(MemoryItem& other) const;
+
+
+    protected:
+
         MemoryID _id;
 
     };
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/TypedEntityContainerBase.cpp b/source/RobotAPI/libraries/armem/core/base/detail/TypedEntityContainerBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd42021d8a566ecca4a5e4662a560660d08b3630
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/TypedEntityContainerBase.cpp
@@ -0,0 +1 @@
+#include "TypedEntityContainerBase.h"
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/TypedEntityContainerBase.h b/source/RobotAPI/libraries/armem/core/base/detail/TypedEntityContainerBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..81f21797dfd4ca8972efd736ba8660b5e48a68f8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/TypedEntityContainerBase.h
@@ -0,0 +1,96 @@
+#pragma once
+
+#include "EntityContainerBase.h"
+
+#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
+
+namespace armarx::armem::base::detail
+{
+
+    /**
+     * @brief An entity container with a specific (Aron) type.
+     */
+    template <class _ValueT, class _EntityT, class _Derived>
+    class TypedEntityContainerBase :
+        virtual public EntityContainerBase<_ValueT, _EntityT, _Derived>
+    {
+        using Base = EntityContainerBase<_ValueT, _EntityT, _Derived>;
+
+
+    public:
+
+        using typename Base::DerivedT;
+        using typename Base::ValueT;
+        using typename Base::EntityT;
+        using typename Base::EntitySnapshotT;
+        using typename Base::EntityInstanceT;
+
+
+        TypedEntityContainerBase(aron::typenavigator::ObjectNavigatorPtr aronType = nullptr) :
+            _aronType(aronType)
+        {}
+
+        TypedEntityContainerBase(const TypedEntityContainerBase<_ValueT, _EntityT, DerivedT>& other) :
+            MemoryItem(other),
+            MemoryContainerBase<std::map<std::string, _ValueT>, DerivedT>(other),
+            _aronType(other._aronType)
+        {}
+
+        TypedEntityContainerBase(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr) :
+            MemoryItem(id),
+            _aronType(aronType)
+        {}
+
+
+        TypedEntityContainerBase& operator=(const TypedEntityContainerBase& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+
+        bool hasAronType() const
+        {
+            return _aronType != nullptr;
+        }
+        aron::typenavigator::ObjectNavigatorPtr& aronType()
+        {
+            return _aronType;
+        }
+        aron::typenavigator::ObjectNavigatorPtr aronType() const
+        {
+            return _aronType;
+        }
+
+        virtual DerivedT copyEmpty() const override
+        {
+            DerivedT d;
+            this->_copySelfEmpty(d);
+            return d;
+        }
+
+
+    protected:
+
+        virtual void _copySelf(DerivedT& other) const override
+        {
+            Base::_copySelf(other);
+            other._aronType = _aronType;
+        }
+
+        virtual void _copySelfEmpty(DerivedT& other) const override
+        {
+            Base::_copySelfEmpty(other);
+            other._aronType = _aronType;
+        }
+
+
+    protected:
+
+        /// The expected Aron type. May be nullptr, in which case no type information is available.
+        aron::typenavigator::ObjectNavigatorPtr _aronType;
+
+    };
+
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/detail/EntityContainer.cpp b/source/RobotAPI/libraries/armem/core/detail/EntityContainer.cpp
deleted file mode 100644
index 43ade411e4058b73fdfde97cd9ce7a28d3f09763..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/detail/EntityContainer.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "EntityContainer.h"
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-
-namespace armarx::armem::detail
-{
-
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/detail/EntityContainer.h b/source/RobotAPI/libraries/armem/core/detail/EntityContainer.h
deleted file mode 100644
index fd9b6a986decd0b7bb8b831f8ef431542745a387..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/detail/EntityContainer.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#pragma once
-
-#include "../Commit.h"
-#include "../Entity.h"
-#include "../EntitySnapshot.h"
-#include "../error/ArMemError.h"
-
-#include "MemoryContainer.h"
-
-
-namespace armarx::armem::detail
-{
-
-    /**
-     * @brief A container of entities at some point in the hierarchy.
-     *
-     * Can be updated by multiple entity updates.
-     */
-    template <class ValueT, class Derived>
-    class EntityContainer : public MemoryContainer<std::map<std::string, ValueT>, Derived>
-    {
-        using Base = MemoryContainer<std::map<std::string, ValueT>, Derived>;
-
-    public:
-
-        EntityContainer()
-        {}
-        EntityContainer(const MemoryID& id) :
-            MemoryContainer<std::map<std::string, ValueT>, Derived> (id)
-        {}
-
-        virtual ~EntityContainer() override
-        {}
-
-
-        virtual const std::string& name() const = 0;
-        virtual std::string& name()
-        {
-            return const_cast<std::string&>(const_cast<const EntityContainer*>(this)->name());
-        }
-
-
-        /**
-         * @brief Store all updates in `commit`.
-         * @param commit The commit.
-         * @return The resulting memory IDs.
-         */
-        std::vector<MemoryID> update(const Commit& commit)
-        {
-            std::vector<MemoryID> ids;
-            for (const auto& update : commit.updates)
-            {
-                ids.push_back(this->update(update));
-            }
-            return ids;
-        }
-        /**
-         * @brief Store the given update.
-         * @param update The update.
-         * @return The resulting entity snapshot's ID.
-         */
-        virtual MemoryID update(const EntityUpdate& update) = 0;
-
-
-        /**
-         * @brief Retrieve an entity.
-         * @param id The entity ID.
-         * @return The entity.
-         * @throw An exception deriving from `armem::error::ArMemError` if the entity is missing.
-         */
-        virtual Entity& getEntity(const MemoryID& id)
-        {
-            return const_cast<Entity&>(const_cast<const EntityContainer*>(this)->getEntity(id));
-        }
-        virtual const Entity& getEntity(const MemoryID& id) const = 0;
-
-        /**
-         * @brief Retrieve an entity snapshot.
-         *
-         * Uses `getEntity()` to retrieve the respective entity.
-         *
-         * @param id The snapshot ID.
-         * @return The entity snapshot.
-         * @throw An exception deriving from `armem::error::ArMemError` if the snapshot is missing.
-         */
-        virtual EntitySnapshot& getEntitySnapshot(const MemoryID& id)
-        {
-            return const_cast<EntitySnapshot&>(const_cast<const EntityContainer*>(this)->getEntitySnapshot(id));
-        }
-        virtual const EntitySnapshot& getEntitySnapshot(const MemoryID& id) const
-        {
-            const Entity& entity = getEntity(id);
-
-            if (id.hasTimestamp())
-            {
-                return entity.getSnapshot(id);
-            }
-            else
-            {
-                return entity.getLatestSnapshot();
-            }
-        }
-
-
-        virtual EntityInstance& getEntityInstance(const MemoryID& id)
-        {
-            return getEntitySnapshot(id).getInstance(id);
-        }
-        virtual const EntityInstance& getEntityInstance(const MemoryID& id) const
-        {
-            return getEntitySnapshot(id).getInstance(id);
-        }
-
-
-        // MemoryLevel interface
-    public:
-        /// Return `name`.
-        virtual std::string getKeyString() const override
-        {
-            return name();
-        }
-
-
-    protected:
-
-        /**
-         * @throw `armem::error::ContainerNameMismatch` if `gottenName` does not match `actualName`.
-         */
-        void _checkContainerName(const std::string& gottenName, const std::string& actualName,
-                                 bool emptyOk = true) const
-        {
-            if (!((emptyOk && gottenName.empty()) || gottenName == actualName))
-            {
-                throw armem::error::ContainerNameMismatch(gottenName, this->getLevelName(), actualName);
-            }
-        }
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/detail/MemoryContainer.cpp b/source/RobotAPI/libraries/armem/core/detail/MemoryContainer.cpp
deleted file mode 100644
index 9fd73048f1a7eef7c03e2500443b0353ffb20177..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/detail/MemoryContainer.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "MemoryContainer.h"
-
-
-namespace armarx::armem::detail
-{
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/detail/MemoryContainer.h b/source/RobotAPI/libraries/armem/core/detail/MemoryContainer.h
deleted file mode 100644
index 6b64db1dd03b00c856d62a6bc0d12139010c0ecf..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/detail/MemoryContainer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#pragma once
-
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include "../../error.h"
-
-#include "MemoryItem.h"
-
-
-namespace armarx::armem::detail
-{
-
-    /**
-     * @class Provides default implmentations of `MemoryContainer`, as well as
-     * iterators (which requires a template).
-     */
-    template <class _ContainerT, class _Derived>
-    class MemoryContainer : public MemoryItem
-    {
-    public:
-        using ContainerT = _ContainerT;
-        using Derived = _Derived;
-
-    public:
-
-        MemoryContainer()
-        {}
-        MemoryContainer(const MemoryID& id) : MemoryItem(id)
-        {}
-
-        virtual ~MemoryContainer()
-        {}
-
-
-        // Container methods
-
-        virtual bool empty() const
-        {
-            return _underlyingContainer().empty();
-        }
-        virtual std::size_t size() const
-        {
-            return _underlyingContainer().size();
-        }
-        virtual void clear()
-        {
-            return _underlyingContainer().clear();
-        }
-
-        typename ContainerT::const_iterator begin() const
-        {
-            return _underlyingContainer().begin();
-        }
-        typename ContainerT::iterator begin()
-        {
-            return _underlyingContainer().begin();
-        }
-        typename ContainerT::const_iterator end() const
-        {
-            return _underlyingContainer().end();
-        }
-        typename ContainerT::iterator end()
-        {
-            return _underlyingContainer().end();
-        }
-
-
-        // Copying
-
-        virtual Derived copy(bool withData = true) const
-        {
-            auto cast = dynamic_cast<const Derived*>(this);
-            ARMARX_CHECK_NOT_NULL(cast);
-
-            Derived other;
-            this->_copySelf(other);
-            this->_copyElements(other, withData);
-            return other;
-        }
-
-        /// Make a copy not containing any elements.
-        virtual Derived copyEmpty() const
-        {
-            auto cast = dynamic_cast<const Derived*>(this);
-            ARMARX_CHECK_NOT_NULL(cast);
-
-            Derived other;
-            this->_copySelf(other);
-            return other;
-        }
-
-
-    protected:
-
-
-        virtual ContainerT& _underlyingContainer() = 0;
-        virtual const ContainerT& _underlyingContainer() const
-        {
-            return const_cast<const ContainerT&>(const_cast<MemoryContainer*>(this)->_underlyingContainer());
-        }
-
-        virtual void _copySelf(Derived& other) const
-        {
-            other.id() = this->id();
-            (void) other;
-        }
-        virtual void _copyElements(Derived& other, bool withData) const
-        {
-            (void) other, (void) withData;
-        }
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/detail/MemoryItem.cpp b/source/RobotAPI/libraries/armem/core/detail/MemoryItem.cpp
deleted file mode 100644
index 32640023ba26f2c3bdaba4f4f49a4925068a7db1..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/detail/MemoryItem.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "MemoryItem.h"
-
-
-namespace armarx::armem::detail
-{
-
-    MemoryItem::MemoryItem()
-    {
-    }
-
-    MemoryItem::MemoryItem(const MemoryID& id) : _id(id)
-    {
-    }
-
-    MemoryItem::~MemoryItem()
-    {
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/detail/TypedEntityContainer.h b/source/RobotAPI/libraries/armem/core/detail/TypedEntityContainer.h
deleted file mode 100644
index f932b72297b89eb9248bd05751ef9a3b0085324f..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/detail/TypedEntityContainer.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-#include "EntityContainer.h"
-
-#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
-
-namespace armarx::armem::detail
-{
-
-    /**
-     * @brief An entity container with a specific (Aron) type.
-     */
-    template <class _ValueT, class Derived>
-    class TypedEntityContainer : public EntityContainer<_ValueT, Derived>
-    {
-        using ValueT = _ValueT;
-        // using Base = EntityContainer<ValueT, Derived>;
-
-    public:
-
-        TypedEntityContainer(aron::typenavigator::ObjectNavigatorPtr aronType = nullptr) : _aronType(aronType)
-        {}
-        TypedEntityContainer(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr) :
-            EntityContainer<ValueT, Derived>(id), _aronType(aronType)
-        {}
-
-        virtual ~TypedEntityContainer() override
-        {}
-
-
-        bool hasAronType() const
-        {
-            return _aronType != nullptr;
-        }
-        aron::typenavigator::ObjectNavigatorPtr& aronType()
-        {
-            return _aronType;
-        }
-        aron::typenavigator::ObjectNavigatorPtr aronType() const
-        {
-            return _aronType;
-        }
-
-
-
-        // MemoryContainer interface
-    protected:
-        virtual void _copySelf(Derived& other) const override
-        {
-            EntityContainer<ValueT, Derived>::_copySelf(other);
-            other._aronType = this->_aronType;
-        }
-
-
-    private:
-
-        /// The expected Aron type. May be nullptr, in which case no type information is available.
-        aron::typenavigator::ObjectNavigatorPtr _aronType;
-
-    };
-
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bc3104b74ea8c1f396dc6ce0aee5742cdafd7e94
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp
@@ -0,0 +1,128 @@
+#include "CoreSegment.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+    CoreSegment::CoreSegment()
+    {
+    }
+
+    CoreSegment::CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withCoreSegmentName(name)),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(MemoryID().withCoreSegmentName(name), aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withCoreSegmentName(name)),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(parentID.withCoreSegmentName(name), aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(id),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(id, aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const CoreSegment& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, ProviderSegment>, CoreSegment>(other),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(other)
+    {
+    }
+
+    CoreSegment& CoreSegment::operator=(const CoreSegment& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    std::filesystem::path CoreSegment::_fullPath() const
+    {
+        if (path)
+        {
+            return _fullPath(*path);
+        }
+        return std::filesystem::path();
+    }
+
+    std::filesystem::path CoreSegment::_fullPath(const std::filesystem::path& path) const
+    {
+        return path / id().memoryName / id().coreSegmentName;
+    }
+
+    wm::CoreSegment CoreSegment::convert() const
+    {
+        wm::CoreSegment m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addProviderSegment(s.convert(_aronType));
+        }
+        return m;
+    }
+
+    void CoreSegment::reload(const std::shared_ptr<std::filesystem::path>& p_ptr)
+    {
+        if (!p_ptr)
+        {
+            ARMARX_WARNING << "The entered is NULL.";
+        }
+        std::filesystem::path p = _fullPath(*p_ptr);
+        if (std::filesystem::is_regular_file(p))
+        {
+            ARMARX_ERROR << "The entered path is leading to a file! Abort due to error.";
+        }
+
+        _container.clear();
+        path = p_ptr;
+
+        if (!std::filesystem::exists(p))
+        {
+            ARMARX_INFO << "The entered path does not exist. Assuming an empty container.";
+        }
+        else
+        {
+            for (const auto& d : std::filesystem::directory_iterator(p))
+            {
+                if (d.is_directory())
+                {
+                    std::string k = d.path().filename();
+                    auto wms = _container.emplace(std::make_pair(k, id().withProviderSegmentName(k)));
+                    wms.first->second.reload(p_ptr);
+                }
+
+                if (d.is_regular_file())
+                {
+                    readAronType(d.path());
+                }
+            }
+        }
+    }
+
+    void CoreSegment::append(const wm::CoreSegment& m)
+    {
+        std::filesystem::create_directories(_fullPath());
+        writeAronType(_fullPath());
+
+        for (const auto& [k, s] : m)
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.append(s);
+            }
+            else
+            {
+                std::filesystem::create_directory(_fullPath() / k);
+                auto wms = _container.emplace(std::make_pair(k, id().withProviderSegmentName(k)));
+                wms.first->second.path = path;
+                wms.first->second.append(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.h b/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.h
new file mode 100644
index 0000000000000000000000000000000000000000..f26c01c67ed90ab5467b32e4ed755b3ddee2e1cf
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <filesystem>
+
+#include "../base/CoreSegmentBase.h"
+#include "detail/TypedEntityContainer.h"
+
+#include "ProviderSegment.h"
+
+#include "../workingmemory/CoreSegment.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+    /**
+     * @brief Data of a core segment containing multiple provider segments.
+     */
+    class CoreSegment :
+        virtual public base::CoreSegmentBase<ProviderSegment, CoreSegment>,
+        virtual public detail::TypedEntityContainer<ProviderSegment, CoreSegment>
+    {
+        using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>;
+
+    public:
+        CoreSegment();
+        CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+
+        CoreSegment(const CoreSegment& other);
+        CoreSegment& operator=(const CoreSegment& other);
+
+        // Conversion
+        wm::CoreSegment convert() const;
+
+        // Filesystem connection
+        void reload(const std::shared_ptr<std::filesystem::path>&);
+        void append(const wm::CoreSegment&);
+
+    private:
+        std::filesystem::path _fullPath() const;
+        std::filesystem::path _fullPath(const std::filesystem::path&) const;
+
+    public:
+        std::shared_ptr<std::filesystem::path> path;
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77ff0d95f4cf7ac7b81ac933d478ce47ae1010a6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp
@@ -0,0 +1,108 @@
+#include "Entity.h"
+
+namespace armarx::armem::d_ltm
+{
+
+    Entity::Entity()
+    {
+    }
+
+    Entity::Entity(const std::string& name, const MemoryID& parentID) :
+        base::detail::MemoryItem(parentID.withEntityName(name))
+    {
+    }
+
+    Entity::Entity(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    Entity::Entity(const Entity& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<Time, EntitySnapshot>, Entity>(other)
+    {
+    }
+
+    Entity& Entity::operator=(const Entity& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    std::filesystem::path Entity::_fullPath() const
+    {
+        if (path)
+        {
+            return _fullPath(*path);
+        }
+        return std::filesystem::path();
+    }
+
+    std::filesystem::path Entity::_fullPath(const std::filesystem::path& path) const
+    {
+        return path / id().memoryName / id().coreSegmentName / id().providerSegmentName / id().entityName;
+    }
+
+    wm::Entity Entity::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const
+    {
+        wm::Entity m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addSnapshot(s.convert(expectedStructure));
+        }
+        return m;
+    }
+
+    void Entity::reload(const std::shared_ptr<std::filesystem::path>& p_ptr)
+    {
+        if (!p_ptr)
+        {
+            ARMARX_WARNING << "The entered is NULL.";
+        }
+        std::filesystem::path p = _fullPath(*p_ptr);
+        if (std::filesystem::is_regular_file(p))
+        {
+            ARMARX_ERROR << "The entered path is leading to a file! Abort due to error.";
+        }
+
+        _container.clear();
+        path = p_ptr;
+
+        if (!std::filesystem::exists(p))
+        {
+            ARMARX_INFO << "The entered path does not exist. Assuming an empty container.";
+        }
+        else
+        {
+            for (const auto& d : std::filesystem::directory_iterator(p))
+            {
+                if (d.is_directory())
+                {
+                    std::string k = d.path().filename();
+                    armem::Time t = armem::Time::microSeconds(std::stol(k));
+                    auto wms = _container.emplace(std::make_pair(t, id().withTimestamp(t)));
+                    wms.first->second.reload(p_ptr);
+                }
+            }
+        }
+    }
+
+    void Entity::append(const wm::Entity& m)
+    {
+        std::filesystem::create_directories(_fullPath());
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.setTo(s);
+            }
+            else
+            {
+                std::filesystem::create_directory(_fullPath() / std::to_string(k.toMicroSeconds()));
+                auto wms = _container.emplace(std::make_pair(k, id().withTimestamp(k)));
+                wms.first->second.path = path;
+                wms.first->second.setTo(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Entity.h b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.h
new file mode 100644
index 0000000000000000000000000000000000000000..756f3eb69dd3499333532187ee207fd4cec4e102
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <filesystem>
+
+#include "../base/EntityBase.h"
+
+#include "EntitySnapshot.h"
+
+#include "../workingmemory/Entity.h"
+
+
+namespace armarx::armem::d_ltm
+{
+    /**
+     * @brief An entity over a period of time.
+     *
+     * An entity should be a physical thing or abstract concept existing
+     * (and potentially evolving) over some time.
+     *
+     * Examples are:
+     * - objects (the green box)
+     * - agents (robot, human)
+     * - locations (frige, sink)
+     * - grasp affordances (general, or for a specific object)
+     * - images
+     * - point clouds
+     * - other sensory values
+     *
+     * At each point in time (`EntitySnapshot`), the entity can have a
+     * (potentially variable) number of instances (`EntityInstance`),
+     * each containing a single `AronData` object of a specific `AronType`.
+     */
+    class Entity :
+        virtual public base::EntityBase<EntitySnapshot, Entity>
+    {
+        using Base = base::EntityBase<EntitySnapshot, Entity>;
+
+    public:
+        Entity();
+        Entity(const std::string& name, const MemoryID& parentID = {});
+        Entity(const MemoryID& id);
+
+        /// Copy the history from `other` to this.
+        Entity(const Entity& other);
+        /// Copy the history from `other` to this.
+        Entity& operator=(const Entity& other);
+
+        // Conversion
+        wm::Entity convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const;
+
+        // Filesystem connection
+        void reload(const std::shared_ptr<std::filesystem::path>&);
+        void append(const wm::Entity&);
+
+    private:
+        std::filesystem::path _fullPath() const;
+        std::filesystem::path _fullPath(const std::filesystem::path&) const;
+
+    public:
+        std::shared_ptr<std::filesystem::path> path;
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..28bcf696369fedfa9bd39ab9cce3f694033211d6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp
@@ -0,0 +1,201 @@
+#include "EntityInstance.h"
+
+#include <iostream>
+#include <fstream>
+
+#include "../../core/error.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h>
+#include <RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h>
+#include <RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h>
+#include <RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h>
+
+namespace armarx::armem::d_ltm
+{
+    EntityInstance::EntityInstance()
+    {
+    }
+
+    EntityInstance::EntityInstance(const EntityInstance& other) :
+        base::detail::MemoryItem(other.id())
+    {
+    }
+
+    EntityInstance::EntityInstance(int index, const MemoryID& parentID) :
+        EntityInstance(parentID.withInstanceIndex(index))
+    {
+    }
+
+    EntityInstance::EntityInstance(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    EntityInstance& EntityInstance::operator=(const EntityInstance& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    bool EntityInstance::equalsDeep(const EntityInstance& other) const
+    {
+        return id() == other.id();
+    }
+
+    void EntityInstance::update(const EntityUpdate& update, int index)
+    {
+        ARMARX_CHECK_FITS_SIZE(index, update.instancesData.size());
+
+        this->index() = index;
+    }
+
+    EntityInstance EntityInstance::copy() const
+    {
+        EntityInstance d;
+        this->_copySelf(d);
+        return d;
+    }
+
+    void EntityInstance::_copySelf(EntityInstance& other) const
+    {
+        EntityInstanceBase<EntityInstance>::_copySelf(other);
+    }
+
+    std::filesystem::path EntityInstance::_fullPath() const
+    {
+        if (path)
+        {
+            return _fullPath(*path);
+        }
+        return std::filesystem::path();
+    }
+
+    std::filesystem::path EntityInstance::_fullPath(const std::filesystem::path& path) const
+    {
+        return path / id().memoryName / id().coreSegmentName / id().providerSegmentName / id().entityName / std::to_string(id().timestamp.toMicroSeconds()) / std::to_string(id().instanceIndex);
+    }
+
+    wm::EntityInstance EntityInstance::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const
+    {
+        std::filesystem::path p = _fullPath();
+        std::filesystem::path d = p / (std::string(DATA_FILENAME) + ".json");
+
+        if (std::filesystem::is_regular_file(d))
+        {
+            std::ifstream ifs(d);
+            std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
+            aron::dataIO::reader::NlohmannJSONReader dataReader(file_content);
+            aron::dataIO::writer::NavigatorWriter navWriter;
+
+            aron::dataIO::Converter::ReadAndConvert(dataReader, navWriter, expectedStructure);
+
+            aron::datanavigator::DictNavigatorPtr aron = aron::datanavigator::DictNavigator::DynamicCastAndCheck(navWriter.getResult());
+            return unwrapData(aron);
+        }
+        else
+        {
+            throw error::ArMemError("An diskMemory EntityInstance is not leading to a regular file.");
+        }
+    }
+
+    void EntityInstance::reload(const std::shared_ptr<std::filesystem::path>& p_ptr)
+    {
+        if (!p_ptr)
+        {
+            ARMARX_WARNING << "The entered is NULL.";
+        }
+        std::filesystem::path p = _fullPath(*p_ptr);
+        if (!std::filesystem::is_directory(p))
+        {
+            ARMARX_ERROR << "The entered path is not leading to a file! This is an error since if the folder for an EntityInstance exists there must be a data file in it (containing at least the metadata).";
+        }
+        else
+        {
+            path = p_ptr;
+        }
+    }
+
+    void EntityInstance::setTo(const wm::EntityInstance& m)
+    {
+        std::filesystem::path p = _fullPath();
+        std::filesystem::create_directories(p);
+
+        std::filesystem::path d = p / (std::string(DATA_FILENAME) + ".json");
+
+        if (std::filesystem::is_regular_file(d))
+        {
+            std::filesystem::remove(d);
+        }
+
+        std::ofstream ofs;
+        ofs.open(d);
+
+        aron::datanavigator::DictNavigatorPtr aron = wrapData(m);
+        aron::dataIO::writer::NlohmannJSONWriter dataWriter;
+        aron::dataIO::Visitor::VisitAndSetup(dataWriter, aron);
+        std::string new_file_full_content = dataWriter.getResult().dump(2);
+
+        ofs << new_file_full_content;
+        ofs.close();
+    }
+
+
+    wm::EntityInstance EntityInstance::unwrapData(const aron::datanavigator::DictNavigatorPtr& dataWrapped) const
+    {
+        wm::EntityInstance e(id());
+        wm::EntityInstanceMetadata& metadata = e.metadata();
+
+        if (dataWrapped->hasElement(DATA_WRAPPER_DATA_FIELD))
+        {
+            aron::datanavigator::DictNavigatorPtr data = aron::datanavigator::DictNavigator::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_DATA_FIELD));
+            e.setData(data);
+        }
+
+        auto timeCreated = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_TIME_CREATED_FIELD));
+        metadata.timeCreated = Time::microSeconds(timeCreated->toAronLongPtr()->value);
+
+        auto timeSent = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_TIME_SENT_FIELD));
+        metadata.timeSent = Time::microSeconds(timeSent->toAronLongPtr()->value);
+
+        auto timeArrived = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_TIME_ARRIVED_FIELD));
+        metadata.timeArrived = Time::microSeconds(timeArrived->toAronLongPtr()->value);
+
+        auto confidence = aron::datanavigator::DoubleNavigator::DynamicCastAndCheck(dataWrapped->getElement(DATA_WRAPPER_CONFIDENCE_FIELD));
+        metadata.confidence = static_cast<float>(confidence->toAronDoublePtr()->value);
+
+        return e;
+    }
+
+    aron::datanavigator::DictNavigatorPtr EntityInstance::wrapData(const wm::EntityInstance& e) const
+    {
+        auto dataWrapped = std::make_shared<aron::datanavigator::DictNavigator>();
+        if (e.data())
+        {
+            dataWrapped->addElement(DATA_WRAPPER_DATA_FIELD, e.data());
+        }
+
+        auto timeWrapped = std::make_shared<aron::datanavigator::LongNavigator>();
+        timeWrapped->setValue(Time::now().toMicroSeconds());
+        dataWrapped->addElement(DATA_WRAPPER_TIME_STORED_FIELD, timeWrapped);
+
+        const wm::EntityInstanceMetadata& metadata = e.metadata();
+        auto timeCreated = std::make_shared<aron::datanavigator::LongNavigator>();
+        timeCreated->setValue(metadata.timeCreated.toMicroSeconds());
+        dataWrapped->addElement(DATA_WRAPPER_TIME_CREATED_FIELD, timeCreated);
+
+        auto timeSent = std::make_shared<aron::datanavigator::LongNavigator>();
+        timeSent->setValue(metadata.timeSent.toMicroSeconds());
+        dataWrapped->addElement(DATA_WRAPPER_TIME_SENT_FIELD, timeSent);
+
+        auto timeArrived = std::make_shared<aron::datanavigator::LongNavigator>();
+        timeArrived->setValue(metadata.timeArrived.toMicroSeconds());
+        dataWrapped->addElement(DATA_WRAPPER_TIME_ARRIVED_FIELD, timeArrived);
+
+        auto confidence = std::make_shared<aron::datanavigator::DoubleNavigator>();
+        confidence->setValue(static_cast<double>(metadata.confidence));
+        dataWrapped->addElement(DATA_WRAPPER_CONFIDENCE_FIELD, confidence);
+
+        return dataWrapped;
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.h b/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e7a0fed18959090f05196ba32565f507e19faf4
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.h
@@ -0,0 +1,67 @@
+#pragma once
+
+#include <filesystem>
+
+#include "../base/EntityInstanceBase.h"
+
+#include "../workingmemory/EntityInstance.h"
+
+namespace armarx::armem::d_ltm
+{
+    /**
+     * @brief Data of a single entity instance.
+     */
+    class EntityInstance :
+        virtual public base::EntityInstanceBase<EntityInstance>
+    {
+        using Base = base::EntityInstanceBase<EntityInstance>;
+
+    public:
+        EntityInstance();
+        EntityInstance(const EntityInstance&);
+        EntityInstance(int index, const MemoryID& parentID = {});
+        EntityInstance(const MemoryID& id);
+
+        EntityInstance& operator=(const EntityInstance& other);
+
+        /**
+         * @brief Fill `*this` with the update's values.
+         * @param update The update.
+         * @param index The instances index.
+         */
+        virtual void update(const EntityUpdate& update, int index) override;
+
+        virtual bool equalsDeep(const EntityInstance& other) const override;
+
+        virtual EntityInstance copy() const override;
+
+        // Conversion
+        wm::EntityInstance convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const;
+
+        // Filesystem connection
+        void reload(const std::shared_ptr<std::filesystem::path>&);
+        void setTo(const wm::EntityInstance&);
+
+    protected:
+        virtual void _copySelf(EntityInstance& other) const override;
+
+    private:
+        std::filesystem::path _fullPath() const;
+        std::filesystem::path _fullPath(const std::filesystem::path&) const;
+
+        wm::EntityInstance unwrapData(const aron::datanavigator::DictNavigatorPtr&) const;
+        aron::datanavigator::DictNavigatorPtr wrapData(const wm::EntityInstance&) const;
+
+    public:
+        std::shared_ptr<std::filesystem::path> path;
+
+    private:
+        static const constexpr char* DATA_FILENAME = "data";
+        static constexpr const char* DATA_WRAPPER_DATA_FIELD            = "__ARON_DATA";
+        static constexpr const char* DATA_WRAPPER_TIME_STORED_FIELD     = "__WRITER_METADATA__TIME_STORED";
+        static constexpr const char* DATA_WRAPPER_TIME_CREATED_FIELD    = "__ENTITY_METADATA__TIME_CREATED";
+        static constexpr const char* DATA_WRAPPER_TIME_SENT_FIELD       = "__ENTITY_METADATA__TIME_SENT";
+        static constexpr const char* DATA_WRAPPER_TIME_ARRIVED_FIELD    = "__ENTITY_METADATA__TIME_ARRIVED";
+        static constexpr const char* DATA_WRAPPER_CONFIDENCE_FIELD      = "__ENTITY_METADATA__CONFIDENCE";
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..98654d7a854b4247d515887ba3e9e4d5996b46d8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp
@@ -0,0 +1,114 @@
+#include "EntitySnapshot.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+
+    EntitySnapshot::EntitySnapshot()
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(Time time, const MemoryID& parentID) :
+        EntitySnapshot(parentID.withTimestamp(time))
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(const EntitySnapshot& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::vector<EntityInstance>, EntitySnapshot>(other)
+    {
+    }
+
+    EntitySnapshot& EntitySnapshot::operator=(const EntitySnapshot& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    std::filesystem::path EntitySnapshot::_fullPath() const
+    {
+        if (path)
+        {
+            return _fullPath(*path);
+        }
+        return std::filesystem::path();
+    }
+
+    std::filesystem::path EntitySnapshot::_fullPath(const std::filesystem::path& path) const
+    {
+        return path / id().memoryName / id().coreSegmentName / id().providerSegmentName
+               / id().entityName
+               / std::to_string(id().timestamp.toMicroSeconds());
+    }
+
+    wm::EntitySnapshot EntitySnapshot::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const
+    {
+        wm::EntitySnapshot m;
+        for (const auto& s : _container)
+        {
+            m.addInstance(s.convert(expectedStructure));
+        }
+        return m;
+    }
+
+    void EntitySnapshot::reload(const std::shared_ptr<std::filesystem::path>& p_ptr)
+    {
+        if (!p_ptr)
+        {
+            ARMARX_WARNING << "The entered is NULL.";
+        }
+        std::filesystem::path p = _fullPath(*p_ptr);
+        if (!std::filesystem::is_directory(p))
+        {
+            ARMARX_ERROR << "The entered path is not leading to a directory! Every EntitySnapshot must at least contain one EntityInstance.";
+        }
+        else
+        {
+            _container.clear();
+            path = p_ptr;
+
+            // todo
+            for (int i = 0; i < 1000; ++i)
+            {
+                std::filesystem::path d = p / std::to_string(i);
+                if (std::filesystem::is_directory(d))
+                {
+                    auto wms = _container.emplace_back(id().withInstanceIndex(i));
+                    wms.reload(p_ptr);
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+    void EntitySnapshot::setTo(const wm::EntitySnapshot& m)
+    {
+        std::filesystem::create_directories(_fullPath());
+
+        // We remove the contente here and reset it with new values
+        _container.clear();
+
+        int i = 0;
+        for (const auto& s : m.instances())
+        {
+            std::filesystem::create_directory(_fullPath() / std::to_string(i));
+
+            auto wms = _container.emplace_back(id().withInstanceIndex(i++));
+            wms.path = path;
+            wms.setTo(s);
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c3cf02ff6cb452797ac0c0433bbef294d92a29f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <filesystem>
+
+#include "../base/EntitySnapshotBase.h"
+
+#include "EntityInstance.h"
+
+#include "../workingmemory/EntitySnapshot.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+    /**
+     * @brief Data of an entity at one point in time.
+     */
+    class EntitySnapshot :
+        virtual public base::EntitySnapshotBase<EntityInstance, EntitySnapshot>
+    {
+        using Base = base::EntitySnapshotBase<EntityInstance, EntitySnapshot>;
+
+    public:
+        EntitySnapshot();
+        EntitySnapshot(Time time, const MemoryID& parentID = {});
+        EntitySnapshot(const MemoryID& id);
+
+        /// Copy the instances from `other` to this.
+        EntitySnapshot(const EntitySnapshot& other);
+
+        /// Copy the instances from `other` to this.
+        EntitySnapshot& operator=(const EntitySnapshot& other);
+
+        // Conversion
+        void reload(const std::shared_ptr<std::filesystem::path>&);
+        wm::EntitySnapshot convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const;
+
+        // MongoDB connection
+        void setTo(const wm::EntitySnapshot&);
+
+    private:
+        std::filesystem::path _fullPath() const;
+        std::filesystem::path _fullPath(const std::filesystem::path&) const;
+
+    public:
+        std::shared_ptr<std::filesystem::path> path;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70ed79acc064f4c0fb3a222c75bd90321c39f0e2
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp
@@ -0,0 +1,112 @@
+#include "Memory.h"
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+    Memory::Memory()
+    {
+    }
+
+    Memory::Memory(const std::string& name) :
+        base::detail::MemoryItem(MemoryID().withMemoryName(name))
+    {
+    }
+
+    Memory::Memory(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    Memory::Memory(const Memory& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, CoreSegment>, Memory>(other)
+    {
+        *this = other;
+    }
+
+    Memory& Memory::operator=(const Memory& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    std::filesystem::path Memory::_fullPath() const
+    {
+        if (path)
+        {
+            return _fullPath(*path);
+        }
+        return std::filesystem::path();
+    }
+
+    std::filesystem::path Memory::_fullPath(const std::filesystem::path& path) const
+    {
+        return path / id().memoryName;
+    }
+
+    wm::Memory Memory::convert() const
+    {
+        wm::Memory m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addCoreSegment(s.convert());
+        }
+        return m;
+    }
+
+    void Memory::reload(const std::filesystem::path& p)
+    {
+        if (std::filesystem::is_regular_file(p))
+        {
+            ARMARX_ERROR << "The entered path is leading to a file! Abort due to error.";
+        }
+
+        _container.clear();
+        path = std::make_shared<std::filesystem::path>(p.parent_path());
+
+        if (!std::filesystem::exists(p))
+        {
+            ARMARX_INFO << "The entered path does not exist. Assuming an empty container.";
+        }
+        else
+        {
+            id() = MemoryID().withMemoryName(p.filename());
+
+            for (const auto& d : std::filesystem::directory_iterator(p))
+            {
+                if (d.is_directory())
+                {
+                    std::string k = d.path().filename();
+                    auto wms = _container.emplace(std::make_pair(k, id().withCoreSegmentName(k)));
+                    wms.first->second.reload(path);
+                }
+            }
+        }
+    }
+
+    void Memory::append(const wm::Memory& m)
+    {
+        std::filesystem::create_directories(_fullPath());
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.append(s);
+            }
+            else
+            {
+                std::filesystem::create_directory(_fullPath() / k);
+
+                auto wms = _container.emplace(std::make_pair(k, id().withCoreSegmentName(k)));
+                wms.first->second.path = path;
+                wms.first->second.append(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Memory.h b/source/RobotAPI/libraries/armem/core/diskmemory/Memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..32bd30fa69c4dff87ef9d13e599cac8442936003
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/Memory.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <filesystem>
+
+#include "../base/MemoryBase.h"
+
+#include "CoreSegment.h"
+
+#include "../workingmemory/Memory.h"
+
+namespace armarx::armem::d_ltm
+{
+
+    /**
+     * @brief Data of a memory consisting of multiple core segments.
+     */
+    class Memory :
+        virtual public base::MemoryBase<CoreSegment, Memory>
+    {
+        using Base = base::MemoryBase<CoreSegment, Memory>;
+
+    public:
+        Memory();
+        Memory(const std::string& name);
+        Memory(const MemoryID& id);
+
+        Memory(const Memory& other);
+        Memory& operator=(const Memory& other);
+
+        // Conversion
+        wm::Memory convert() const;
+
+        // Filesystem connection
+        void reload(const std::filesystem::path&);
+        void append(const wm::Memory&);
+
+    private:
+        std::filesystem::path _fullPath() const;
+        std::filesystem::path _fullPath(const std::filesystem::path&) const;
+
+    public:
+        std::shared_ptr<std::filesystem::path> path;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ae84449bb7a55ccf5d7a525b5b27f50c34fb3815
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp
@@ -0,0 +1,135 @@
+#include "ProviderSegment.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+    ProviderSegment::ProviderSegment()
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withProviderSegmentName(name)),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(MemoryID().withProviderSegmentName(name), aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(parentID.withProviderSegmentName(name)),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(parentID.withProviderSegmentName(name), aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(id),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(id, aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const ProviderSegment& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, Entity>, ProviderSegment>(other),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(other)
+    {
+    }
+
+    ProviderSegment& ProviderSegment::operator=(const ProviderSegment& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    std::filesystem::path ProviderSegment::_fullPath() const
+    {
+        if (path)
+        {
+            return _fullPath(*path);
+        }
+        return std::filesystem::path();
+    }
+
+    std::filesystem::path ProviderSegment::_fullPath(const std::filesystem::path& path) const
+    {
+        return path / id().memoryName / id().coreSegmentName / id().providerSegmentName;
+    }
+
+    wm::ProviderSegment ProviderSegment::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const
+    {
+        wm::ProviderSegment m;
+        for (const auto& [_, s] : _container)
+        {
+            if (hasAronType())
+            {
+                m.addEntity(s.convert(_aronType));
+            }
+            else
+            {
+                m.addEntity(s.convert(expectedStructure));
+            }
+        }
+        return m;
+    }
+
+    void ProviderSegment::reload(const std::shared_ptr<std::filesystem::path>& p_ptr)
+    {
+        if (!p_ptr)
+        {
+            ARMARX_WARNING << "The entered is NULL.";
+        }
+        std::filesystem::path p = _fullPath(*p_ptr);
+        if (std::filesystem::is_regular_file(p))
+        {
+            ARMARX_ERROR << "The entered path is leading to a file! Abort due to error.";
+        }
+
+        _container.clear();
+        path = p_ptr;
+
+        if (!std::filesystem::exists(p))
+        {
+            ARMARX_INFO << "The entered path does not exist. Assuming an empty container.";
+        }
+        else
+        {
+            for (const auto& d : std::filesystem::directory_iterator(p))
+            {
+                if (d.is_directory())
+                {
+                    std::string k = d.path().filename();
+                    auto wms = _container.emplace(std::make_pair(k, id().withEntityName(k)));
+                    wms.first->second.reload(p_ptr);
+                }
+
+                if (d.is_regular_file())
+                {
+                    readAronType(d.path());
+                }
+            }
+        }
+    }
+
+    void ProviderSegment::append(const wm::ProviderSegment& m)
+    {
+        std::filesystem::create_directories(_fullPath());
+        writeAronType(_fullPath());
+
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.append(s);
+            }
+            else
+            {
+                std::filesystem::create_directory(_fullPath() / k);
+                auto wms = _container.emplace(std::make_pair(k, id().withEntityName(k)));
+                wms.first->second.path = path;
+                wms.first->second.append(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.h b/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.h
new file mode 100644
index 0000000000000000000000000000000000000000..c3a5f1dfd2b75e49d8d20c54816a793c0ba85c4b
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <filesystem>
+
+#include "../base/ProviderSegmentBase.h"
+#include "detail/TypedEntityContainer.h"
+
+#include "Entity.h"
+
+#include "../workingmemory/ProviderSegment.h"
+
+
+namespace armarx::armem::d_ltm
+{
+
+    /**
+     * @brief Data of a provider segment containing multiple entities.
+     */
+    class ProviderSegment :
+        virtual public base::ProviderSegmentBase<Entity, ProviderSegment>,
+        virtual public detail::TypedEntityContainer<Entity, ProviderSegment>
+    {
+        using Base = base::ProviderSegmentBase<Entity, ProviderSegment>;
+
+    public:
+        ProviderSegment();
+        ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+
+        ProviderSegment(const ProviderSegment& other);
+        ProviderSegment& operator=(const ProviderSegment& other);
+
+        // Conversion
+        wm::ProviderSegment convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const;
+
+        // Filesystem connection
+        void reload(const std::shared_ptr<std::filesystem::path>&);
+        void append(const wm::ProviderSegment&);
+
+    private:
+        std::filesystem::path _fullPath() const;
+        std::filesystem::path _fullPath(const std::filesystem::path&) const;
+
+    public:
+        std::shared_ptr<std::filesystem::path> path;
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/detail/TypedEntityContainer.h b/source/RobotAPI/libraries/armem/core/diskmemory/detail/TypedEntityContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..9163b9482dc880a667f810e43039a1ac81d52f0a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/diskmemory/detail/TypedEntityContainer.h
@@ -0,0 +1,100 @@
+#pragma once
+
+#include <iostream>
+#include <fstream>
+
+#include "../../base/detail/TypedEntityContainerBase.h"
+#include "../Entity.h"
+
+#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
+#include <RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h>
+#include <RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h>
+#include <RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.h>
+#include <RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h>
+#include <RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h>
+
+namespace armarx::armem::d_ltm::detail
+{
+
+    /**
+     * @brief An entity container with a specific (Aron) type.
+     */
+    template <class _ValueT, class Derived>
+    class TypedEntityContainer :
+        virtual public base::detail::TypedEntityContainerBase<_ValueT, Entity, Derived>
+    {
+        using Base = base::detail::TypedEntityContainerBase<_ValueT, Entity, Derived>;
+
+    public:
+        TypedEntityContainer& operator=(const TypedEntityContainer& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+    protected:
+        aron::typenavigator::ObjectNavigatorPtr unwrapType(const aron::typenavigator::ObjectNavigatorPtr& t) const
+        {
+            return aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(t->getMemberType(TYPE_WRAPPER_DATA_FIELD));
+        }
+
+        aron::typenavigator::ObjectNavigatorPtr wrapType(const aron::typenavigator::ObjectNavigatorPtr& t) const
+        {
+            aron::typenavigator::ObjectNavigatorPtr typeWrapped(new aron::typenavigator::ObjectNavigator());
+            typeWrapped->setObjectName(t->getObjectName() + "__ltm_type_export");
+            typeWrapped->addMemberType(TYPE_WRAPPER_DATA_FIELD, t);
+
+            typeWrapped->addMemberType(TYPE_WRAPPER_TIME_STORED_FIELD, std::make_shared<aron::typenavigator::LongNavigator>());
+            typeWrapped->addMemberType(TYPE_WRAPPER_TIME_CREATED_FIELD, std::make_shared<aron::typenavigator::LongNavigator>());
+            typeWrapped->addMemberType(TYPE_WRAPPER_TIME_SENT_FIELD, std::make_shared<aron::typenavigator::LongNavigator>());
+            typeWrapped->addMemberType(TYPE_WRAPPER_TIME_ARRIVED_FIELD, std::make_shared<aron::typenavigator::LongNavigator>());
+            typeWrapped->addMemberType(TYPE_WRAPPER_CONFIDENCE_FIELD, std::make_shared<aron::typenavigator::DoubleNavigator>());
+
+            return typeWrapped;
+        }
+
+        using Base::aronType;
+        void readAronType(const std::filesystem::path& d)
+        {
+            if (std::filesystem::is_regular_file(d))
+            {
+                if (d.filename() == (std::string(TYPE_FILENAME) + ".json"))
+                {
+                    std::ifstream ifs(d);
+                    std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
+
+                    aron::typeIO::reader::NlohmannJSONReader typeReader(file_content);
+                    aron::typeIO::writer::NavigatorWriter navWriter;
+                    aron::typeIO::Converter::ReadAndConvert(typeReader, navWriter);
+                    this->aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(navWriter.getResult());
+                }
+            }
+        }
+
+        using Base::hasAronType;
+        void writeAronType(const std::filesystem::path& d)
+        {
+            if (hasAronType())
+            {
+                std::ofstream ofs;
+                ofs.open(d);
+
+                aron::typeIO::writer::NlohmannJSONWriter typeWriter;
+                aron::typeIO::Visitor::VisitAndSetup(typeWriter, this->aronType());
+                std::string new_file_full_content = typeWriter.getResult().dump(2);
+
+                ofs << new_file_full_content;
+                ofs.close();
+            }
+        }
+
+    private:
+        static const constexpr char* TYPE_FILENAME = "type";
+        static constexpr const char* TYPE_WRAPPER_DATA_FIELD            = "__ARON_DATA";
+        static constexpr const char* TYPE_WRAPPER_TIME_STORED_FIELD     = "__WRITER_METADATA__TIME_STORED";
+        static constexpr const char* TYPE_WRAPPER_TIME_CREATED_FIELD    = "__ENTITY_METADATA__TIME_CREATED";
+        static constexpr const char* TYPE_WRAPPER_TIME_SENT_FIELD       = "__ENTITY_METADATA__TIME_SENT";
+        static constexpr const char* TYPE_WRAPPER_TIME_ARRIVED_FIELD    = "__ENTITY_METADATA__TIME_ARRIVED";
+        static constexpr const char* TYPE_WRAPPER_CONFIDENCE_FIELD      = "__ENTITY_METADATA__CONFIDENCE";
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/ice_conversions.cpp
index 684028ae6c96d8e905de06d1bf957669d6db3d47..d79acf1da2b86f94414205131173797e0354bc24 100644
--- a/source/RobotAPI/libraries/armem/core/ice_conversions.cpp
+++ b/source/RobotAPI/libraries/armem/core/ice_conversions.cpp
@@ -145,138 +145,13 @@ namespace armarx
     }
 
 
-    void armem::detail::toIceItem(data::detail::MemoryItem& ice, const MemoryItem& item)
+    void armem::detail::toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item)
     {
         toIce(ice.id, item.id());
     }
 
-    void armem::detail::fromIceItem(const data::detail::MemoryItem& ice, MemoryItem& item)
+    void armem::detail::fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item)
     {
         fromIce(ice.id, item.id());
     }
-
-
-    void armem::toIce(data::EntityInstanceMetadata& ice, const EntityInstanceMetadata& metadata)
-    {
-        ice.confidence = metadata.confidence;
-        toIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
-        toIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
-        toIce(ice.timeSentMicroSeconds, metadata.timeSent);
-    }
-    void armem::fromIce(const data::EntityInstanceMetadata& ice, EntityInstanceMetadata& metadata)
-    {
-        metadata.confidence = ice.confidence;
-        fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
-        fromIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
-        fromIce(ice.timeSentMicroSeconds, metadata.timeSent);
-    }
-
-    void armem::toIce(data::EntityInstance& ice, const EntityInstance& data)
-    {
-        detail::toIceItem(ice, data);
-
-        if (data.data())
-        {
-            ice.data = data.data()->toAronDictPtr();
-        }
-        toIce(ice.metadata, data.metadata());
-    }
-    void armem::fromIce(const data::EntityInstance& ice, EntityInstance& data)
-    {
-        detail::fromIceItem(ice, data);
-
-        if (ice.data)
-        {
-            data.setData(aron::datanavigator::DictNavigator::FromAronDictPtr(ice.data));
-        }
-        fromIce(ice.metadata, data.metadata());
-    }
-
-
-    void armem::toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot)
-    {
-        detail::toIceItem(ice, snapshot);
-
-        toIce(ice.instances, snapshot.instances);
-    }
-    void armem::fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot)
-    {
-        detail::fromIceItem(ice, snapshot);
-
-        fromIce(ice.instances, snapshot.instances);
-    }
-
-    void armem::toIce(data::Entity& ice, const Entity& entity)
-    {
-        detail::toIceItem(ice, entity);
-
-        toIce(ice.history, entity.history);
-    }
-    void armem::fromIce(const data::Entity& ice, Entity& entity)
-    {
-        detail::fromIceItem(ice, entity);
-
-        fromIce(ice.history, entity.history);
-    }
-
-
-    void armem::toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment)
-    {
-        detail::toIceItem(ice, providerSegment);
-
-        if (providerSegment.hasAronType())
-        {
-            ice.aronType = providerSegment.aronType()->getResult();
-        }
-        toIce(ice.entities, providerSegment.entities);
-    }
-    void armem::fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment)
-    {
-        detail::fromIceItem(ice, providerSegment);
-
-        if (ice.aronType)
-        {
-            providerSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(
-                                             aron::typenavigator::Navigator::FromAronType(ice.aronType)
-                                         );
-        }
-        fromIce(ice.entities, providerSegment.entities);
-    }
-
-    void armem::toIce(data::CoreSegment& ice, const CoreSegment& coreSegment)
-    {
-        detail::toIceItem(ice, coreSegment);
-
-        if (coreSegment.hasAronType())
-        {
-            ice.aronType = coreSegment.aronType()->getResult();
-        }
-        toIce(ice.providerSegments, coreSegment.providerSegments);
-    }
-    void armem::fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment)
-    {
-        detail::fromIceItem(ice, coreSegment);
-
-        if (ice.aronType)
-        {
-            coreSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(
-                                         aron::typenavigator::Navigator::FromAronType(ice.aronType)
-                                     );
-        }
-        fromIce(ice.providerSegments, coreSegment.providerSegments);
-    }
-
-    void armem::toIce(data::Memory& ice, const Memory& memory)
-    {
-        detail::toIceItem(ice, memory);
-
-        toIce(ice.coreSegments, memory.coreSegments);
-    }
-    void armem::fromIce(const data::Memory& ice, Memory& memory)
-    {
-        detail::fromIceItem(ice, memory);
-
-        fromIce(ice.coreSegments, memory.coreSegments);
-    }
-
 }
diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions.h b/source/RobotAPI/libraries/armem/core/ice_conversions.h
index f615e7c3bfd05861b81a3debedc0b8500b6e1365..874684cac2a6a52b8742c36dcc2bdea8346e1586 100644
--- a/source/RobotAPI/libraries/armem/core/ice_conversions.h
+++ b/source/RobotAPI/libraries/armem/core/ice_conversions.h
@@ -6,7 +6,7 @@
 #include "ice_conversions_templates.h"
 
 #include "Commit.h"
-#include "Memory.h"
+#include "base/detail/MemoryItem.h"
 
 
 namespace IceUtil
@@ -52,35 +52,10 @@ namespace armarx::armem
     void fromIce(const data::EntityUpdate& ice, EntityUpdate& update, Time timeArrived);
 
 
-
-    void toIce(data::EntityInstanceMetadata& ice, const EntityInstanceMetadata& metadata);
-    void fromIce(const data::EntityInstanceMetadata& ice, EntityInstanceMetadata& metadata);
-
-    void toIce(data::EntityInstance& ice, const EntityInstance& data);
-    void fromIce(const data::EntityInstance& ice, EntityInstance& data);
-
-
-    void toIce(data::EntitySnapshot& ice, const EntitySnapshot& snapshot);
-    void fromIce(const data::EntitySnapshot& ice, EntitySnapshot& snapshot);
-
-    void toIce(data::Entity& ice, const Entity& entity);
-    void fromIce(const data::Entity& ice, Entity& entity);
-
-
-    void toIce(data::ProviderSegment& ice, const ProviderSegment& providerSegment);
-    void fromIce(const data::ProviderSegment& ice, ProviderSegment& providerSegment);
-
-    void toIce(data::CoreSegment& ice, const CoreSegment& coreSegment);
-    void fromIce(const data::CoreSegment& ice, CoreSegment& coreSegment);
-
-    void toIce(data::Memory& ice, const Memory& memory);
-    void fromIce(const data::Memory& ice, Memory& memory);
-
-
     namespace detail
     {
-        void toIceItem(data::detail::MemoryItem& ice, const MemoryItem& item);
-        void fromIceItem(const data::detail::MemoryItem& ice, MemoryItem& item);
+        void toIceItem(data::detail::MemoryItem& ice, const armem::base::detail::MemoryItem& item);
+        void fromIceItem(const data::detail::MemoryItem& ice, armem::base::detail::MemoryItem& item);
     }
 
 }
diff --git a/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h b/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h
index 2f729f2026aa2fc20ce616b18ed408bf3d1f3206..e0c71faac37cd899d85d174c33196499a29df770 100644
--- a/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h
+++ b/source/RobotAPI/libraries/armem/core/ice_conversions_templates.h
@@ -22,8 +22,24 @@ namespace armarx::armem
     }
 
 
-    // General return version
+    // Ice Handle
+    template <class IceT, class CppT>
+    void toIce(::IceInternal::Handle<IceT>& ice, const CppT& cpp)
+    {
+        ice = new IceT();
+        toIce(*ice, cpp);
+    }
+    template <class IceT, class CppT>
+    void fromIce(const ::IceInternal::Handle<IceT>& ice, CppT& cpp)
+    {
+        if (ice)
+        {
+            fromIce(*ice, cpp);
+        }
+    }
+
 
+    // General return version
     template <class IceT, class CppT>
     IceT toIce(const CppT& cpp)
     {
@@ -39,7 +55,6 @@ namespace armarx::armem
         return cpp;
     }
 
-
     // std::unique_ptr
 
     template <class IceT, class CppT>
@@ -58,24 +73,6 @@ namespace armarx::armem
     }
 
 
-    // Ice Handle
-
-    template <class IceT, class CppT>
-    void toIce(::IceInternal::Handle<IceT>& ice, const CppT& cpp)
-    {
-        ice = new IceT();
-        toIce(*ice, cpp);
-    }
-    template <class IceT, class CppT>
-    void fromIce(const ::IceInternal::Handle<IceT>& ice, CppT& cpp)
-    {
-        if (ice)
-        {
-            fromIce(*ice, cpp);
-        }
-    }
-
-
     // Ice Handle <-> std::unique_ptr
 
     template <class IceT, class CppT>
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskReader/DiskReader.cpp b/source/RobotAPI/libraries/armem/core/io/DiskReader/DiskReader.cpp
deleted file mode 100644
index 08584369d6f745f7c0203497a531cd2e133319c2..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskReader/DiskReader.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#include "DiskReader.h"
-
-#include <sstream>
-#include <fstream>
-#include <iostream>
-
-// ArmarX
-#include <RobotAPI/interface/aron.h>
-#include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h>
-
-#include <RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h>
-#include <RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h>
-
-#include <RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h>
-
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-namespace armarx::armem::io
-{
-
-    FileSystemLookupMemory DiskReader::readMemoryStructureFromDisk()
-    {
-        FileSystemLookupMemory ret;
-
-        for (const auto& memoryFolder : std::filesystem::directory_iterator(rootPath))
-        {
-            if (!std::filesystem::is_directory(memoryFolder))
-            {
-                continue;
-            }
-
-            std::string folderName = memoryFolder.path().filename();
-            FileSystemLookupMemory tmp = readMemoryStructureFromDisk(folderName);
-            ret.merge(tmp);
-        }
-        return ret;
-    }
-
-    FileSystemLookupMemory DiskReader::readMemoryStructureFromDisk(const std::string& memoryFolderName)
-    {
-        FileSystemLookupMemory ret;
-
-        std::filesystem::path p = rootPath / memoryFolderName;
-        if (!std::filesystem::is_directory(p))
-        {
-            return ret;
-        }
-
-        for (const auto& coreSegmentFolder : std::filesystem::directory_iterator(p))
-        {
-            if (!std::filesystem::is_directory(coreSegmentFolder))
-            {
-                continue;
-            }
-            std::string coreSegmentName = coreSegmentFolder.path().filename();
-            for (const auto& providerSegmentFolder : std::filesystem::directory_iterator(coreSegmentFolder.path()))
-            {
-                if (!std::filesystem::is_directory(providerSegmentFolder))
-                {
-                    continue;
-                }
-                std::string providerSegmentName = providerSegmentFolder.path().filename();
-                for (const auto& entityFolder : std::filesystem::directory_iterator(providerSegmentFolder.path()))
-                {
-                    if (!std::filesystem::is_directory(entityFolder))
-                    {
-                        continue;
-                    }
-                    std::string entityName = entityFolder.path().filename();
-                    for (const auto& entityHistoryFolder : std::filesystem::directory_iterator(entityFolder.path()))
-                    {
-                        if (!std::filesystem::is_directory(entityHistoryFolder))
-                        {
-                            continue;
-                        }
-                        Time entityTimestamp = armem::timeFromStringMicroSeconds(entityHistoryFolder.path().filename());
-
-                        // TODO: make this relative to amount of files in folder
-                        for (unsigned int i = 0; i < 10000; ++i)
-                        {
-                            std::filesystem::path entityInstance = entityHistoryFolder / std::filesystem::path(std::to_string(i) + getEntityInstanceSuffix());
-                            if (!std::filesystem::is_regular_file(entityInstance))
-                            {
-                                break;
-                            }
-                            DiskMemory& mem = ret.memoryLookupTable[memoryFolderName];
-                            DiskCoreSegment& mem_core = mem[coreSegmentName];
-                            DiskProviderSegment& mem_prov = mem_core[providerSegmentName];
-                            DiskEntity& mem_entity = mem_prov[entityName];
-                            DiskEntitySnapshot& mem_entity_history = mem_entity[entityTimestamp];
-
-                            mem_entity_history.push_back(entityInstance);
-                        }
-                    }
-                }
-            }
-        }
-        return ret;
-    }
-
-    EntityInstance DiskReader::readSingleInstanceFromDisk(const MemoryID& id, const aron::typenavigator::NavigatorPtr& expectedStructure) const
-    {
-        std::filesystem::path p = rootPath / (id.str() + getEntityInstanceSuffix());
-        return readSingleInstanceFromDisk(p, expectedStructure);
-    }
-
-    EntityInstance DiskReader::readSingleInstanceFromDisk(const std::filesystem::path& p, const aron::typenavigator::NavigatorPtr& expectedStructure) const
-    {
-        if (!std::filesystem::is_regular_file(p))
-        {
-            throw error::PathNotARegularFile(p.string(), "During readSingleInstanceFromDisk tried to read an entityInstance from a non-file path.");
-        }
-
-        std::ifstream ifs(p);
-        std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
-
-        aron::datanavigator::DictNavigatorPtr dictdata = getStringAsDataNavigator(file_content, expectedStructure);
-        return unwrapData(dictdata);
-    }
-
-    aron::typenavigator::ObjectNavigatorPtr DiskReader::readSingleTypeInformationFromDisk(const MemoryID& id) const
-    {
-        std::filesystem::path p = rootPath / id.str() / (id.getLeafItem() + getTypeSuffix());
-        return readSingleTypeInformationFromDisk(p);
-    }
-
-    aron::typenavigator::ObjectNavigatorPtr DiskReader::readSingleTypeInformationFromDisk(const std::filesystem::path& p) const
-    {
-        if (!std::filesystem::is_regular_file(p))
-        {
-            return nullptr;
-        }
-
-        std::ifstream ifs(p);
-        std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
-
-        aron::typenavigator::ObjectNavigatorPtr objecttype = getStringAsTypeNavigator(file_content);
-        return objecttype;
-    }
-
-    EntityInstance DiskReader::unwrapData(const aron::datanavigator::DictNavigatorPtr& dataWrapped) const
-    {
-        EntityInstance e;
-        EntityInstanceMetadata& metadata = e.metadata();
-
-        aron::datanavigator::DictNavigatorPtr data = aron::datanavigator::DictNavigator::DynamicCastAndCheck(dataWrapped->getElement(DISK_READER_WRITER_DATA_FIELD));
-        e.setData(data);
-
-        // not used right now
-        //aron::datanavigator::LongNavigatorPtr timeWrapped = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DISK_READER_WRITER_TIME_WRAPPED_FIELD));
-
-        aron::datanavigator::LongNavigatorPtr timeCreated = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DISK_READER_WRITER_TIME_CREATED_FIELD));
-        metadata.timeCreated = Time::microSeconds(timeCreated->toAronLongPtr()->value);
-
-        aron::datanavigator::LongNavigatorPtr timeSent = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DISK_READER_WRITER_TIME_SENT_FIELD));
-        metadata.timeSent = Time::microSeconds(timeSent->toAronLongPtr()->value);
-
-        aron::datanavigator::LongNavigatorPtr timeArrived = aron::datanavigator::LongNavigator::DynamicCastAndCheck(dataWrapped->getElement(DISK_READER_WRITER_TIME_ARRIVED_FIELD));
-        metadata.timeArrived = Time::microSeconds(timeArrived->toAronLongPtr()->value);
-
-        aron::datanavigator::DoubleNavigatorPtr confidence = aron::datanavigator::DoubleNavigator::DynamicCastAndCheck(dataWrapped->getElement(DISK_READER_WRITER_CONFIDENCE_FIELD));
-        metadata.confidence = static_cast<float>(confidence->toAronDoublePtr()->value);
-
-        return e;
-    }
-
-    aron::typenavigator::ObjectNavigatorPtr DiskReader::unwrapType(const aron::typenavigator::ObjectNavigatorPtr& t) const
-    {
-        return aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(t->getMemberType(DISK_READER_WRITER_DATA_FIELD));
-    }
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskReader/DiskReader.h b/source/RobotAPI/libraries/armem/core/io/DiskReader/DiskReader.h
deleted file mode 100644
index 2ae252521b823e270533d2305a4af272b76bf944..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskReader/DiskReader.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <filesystem>
-#include <memory>
-#include <string>
-
-#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/Navigator.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
-
-#include <RobotAPI/libraries/armem/core/EntityInstance.h>
-
-#include "../DiskReaderWriter.h"
-#include "../FileSystemLookupMemory.h"
-
-
-namespace armarx::armem::io
-{
-    class DiskReader;
-    using DiskReaderPtr = std::shared_ptr<DiskReader>;
-
-    class DiskReader : virtual public DiskReaderWriter
-    {
-    public:
-
-        using DiskReaderWriter::DiskReaderWriter;
-
-        FileSystemLookupMemory readMemoryStructureFromDisk();
-        FileSystemLookupMemory readMemoryStructureFromDisk(const std::string&);
-
-        EntityInstance readSingleInstanceFromDisk(const std::filesystem::path&, const aron::typenavigator::NavigatorPtr& expectedStructure = nullptr) const;
-        EntityInstance readSingleInstanceFromDisk(const MemoryID&, const aron::typenavigator::NavigatorPtr& expectedStructure = nullptr) const;
-
-        aron::typenavigator::ObjectNavigatorPtr readSingleTypeInformationFromDisk(const std::filesystem::path&) const;
-        aron::typenavigator::ObjectNavigatorPtr readSingleTypeInformationFromDisk(const MemoryID&) const;
-
-    protected:
-        EntityInstance unwrapData(const aron::datanavigator::DictNavigatorPtr&) const;
-        aron::typenavigator::ObjectNavigatorPtr unwrapType(const aron::typenavigator::ObjectNavigatorPtr&) const;
-
-        virtual aron::datanavigator::DictNavigatorPtr getStringAsDataNavigator(const std::string&, const aron::typenavigator::NavigatorPtr&) const = 0;
-        virtual aron::typenavigator::ObjectNavigatorPtr getStringAsTypeNavigator(const std::string& s) const = 0;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.cpp b/source/RobotAPI/libraries/armem/core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.cpp
deleted file mode 100644
index 3742996cda7cf4f03a15615a5ba7a296dfeba591..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "NlohmannJSONDiskReader.h"
-
-#include <RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h>
-#include <RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h>
-#include <RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h>
-
-
-namespace armarx::armem::io
-{
-
-    NlohmannJSONDiskReader::NlohmannJSONDiskReader(bool createFolder) :
-        DiskReaderWriter(createFolder),
-        DiskReader(createFolder)
-    {
-    }
-
-    NlohmannJSONDiskReader::NlohmannJSONDiskReader(const std::string& rootPath, bool createFolder) :
-        DiskReaderWriter(rootPath, createFolder),
-        DiskReader(rootPath, createFolder)
-    {
-    }
-
-    aron::datanavigator::DictNavigatorPtr NlohmannJSONDiskReader::getStringAsDataNavigator(const std::string& s, const aron::typenavigator::NavigatorPtr& expectedStructure) const
-    {
-        aron::dataIO::reader::NlohmannJSONReader dataReader(s);
-        aron::dataIO::writer::NavigatorWriter navWriter;
-        aron::dataIO::Converter::ConvertFromReader(dataReader, navWriter, expectedStructure);
-        return aron::datanavigator::DictNavigator::DynamicCastAndCheck(navWriter.getResult());
-    }
-
-    aron::typenavigator::ObjectNavigatorPtr NlohmannJSONDiskReader::getStringAsTypeNavigator(const std::string& s) const
-    {
-        aron::typeIO::reader::NlohmannJSONReader typeReader(s);
-        aron::typeIO::writer::NavigatorWriter navWriter;
-        aron::typeIO::Converter::ConvertFromReader(typeReader, navWriter);
-        return aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(navWriter.getResult());
-    }
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.h b/source/RobotAPI/libraries/armem/core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.h
deleted file mode 100644
index 6358d751b07fe395de0345bf06aa4af374b85289..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <memory>
-#include <string>
-
-// Base Class
-#include "../DiskReader.h"
-
-
-namespace armarx::armem::io
-{
-    class NlohmannJSONDiskReader;
-    using NlohmannJSONDiskReaderPtr = std::shared_ptr<NlohmannJSONDiskReader>;
-
-    class NlohmannJSONDiskReader : virtual public DiskReader
-    {
-    public:
-        NlohmannJSONDiskReader(bool createFolder);
-        NlohmannJSONDiskReader(const std::string& rootPath, bool createFolder);
-
-
-    protected:
-        aron::datanavigator::DictNavigatorPtr getStringAsDataNavigator(
-            const std::string&, const aron::typenavigator::NavigatorPtr& expectedStructure = nullptr) const override;
-        aron::typenavigator::ObjectNavigatorPtr getStringAsTypeNavigator(const std::string& s) const override;
-
-        std::string getEntityInstanceSuffix() const override
-        {
-            return ".data.json";
-        }
-
-        std::string getTypeSuffix() const override
-        {
-            return ".type.json";
-        }
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskReaderWriter.cpp b/source/RobotAPI/libraries/armem/core/io/DiskReaderWriter.cpp
deleted file mode 100644
index 0929a3fc4d85a0efa44178cca02d218104956d48..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskReaderWriter.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#include "DiskReaderWriter.h"
-
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-namespace armarx::armem::io
-{
-
-    DiskReaderWriter::DiskReaderWriter(bool createIfNotExistent) :
-        DiskReaderWriter("/tmp/MemoryExport", createIfNotExistent)
-    {}
-
-    DiskReaderWriter::DiskReaderWriter(const std::filesystem::path& rootPath, bool createIfNotExistent) :
-        rootPath(rootPath)
-    {
-        if (!std::filesystem::exists(rootPath.parent_path()))
-        {
-            throw error::PathDoesNotExist(rootPath.parent_path().string(),
-                                          "The parent path does not exist. At least this directory must exist!");
-        }
-
-        if (!std::filesystem::is_directory(rootPath.parent_path()))
-        {
-            throw error::PathDoesNotExist(rootPath.parent_path().string(), "The parent path is not a directory. It must be a directory.");
-        }
-
-        if (!std::filesystem::exists(rootPath))
-        {
-            if (createIfNotExistent)
-            {
-                std::filesystem::create_directory(rootPath);
-            }
-            else
-            {
-                throw error::PathDoesNotExist(rootPath.string(), "The path does not exist and a new folder should not be created!");
-            }
-        }
-
-        if (!std::filesystem::is_directory(rootPath))
-        {
-            throw error::PathNotADirectory(rootPath.string(), "The Path is not valid. It points to a file instead of a folder!");
-        }
-    }
-
-    DiskReaderWriter::~DiskReaderWriter()
-    {
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskReaderWriter.h b/source/RobotAPI/libraries/armem/core/io/DiskReaderWriter.h
deleted file mode 100644
index eaed6011e162b5244e8ed4f97877d2b43c4f53c9..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskReaderWriter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <string>
-#include <filesystem>
-
-// ArmarX
-#include <RobotAPI/interface/aron.h>
-
-#include <RobotAPI/libraries/armem/core/Time.h>
-
-
-namespace armarx::armem::io
-{
-    class DiskReaderWriter
-    {
-    public:
-        DiskReaderWriter(bool createIfNotExistent);
-        DiskReaderWriter(const std::filesystem::path& rootPath, bool createIfNotExistent);
-
-        virtual ~DiskReaderWriter();
-
-
-    protected:
-        virtual std::string getEntityInstanceSuffix() const = 0;
-        virtual std::string getTypeSuffix() const = 0;
-
-    protected:
-        std::filesystem::path rootPath;
-
-        const std::string DISK_READER_WRITER_DATA_FIELD            = "DATA";
-        const std::string DISK_READER_WRITER_TIME_STORED_FIELD     = "STORAGE_MANAGER_METADATA__TIME_STORED";
-        const std::string DISK_READER_WRITER_TIME_CREATED_FIELD    = "ENTITY_METADATA__TIME_CREATED";
-        const std::string DISK_READER_WRITER_TIME_SENT_FIELD       = "ENTITY_METADATA__TIME_SENT";
-        const std::string DISK_READER_WRITER_TIME_ARRIVED_FIELD    = "ENTITY_METADATA__TIME_ARRIVED";
-        const std::string DISK_READER_WRITER_CONFIDENCE_FIELD      = "ENTITY_METADATA__CONFIDENCE";
-
-    };
-
-    using DiskReaderWriterPtr = std::shared_ptr<DiskReaderWriter>;
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskWriter/DiskWriter.cpp b/source/RobotAPI/libraries/armem/core/io/DiskWriter/DiskWriter.cpp
deleted file mode 100644
index 9168f8adf64313f17a21700a50d93113db60954c..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskWriter/DiskWriter.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-// STD/STL
-#include "DiskWriter.h"
-
-#include <fstream>
-#include <iostream>
-
-// ArmarX
-#include <RobotAPI/interface/aron.h>
-#include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h>
-
-#include <RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h>
-#include <RobotAPI/libraries/aron/core/io/dataIO/Writer.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/Writer.h>
-
-
-// BaseClass
-#include "../DiskReaderWriter.h"
-#include "../FileSystemLookupMemory.h"
-
-#include <RobotAPI/libraries/armem/core/Memory.h>
-#include <RobotAPI/libraries/armem/core/CoreSegment.h>
-#include <RobotAPI/libraries/armem/core/Entity.h>
-
-
-namespace armarx::armem::io
-{
-
-    DiskWriterReturnInformation DiskWriter::writeOnDisk(const Memory& m)
-    {
-        MemoryID id = m.id().getMemoryID();
-        DiskWriterReturnInformation ret(id.memoryName);
-
-        std::filesystem::path p = rootPath / id.str();
-        if (!ensureDirectoryPathExists(p))
-        {
-            ret.hasError = true;
-            return ret;
-        }
-
-        for (const auto& [coreKey, coreSegment] : m.coreSegments)
-        {
-            MemoryID storeCore(id);
-            storeCore.coreSegmentName = coreKey;
-            DiskWriterReturnInformation other = writeOnDisk(storeCore, coreSegment);
-            ret.append(other);
-        }
-        return ret;
-    }
-
-    DiskWriterReturnInformation DiskWriter::writeOnDisk(const MemoryID& i, const CoreSegment& s)
-    {
-        MemoryID id = i.getCoreSegmentID();
-        DiskWriterReturnInformation ret(id.memoryName);
-
-        std::filesystem::path p = rootPath / id.str();
-        if (!ensureDirectoryPathExists(p))
-        {
-            ret.coreSegmentsError.push_back(id.str());
-            ret.hasError = true;
-            return ret;
-        }
-
-        if (s.hasAronType())
-        {
-            std::string val = getTypeAsString(wrapType(s.aronType()));
-
-            std::filesystem::path coreSegmentProviderPath = rootPath / id.str() / (id.coreSegmentName + getTypeSuffix());
-            std::ofstream ofs;
-            ofs.open(coreSegmentProviderPath);
-            ofs << val;
-            ofs.close();
-        }
-
-        for (const auto& [providerKey, providerSegment] : s.providerSegments)
-        {
-            MemoryID storeProvider(id);
-            storeProvider.providerSegmentName = providerKey;
-            DiskWriterReturnInformation other = writeOnDisk(storeProvider, providerSegment);
-            ret.append(other);
-        }
-        return ret;
-    }
-
-    DiskWriterReturnInformation DiskWriter::writeOnDisk(const MemoryID& i, const ProviderSegment& s)
-    {
-        MemoryID id = i.getProviderSegmentID();
-        DiskWriterReturnInformation ret(id.memoryName);
-
-        std::filesystem::path p = rootPath / id.str();
-        if (!ensureDirectoryPathExists(p))
-        {
-            ret.providerSegmentsError.push_back(id.str());
-            ret.hasError = true;
-            return ret;
-        }
-
-        if (s.hasAronType())
-        {
-            std::string val = getTypeAsString(wrapType(s.aronType()));
-
-            std::filesystem::path providerSegmentProviderPath = rootPath / id.str() / (id.providerSegmentName + getTypeSuffix());
-            std::ofstream ofs;
-            ofs.open(providerSegmentProviderPath);
-            ofs << val;
-            ofs.close();
-        }
-
-        for (const auto& [entityKey, entity] : s.entities)
-        {
-            MemoryID storeEntity(id);
-            storeEntity.entityName = entityKey;
-            DiskWriterReturnInformation other = writeOnDisk(storeEntity, entity);
-            ret.append(other);
-        }
-        return ret;
-    }
-
-    DiskWriterReturnInformation DiskWriter::writeOnDisk(const MemoryID& i, const Entity& s)
-    {
-        MemoryID id = i.getEntityID();
-        DiskWriterReturnInformation ret(id.memoryName);
-
-        std::filesystem::path p = rootPath / id.str();
-        if (!ensureDirectoryPathExists(p))
-        {
-            ret.entitiesError.push_back(id.str());
-            ret.hasError = true;
-            return ret;
-        }
-
-        for (const auto& [ts, snapshot] : s.history)
-        {
-            MemoryID storeSnapshot(id);
-            storeSnapshot.timestamp = ts;
-            DiskWriterReturnInformation other = writeOnDisk(storeSnapshot, snapshot);
-            ret.append(other);
-        }
-        return ret;
-    }
-
-    DiskWriterReturnInformation DiskWriter::writeOnDisk(const MemoryID& _id, const EntitySnapshot& s)
-    {
-        MemoryID id = _id.getEntitySnapshotID();
-        DiskWriterReturnInformation ret(id.memoryName);
-
-        std::filesystem::path p = rootPath / id.str();
-        if (!ensureDirectoryPathExists(p))
-        {
-            ret.historyTimestampsError.push_back(id.str());
-            ret.hasError = true;
-            return ret;
-        }
-
-        int i = 0;
-        for (const EntityInstance& instance : s.instances)
-        {
-            MemoryID storeInstance(id);
-            storeInstance.instanceIndex = i;
-
-            std::filesystem::path entityElementPath = rootPath / (storeInstance.str() + getEntityInstanceSuffix());
-            std::string val = getDataAsString(wrapData(instance));
-
-            if (filePathExists(entityElementPath))
-            {
-                if (std::filesystem::is_directory(entityElementPath))
-                {
-                    ret.entityInstancesError.push_back(id.str());
-                    ret.hasError = true;
-                    return ret;
-                }
-                //std::ifstream ifs(entityElementPath);
-                //std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
-                //if (file_content == val)
-                //{
-                //    // already written. skip
-                //    continue;
-                //}
-            }
-
-            std::ofstream ofs;
-            ofs.open(entityElementPath);
-            ofs << val;
-            ofs.close();
-            ret.storedElements.memoryLookupTable[id.memoryName]
-            [id.coreSegmentName]
-            [id.providerSegmentName]
-            [id.entityName]
-            [id.timestamp].push_back(entityElementPath);
-
-            i++;
-        }
-        return ret;
-    }
-
-    aron::datanavigator::DictNavigatorPtr DiskWriter::wrapData(const EntityInstance& e) const
-    {
-        aron::datanavigator::DictNavigatorPtr dataWrapped(new aron::datanavigator::DictNavigator());
-        dataWrapped->addElement(DISK_READER_WRITER_DATA_FIELD, e.data());
-
-        aron::datanavigator::LongNavigatorPtr timeWrapped(new aron::datanavigator::LongNavigator());
-        timeWrapped->setValue(Time::now().toMicroSeconds());
-        dataWrapped->addElement(DISK_READER_WRITER_TIME_STORED_FIELD, timeWrapped);
-
-
-        const EntityInstanceMetadata& metadata = e.metadata();
-        aron::datanavigator::LongNavigatorPtr timeCreated(new aron::datanavigator::LongNavigator());
-        timeCreated->setValue(metadata.timeCreated.toMicroSeconds());
-        dataWrapped->addElement(DISK_READER_WRITER_TIME_CREATED_FIELD, timeCreated);
-
-        aron::datanavigator::LongNavigatorPtr timeSent(new aron::datanavigator::LongNavigator());
-        timeSent->setValue(metadata.timeSent.toMicroSeconds());
-        dataWrapped->addElement(DISK_READER_WRITER_TIME_SENT_FIELD, timeSent);
-
-        aron::datanavigator::LongNavigatorPtr timeArrived(new aron::datanavigator::LongNavigator());
-        timeArrived->setValue(metadata.timeArrived.toMicroSeconds());
-        dataWrapped->addElement(DISK_READER_WRITER_TIME_ARRIVED_FIELD, timeArrived);
-
-        aron::datanavigator::DoubleNavigatorPtr confidence(new aron::datanavigator::DoubleNavigator());
-        confidence->setValue(metadata.confidence);
-        dataWrapped->addElement(DISK_READER_WRITER_CONFIDENCE_FIELD, confidence);
-
-        return dataWrapped;
-    }
-
-    aron::typenavigator::ObjectNavigatorPtr DiskWriter::wrapType(const aron::typenavigator::ObjectNavigatorPtr& t) const
-    {
-        aron::typenavigator::ObjectNavigatorPtr typeWrapped(new aron::typenavigator::ObjectNavigator());
-        typeWrapped->setObjectName(t->getName() + "__ltm_export");
-        typeWrapped->addMemberType(DISK_READER_WRITER_DATA_FIELD, t);
-
-        typeWrapped->addMemberType(DISK_READER_WRITER_TIME_STORED_FIELD, aron::typenavigator::LongNavigatorPtr(new aron::typenavigator::LongNavigator()));
-        typeWrapped->addMemberType(DISK_READER_WRITER_TIME_CREATED_FIELD, aron::typenavigator::LongNavigatorPtr(new aron::typenavigator::LongNavigator()));
-        typeWrapped->addMemberType(DISK_READER_WRITER_TIME_SENT_FIELD, aron::typenavigator::LongNavigatorPtr(new aron::typenavigator::LongNavigator()));
-        typeWrapped->addMemberType(DISK_READER_WRITER_TIME_ARRIVED_FIELD, aron::typenavigator::LongNavigatorPtr(new aron::typenavigator::LongNavigator()));
-        typeWrapped->addMemberType(DISK_READER_WRITER_CONFIDENCE_FIELD, aron::typenavigator::DoubleNavigatorPtr(new aron::typenavigator::DoubleNavigator()));
-
-        return typeWrapped;
-    }
-
-    bool DiskWriter::directoryPathExists(const std::filesystem::path& p) const
-    {
-        return std::filesystem::exists(p) && std::filesystem::is_directory(p);
-    }
-
-    bool DiskWriter::ensureDirectoryPathExists(const std::filesystem::path& p) const
-    {
-        if (!std::filesystem::exists(p))
-        {
-            return std::filesystem::create_directory(p);
-        }
-        return directoryPathExists(p);
-    }
-
-    bool DiskWriter::filePathExists(const std::filesystem::path& p) const
-    {
-        return std::filesystem::exists(p) && std::filesystem::is_regular_file(p);
-    }
-
-
-    io::DiskWriterReturnInformation::DiskWriterReturnInformation(const std::string& m) :
-        memoryName(m)
-    {
-    }
-
-    void io::DiskWriterReturnInformation::append(const io::DiskWriterReturnInformation& o)
-    {
-        if (memoryName != o.memoryName)
-        {
-            // The memory name must be equal
-            return;
-        }
-
-        storedElements.merge(o.storedElements);
-
-        coreSegmentsError.insert(coreSegmentsError.end(), o.coreSegmentsError.begin(), o.coreSegmentsError.end());
-        providerSegmentsError.insert(providerSegmentsError.end(), o.providerSegmentsError.begin(), o.providerSegmentsError.end());
-        entitiesError.insert(entitiesError.end(), o.entitiesError.begin(), o.entitiesError.end());
-        historyTimestampsError.insert(historyTimestampsError.end(), o.historyTimestampsError.begin(), o.historyTimestampsError.end());
-        entityInstancesError.insert(entityInstancesError.end(), o.entityInstancesError.begin(), o.entityInstancesError.end());
-    }
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskWriter/DiskWriter.h b/source/RobotAPI/libraries/armem/core/io/DiskWriter/DiskWriter.h
deleted file mode 100644
index c8b4e4541e341e23bab18f45cb956620178771c8..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskWriter/DiskWriter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <memory>
-#include <string>
-#include <filesystem>
-
-// ArmarX
-#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/Navigator.h>
-#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
-
-
-// BaseClass
-#include "../DiskReaderWriter.h"
-#include "../FileSystemLookupMemory.h"
-
-#include <RobotAPI/libraries/armem/core/Memory.h>
-
-
-namespace armarx::armem::io
-{
-    struct DiskWriterReturnInformation;
-
-
-    class DiskWriter;
-    using DiskWriterPtr = std::shared_ptr<DiskWriter>;
-
-    class DiskWriter : virtual public DiskReaderWriter
-    {
-    public:
-
-        using DiskReaderWriter::DiskReaderWriter;
-
-        DiskWriterReturnInformation writeOnDisk(const Memory& m);
-        DiskWriterReturnInformation writeOnDisk(const MemoryID&, const CoreSegment&);
-        DiskWriterReturnInformation writeOnDisk(const MemoryID&, const ProviderSegment&);
-        DiskWriterReturnInformation writeOnDisk(const MemoryID&, const Entity&);
-        DiskWriterReturnInformation writeOnDisk(const MemoryID&, const EntitySnapshot&);
-
-    protected:
-        aron::datanavigator::DictNavigatorPtr wrapData(const EntityInstance& e) const;
-        aron::typenavigator::ObjectNavigatorPtr wrapType(const aron::typenavigator::ObjectNavigatorPtr&) const;
-
-        virtual std::string getDataAsString(const aron::datanavigator::DictNavigatorPtr&) const = 0;
-        virtual std::string getTypeAsString(const aron::typenavigator::ObjectNavigatorPtr&) const = 0;
-
-        bool directoryPathExists(const std::filesystem::path& p) const;
-        bool ensureDirectoryPathExists(const std::filesystem::path& p) const;
-
-        bool filePathExists(const std::filesystem::path& p) const;
-    };
-
-
-    struct DiskWriterReturnInformation
-    {
-        std::string memoryName = "";
-        bool hasError = false;
-
-        FileSystemLookupMemory storedElements;
-        std::vector<std::string> coreSegmentsError;
-        std::vector<std::string> providerSegmentsError;
-        std::vector<std::string> entitiesError;
-        std::vector<std::string> historyTimestampsError;
-        std::vector<std::string> entityInstancesError;
-
-        DiskWriterReturnInformation(const std::string& m);
-
-        void append(const DiskWriterReturnInformation& o);
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.cpp b/source/RobotAPI/libraries/armem/core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.cpp
deleted file mode 100644
index a52253d8cdfe867195e3f595832746a7e312f0fc..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "NlohmannJSONDiskWriter.h"
-
-#include <RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h>
-#include <RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h>
-#include <RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h>
-
-
-namespace armarx::armem::io
-{
-    NlohmannJSONDiskWriter::NlohmannJSONDiskWriter(bool createFolder) :
-        DiskReaderWriter(createFolder),
-        DiskWriter(createFolder)
-    {
-    }
-
-    NlohmannJSONDiskWriter::NlohmannJSONDiskWriter(const std::string& rootPath, bool createFolder) :
-        DiskReaderWriter(rootPath, createFolder),
-        DiskWriter(rootPath, createFolder)
-    {
-    }
-
-    std::string NlohmannJSONDiskWriter::getDataAsString(const aron::datanavigator::DictNavigatorPtr& aronDataNav) const
-    {
-        aron::dataIO::writer::NlohmannJSONWriter dataWriter;
-        aron::dataIO::Visitor::SetupWriterFromAronDataPtr(dataWriter, aronDataNav->getResult());
-        return dataWriter.getResult().dump(2);
-    }
-
-    std::string NlohmannJSONDiskWriter::getTypeAsString(const aron::typenavigator::ObjectNavigatorPtr& aronTypeNav) const
-    {
-        aron::typeIO::writer::NlohmannJSONWriter typeWriter;
-        aron::typeIO::Visitor::SetupWriterFromAronTypePtr(typeWriter, aronTypeNav->getResult());
-        return typeWriter.getResult().dump(2);
-    }
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.h b/source/RobotAPI/libraries/armem/core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.h
deleted file mode 100644
index 67d35f01aa874f3c203d4ffffd5bd5691b237bb0..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <memory>
-#include <string>
-
-// Base Class
-#include "../DiskWriter.h"
-
-
-namespace armarx::armem::io
-{
-    class NlohmannJSONDiskWriter;
-    using NlohmannJSONDiskWriterPtr = std::shared_ptr<NlohmannJSONDiskWriter>;
-
-    class NlohmannJSONDiskWriter : virtual public DiskWriter
-    {
-    public:
-        NlohmannJSONDiskWriter(bool createFolder);
-        NlohmannJSONDiskWriter(const std::string& rootPath, bool createFolder);
-
-
-    protected:
-        std::string getDataAsString(const aron::datanavigator::DictNavigatorPtr&) const override;
-        std::string getTypeAsString(const aron::typenavigator::ObjectNavigatorPtr&) const override;
-
-        std::string getEntityInstanceSuffix() const override
-        {
-            return ".data.json";
-        }
-
-        std::string getTypeSuffix() const override
-        {
-            return ".type.json";
-        }
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/FileSystemLookupMemory.cpp b/source/RobotAPI/libraries/armem/core/io/FileSystemLookupMemory.cpp
deleted file mode 100644
index ea9dc07dd048426f3cf4d57fa22790b27b15921d..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/FileSystemLookupMemory.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#include "FileSystemLookupMemory.h"
-
-
-namespace armarx::armem::io
-{
-
-    DiskMemory FileSystemLookupMemory::getDiskMemory(const std::string& n) const
-    {
-        if (!hasMemory(n))
-        {
-            throw error::ArMemError("Could not find a memory with name '" + n + "' in lookup memory.");
-        }
-        return memoryLookupTable.at(n);
-    }
-
-    DiskMemory FileSystemLookupMemory::getDiskMemory(const MemoryID& id) const
-    {
-        if (!hasMemory(id))
-        {
-            throw error::InvalidMemoryID(id, "MemoryName does not exist in lookup memory.");
-        }
-        return memoryLookupTable.at(id.memoryName);
-    }
-
-    DiskCoreSegment FileSystemLookupMemory::getDiskCoreSegment(const MemoryID& id) const
-    {
-        if (!hasCoreSegment(id))
-        {
-            throw error::InvalidMemoryID(id, "CoreSegmentName does not exist in lookup memory.");
-        }
-        return getDiskMemory(id).at(id.coreSegmentName);
-    }
-
-    DiskProviderSegment FileSystemLookupMemory::getDiskProviderSegment(const MemoryID& id) const
-    {
-        if (!hasProviderSegment(id))
-        {
-            throw error::InvalidMemoryID(id, "ProviderSegmentName does not exist in lookup memory.");
-        }
-        return getDiskCoreSegment(id).at(id.providerSegmentName);
-    }
-
-    DiskEntity FileSystemLookupMemory::getDiskEntity(const MemoryID& id) const
-    {
-        if (!hasEntity(id))
-        {
-            throw error::InvalidMemoryID(id, "EntityName does not exist in lookup memory.");
-        }
-        return getDiskProviderSegment(id).at(id.entityName);
-    }
-
-    DiskEntitySnapshot FileSystemLookupMemory::getDiskEntitySnapshot(const MemoryID& id) const
-    {
-        if (!hasEntitySnapshot(id))
-        {
-            throw error::InvalidMemoryID(id, "EntitySnapshotTimestamp does not exist in lookup memory.");
-        }
-        return getDiskEntity(id).at(id.timestamp);
-    }
-
-    DiskEntityInstance FileSystemLookupMemory::getDiskEntityInstance(const MemoryID& id) const
-    {
-        if (!hasEntityInstance(id))
-        {
-            throw error::InvalidMemoryID(id, "EntityInstanceIndex does not exist in lookup memory.");
-        }
-        return getDiskEntitySnapshot(id).at(id.instanceIndex);
-    }
-
-
-    bool FileSystemLookupMemory::hasMemory(const std::string& n) const
-    {
-        MemoryID id;
-        id.memoryName = n;
-        return hasMemory(id);
-    }
-
-    bool FileSystemLookupMemory::hasMemory(const MemoryID& id) const
-    {
-        return id.hasMemoryName() && memoryLookupTable.find(id.memoryName) != memoryLookupTable.end();
-    }
-
-    bool FileSystemLookupMemory::hasCoreSegment(const MemoryID& id) const
-    {
-        if (hasMemory(id))
-        {
-            const auto& m = getDiskMemory(id);
-            return id.hasCoreSegmentName() && m.find(id.coreSegmentName) != m.end();
-        }
-        return false;
-    }
-
-    bool FileSystemLookupMemory::hasProviderSegment(const MemoryID& id) const
-    {
-        if (hasCoreSegment(id))
-        {
-            const auto& m = getDiskCoreSegment(id);
-            return id.hasProviderSegmentName() && m.find(id.providerSegmentName) != m.end();
-        }
-        return false;
-    }
-
-    bool FileSystemLookupMemory::hasEntity(const MemoryID& id) const
-    {
-        if (hasProviderSegment(id))
-        {
-            const auto& m = getDiskProviderSegment(id);
-            return id.hasEntityName() && m.find(id.entityName) != m.end();
-        }
-        return false;
-    }
-
-    bool FileSystemLookupMemory::hasEntitySnapshot(const MemoryID& id) const
-    {
-        if (hasEntity(id))
-        {
-            const auto& m = getDiskEntity(id);
-            return id.hasTimestamp() && m.find(id.timestamp) != m.end();
-        }
-        return false;
-    }
-
-    bool FileSystemLookupMemory::hasEntityInstance(const MemoryID& id) const
-    {
-        if (hasEntitySnapshot(id))
-        {
-            const auto& m = getDiskEntitySnapshot(id);
-            return id.hasInstanceIndex() && m.size() >= (size_t) id.instanceIndex;
-        }
-        return false;
-    }
-
-
-    void FileSystemLookupMemory::merge(const FileSystemLookupMemory& m)
-    {
-        for (const auto& [memoryName, memory] : m.memoryLookupTable)
-        {
-            if (memoryLookupTable.find(memoryName) == memoryLookupTable.end())
-            {
-                memoryLookupTable[memoryName] = memory;
-                continue;
-            }
-
-            DiskMemory& lutMemory = memoryLookupTable[memoryName];
-            for (const auto& [coreKey, coreSegment] : memory)
-            {
-                if (lutMemory.find(coreKey) == lutMemory.end())
-                {
-                    lutMemory[coreKey] = coreSegment;
-                    continue;
-                }
-
-                DiskCoreSegment& lutCoreSegment = lutMemory[coreKey];
-                for (const auto& [providerKey, providerSegment] : coreSegment)
-                {
-                    if (lutCoreSegment.find(providerKey) == lutCoreSegment.end())
-                    {
-                        lutCoreSegment[providerKey] = providerSegment;
-                        continue;
-                    }
-
-                    DiskProviderSegment& lutProviderSegment = lutCoreSegment[providerKey];
-                    for (const auto& [entityKey, entity] : providerSegment)
-                    {
-                        if (lutProviderSegment.find(entityKey) == lutProviderSegment.end())
-                        {
-                            lutProviderSegment[entityKey] = entity;
-                            continue;
-                        }
-
-                        DiskEntity& lutEntity = lutProviderSegment[entityKey];
-                        for (const auto& [entityHistoryTimestamp, entitySnapshot] : entity)
-                        {
-                            if (lutEntity.find(entityHistoryTimestamp) == lutEntity.end())
-                            {
-                                lutEntity[entityHistoryTimestamp] = entitySnapshot;
-                                continue;
-                            }
-
-                            DiskEntitySnapshot& lutEntitySnapshot = lutEntity[entityHistoryTimestamp];
-                            //for (unsigned int i = 0; i < entitySnapshot.size(); ++i)
-                            //{
-                            //    // clear internal stored memory of that snapshot
-                            //    internalMemoryEntitySnapshot.clear();
-                            //    internalMemoryEntitySnapshot.push_back(entitySnapshot[i]);
-                            //}
-                            // for now, simply overwrite all values since one history timestamp should not have two different snapshots
-                            lutEntitySnapshot = entitySnapshot;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/FileSystemLookupMemory.h b/source/RobotAPI/libraries/armem/core/io/FileSystemLookupMemory.h
deleted file mode 100644
index c3aa952f6e7895221db20f157f6fee83796722ea..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/FileSystemLookupMemory.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <filesystem>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "../Time.h"
-#include "../Memory.h"
-#include "../error.h"
-
-
-namespace armarx::armem::io
-{
-    using DiskEntityInstance = std::filesystem::path; // absolute paths to stored files
-    using DiskEntitySnapshot = std::vector<DiskEntityInstance>;
-    using DiskEntity = std::map<Time, DiskEntitySnapshot>;
-    using DiskProviderSegment = std::map<std::string, DiskEntity>;
-    using DiskCoreSegment = std::map<std::string, DiskProviderSegment>;
-    using DiskMemory = std::map<std::string, DiskCoreSegment>;
-
-
-    class FileSystemLookupMemory
-    {
-    public:
-        FileSystemLookupMemory() = default;
-        void merge(const FileSystemLookupMemory& m);
-
-        DiskMemory getDiskMemory(const std::string&) const;
-        DiskMemory getDiskMemory(const MemoryID&) const;
-        DiskCoreSegment getDiskCoreSegment(const MemoryID&) const;
-        DiskProviderSegment getDiskProviderSegment(const MemoryID&) const;
-        DiskEntity getDiskEntity(const MemoryID&) const;
-        DiskEntitySnapshot getDiskEntitySnapshot(const MemoryID&) const;
-        DiskEntityInstance getDiskEntityInstance(const MemoryID&) const;
-
-        bool hasMemory(const std::string&) const;
-        bool hasMemory(const MemoryID&) const;
-        bool hasCoreSegment(const MemoryID&) const;
-        bool hasProviderSegment(const MemoryID&) const;
-        bool hasEntity(const MemoryID&) const;
-        bool hasEntitySnapshot(const MemoryID&) const;
-        bool hasEntityInstance(const MemoryID&) const;
-
-        std::map<std::string, DiskMemory> memoryLookupTable;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.cpp b/source/RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.cpp
deleted file mode 100644
index d39acab1af52a9ed4ec40b01d887a9168960df80..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include "MemoryFileSystemStorage.h"
-
-#include <RobotAPI/libraries/aron/core/Debug.h>
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-namespace armarx::armem::io
-{
-    FileSystemMemoryManager::FileSystemMemoryManager(const std::filesystem::path& rootPath, bool createFolder) :
-        FileSystemMemoryManager(std::make_shared<io::NlohmannJSONDiskWriter>(rootPath, createFolder),
-                                std::make_shared<io::NlohmannJSONDiskReader>(rootPath, createFolder))
-    {
-    }
-
-    FileSystemMemoryManager::FileSystemMemoryManager(const io::DiskWriterPtr& w, const io::DiskReaderPtr& r) :
-        writer(w),
-        reader(r)
-    {
-    }
-
-    void FileSystemMemoryManager::writeOnDisk(const Memory& m)
-    {
-        io::DiskWriterReturnInformation info = writer->writeOnDisk(m);
-        merge(info.storedElements);
-    }
-
-    void FileSystemMemoryManager::writeOnDisk(const MemoryID& id, const CoreSegment& s)
-    {
-        io::DiskWriterReturnInformation info = writer->writeOnDisk(id, s);
-        merge(info.storedElements);
-    }
-
-    void FileSystemMemoryManager::writeOnDisk(const MemoryID& id, const ProviderSegment& s)
-    {
-        io::DiskWriterReturnInformation info = writer->writeOnDisk(id, s);
-        merge(info.storedElements);
-    }
-
-    void FileSystemMemoryManager::writeOnDisk(const MemoryID& id, const Entity& s)
-    {
-        io::DiskWriterReturnInformation info = writer->writeOnDisk(id, s);
-        merge(info.storedElements);
-    }
-
-    void FileSystemMemoryManager::writeOnDisk(const MemoryID& id, const EntitySnapshot& s)
-    {
-        io::DiskWriterReturnInformation info = writer->writeOnDisk(id, s);
-        merge(info.storedElements);
-    }
-
-    Memory FileSystemMemoryManager::readMemoryFromDisk(const std::string& n) const
-    {
-        MemoryID id;
-        id.memoryName = n;
-        return readMemoryFromDisk(id);
-    }
-
-    Memory FileSystemMemoryManager::readMemoryFromDisk(const MemoryID& _id) const
-    {
-        if (!_id.hasMemoryName())
-        {
-            throw error::InvalidMemoryID(_id, "MemoryName is missing.");
-        }
-        Memory ret(_id.memoryName);
-        if (internalMemory.hasMemory(_id))
-        {
-            MemoryID id = _id.getMemoryID();
-            for (const auto& [coreKey, _] : internalMemory.getDiskMemory(_id))
-            {
-                id.coreSegmentName = coreKey;
-                CoreSegment s = readCoreSegmentFromDisk(id);
-                ret.addCoreSegment(s);
-            }
-        }
-        return ret;
-    }
-
-    CoreSegment FileSystemMemoryManager::readCoreSegmentFromDisk(const MemoryID& _id) const
-    {
-        if (!_id.hasCoreSegmentName())
-        {
-            throw error::InvalidMemoryID(_id, "CoreSegmentName is missing.");
-        }
-
-        CoreSegment ret(_id.coreSegmentName);
-        if (internalMemory.hasCoreSegment(_id))
-        {
-            MemoryID id = _id.getCoreSegmentID();
-            for (const auto& [providerKey, _] : internalMemory.getDiskCoreSegment(_id))
-            {
-                id.providerSegmentName = providerKey;
-                ProviderSegment s = readProviderSegmentFromDisk(id);
-                ret.addProviderSegment(s);
-            }
-        }
-        return ret;
-    }
-
-    ProviderSegment FileSystemMemoryManager::readProviderSegmentFromDisk(const MemoryID& _id) const
-    {
-        if (!_id.hasProviderSegmentName())
-        {
-            throw error::InvalidMemoryID(_id, "ProviderSegmentName is missing.");
-        }
-
-        ProviderSegment ret(_id.providerSegmentName);
-        if (internalMemory.hasProviderSegment(_id))
-        {
-            MemoryID id = _id.getProviderSegmentID();
-            for (const auto& [entityKey, _] : internalMemory.getDiskProviderSegment(_id))
-            {
-                id.entityName = entityKey;
-                Entity s = readEntityFromDisk(id);
-                ret.addEntity(s);
-            }
-        }
-        return ret;
-    }
-
-    Entity FileSystemMemoryManager::readEntityFromDisk(const MemoryID& _id) const
-    {
-        if (!_id.hasEntityName())
-        {
-            throw error::InvalidMemoryID(_id, "EntityName is missing.");
-        }
-
-        Entity ret(_id.entityName);
-        if (internalMemory.hasEntity(_id))
-        {
-            MemoryID id = _id.getEntityID();
-            for (const auto& [ts, _] : internalMemory.getDiskEntity(_id))
-            {
-                id.timestamp = ts;
-                EntitySnapshot s = readEntitySnapshotFromDisk(id);
-                ret.addSnapshot(s);
-            }
-        }
-        return ret;
-    }
-
-    EntitySnapshot FileSystemMemoryManager::readEntitySnapshotFromDisk(const MemoryID& _id) const
-    {
-        if (!_id.hasTimestamp())
-        {
-            throw error::InvalidMemoryID(_id, "Timestamp is missing.");
-        }
-
-        EntitySnapshot ret(_id.timestamp);
-        if (internalMemory.hasEntitySnapshot(_id))
-        {
-            MemoryID id = _id.getEntitySnapshotID();
-            for (unsigned int i = 0; i < internalMemory.getDiskEntitySnapshot(_id).size(); ++i)
-            {
-                id.instanceIndex = static_cast<int>(i);
-                EntityInstance s = readEntityInstanceFromDisk(id);
-                ret.addInstance(s);
-            }
-        }
-        return ret;
-    }
-
-    EntityInstance FileSystemMemoryManager::readEntityInstanceFromDisk(const MemoryID& _id) const
-    {
-        if (!_id.hasInstanceIndex())
-        {
-            throw error::InvalidMemoryID(_id, "InstanceIndex is missing.");
-        }
-
-        EntityInstance ret(_id.instanceIndex);
-        if (internalMemory.hasEntityInstance(_id))
-        {
-            aron::typenavigator::ObjectNavigatorPtr typeInformation = readClosestTypeInformation(_id);
-            const DiskEntityInstance& path = internalMemory.getDiskEntityInstance(_id);
-            return reader->readSingleInstanceFromDisk(path, typeInformation);
-        }
-        return ret;
-    }
-
-    aron::typenavigator::ObjectNavigatorPtr FileSystemMemoryManager::readClosestTypeInformation(const MemoryID& _id) const
-    {
-        if (_id.hasInstanceIndex())
-        {
-            aron::typenavigator::ObjectNavigatorPtr t = reader->readSingleTypeInformationFromDisk(_id);
-            if (t != nullptr)
-            {
-                return t;
-            }
-        }
-        if (_id.hasTimestamp())
-        {
-            MemoryID id = _id.getEntitySnapshotID();
-            aron::typenavigator::ObjectNavigatorPtr t = reader->readSingleTypeInformationFromDisk(id);
-            if (t != nullptr)
-            {
-                return t;
-            }
-        }
-        if (_id.hasEntityName())
-        {
-            MemoryID id = _id.getEntityID();
-            aron::typenavigator::ObjectNavigatorPtr t = reader->readSingleTypeInformationFromDisk(id);
-            if (t != nullptr)
-            {
-                return t;
-            }
-        }
-        if (_id.hasProviderSegmentName())
-        {
-            MemoryID id = _id.getProviderSegmentID();
-            aron::typenavigator::ObjectNavigatorPtr t = reader->readSingleTypeInformationFromDisk(id);
-            if (t != nullptr)
-            {
-                return t;
-            }
-        }
-        if (_id.hasCoreSegmentName())
-        {
-            MemoryID id = _id.getCoreSegmentID();
-            aron::typenavigator::ObjectNavigatorPtr t = reader->readSingleTypeInformationFromDisk(id);
-            if (t != nullptr)
-            {
-                return t;
-            }
-        }
-        if (_id.hasMemoryName())
-        {
-            MemoryID id = _id.getMemoryID();
-            aron::typenavigator::ObjectNavigatorPtr t = reader->readSingleTypeInformationFromDisk(id);
-            if (t != nullptr)
-            {
-                return t;
-            }
-        }
-
-        return nullptr;
-    }
-
-    void FileSystemMemoryManager::update()
-    {
-        FileSystemLookupMemory up = reader->readMemoryStructureFromDisk();
-        merge(up);
-    }
-
-    std::string FileSystemMemoryManager::toString()
-    {
-        std::stringstream ss;
-        std::string tabs = "";
-        for (const auto& [memoryName, memory] : internalMemory.memoryLookupTable)
-        {
-            ss << memoryName << ": " << std::endl;
-            std::string tabs = "\t";
-            for (const auto& [coreKey, coreSegment] : memory)
-            {
-                ss << tabs << coreKey << ": " << std::endl;
-                std::string tabs = "\t\t";
-                for (const auto& [providerKey, providerSegment] : coreSegment)
-                {
-                    ss << tabs << providerKey << ": " << std::endl;
-                    std::string tabs = "\t\t\t";
-                    for (const auto& [entityKey, entity] : providerSegment)
-                    {
-                        ss << tabs << entityKey << ": " << std::endl;
-                        std::string tabs = "\t\t\t\t";
-                        for (const auto& [entityHistoryTimestamp, entitySnapshot] : entity)
-                        {
-                            ss << tabs << entityHistoryTimestamp.toMicroSeconds() << ":" << std::endl;
-                            ss << tabs << "[" << std::endl;
-                            for (unsigned int i = 0; i < entitySnapshot.size(); ++i)
-                            {
-                                const std::string& newlyGenerate = entitySnapshot[i];
-                                ss << tabs << "\t(" << i << " => " << newlyGenerate << ")";
-                                if (i < entitySnapshot.size() - 1)
-                                {
-                                    ss << ", ";
-                                }
-                                ss << std::endl;
-                            }
-                            ss << tabs << "]" << std::endl;
-                        }
-                    }
-                }
-            }
-        }
-        return ss.str();
-    }
-
-    void FileSystemMemoryManager::merge(const FileSystemLookupMemory& info)
-    {
-        internalMemory.merge(info);
-    }
-}
diff --git a/source/RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.h b/source/RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.h
deleted file mode 100644
index 9f44bb7a037aeed8dcf32acda6c5b8374514c45c..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-* This file is part of ArmarX.
-*
-* ArmarX is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* ArmarX is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* @author     Fabian Peller (fabian dot peller at kit dot edu)
-* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
-*             GNU General Public License
-*/
-
-#pragma once
-
-// STD/STL
-#include <filesystem>
-#include <string>
-#include <utility>  // std::pair
-
-// ArmarX
-#include <RobotAPI/interface/aron.h>
-
-#include "DiskWriter/DiskWriter.h"
-#include "DiskWriter/NlohmannJSONDiskWriter/NlohmannJSONDiskWriter.h"
-#include "DiskReader/DiskReader.h"
-#include "DiskReader/NlohmannJSONDiskReader/NlohmannJSONDiskReader.h"
-
-
-namespace armarx::armem::io
-{
-    class FileSystemMemoryManager
-    {
-    public:
-        FileSystemMemoryManager() = delete;
-        FileSystemMemoryManager(const std::filesystem::path& rootPath, bool createFolder = false);
-        FileSystemMemoryManager(const io::DiskWriterPtr&, const io::DiskReaderPtr&);
-
-        void writeOnDisk(const Memory& memory);
-        void writeOnDisk(const MemoryID& coreSegmentID, const CoreSegment& coreSegment);
-        void writeOnDisk(const MemoryID& providerSegmentID, const ProviderSegment& providerSegment);
-        void writeOnDisk(const MemoryID& entityID, const Entity& entity);
-        // void writeOnDisk(const MemoryID&, const Entity&, aron::typenavigator::ObjectNavigatorPtr = nullptr);
-        void writeOnDisk(const MemoryID& entitySnapshotID, const EntitySnapshot& entitySnapshot);
-
-        void update();
-        void merge(const FileSystemLookupMemory& info);
-
-        Memory readMemoryFromDisk(const std::string& memoryName) const;
-        Memory readMemoryFromDisk(const MemoryID& memoryID) const;
-        CoreSegment readCoreSegmentFromDisk(const MemoryID& coreSegmentID) const;
-        ProviderSegment readProviderSegmentFromDisk(const MemoryID& providerSegmentID) const;
-        Entity readEntityFromDisk(const MemoryID& entityID) const;
-        EntitySnapshot readEntitySnapshotFromDisk(const MemoryID& entitySnapshotID) const;
-        EntityInstance readEntityInstanceFromDisk(const MemoryID& entityInstanceID) const;
-
-        aron::typenavigator::ObjectNavigatorPtr readClosestTypeInformation(const MemoryID&) const;
-
-        //std::pair<Entity, aron::typenavigator::ObjectNavigatorPtr> readTypedEntityFromDisk();
-        //std::pair<EntitySnapshot, aron::typenavigator::ObjectNavigatorPtr> readTypedEntitySnapshotFromDisk();
-
-        std::string toString();
-
-    private:
-        FileSystemLookupMemory internalMemory;
-
-        DiskWriterPtr writer;
-        DiskReaderPtr reader;
-    };
-}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/CoreSegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6bebc718e499ed311d3090aacd3dd6b71bc5078f
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/CoreSegment.cpp
@@ -0,0 +1,71 @@
+#include "CoreSegment.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::ltm
+{
+
+    CoreSegment::CoreSegment()
+    {
+    }
+
+    CoreSegment::CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withCoreSegmentName(name)),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(MemoryID().withCoreSegmentName(name), aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withCoreSegmentName(name)),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(parentID.withCoreSegmentName(name), aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(id),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(id, aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const CoreSegment& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, ProviderSegment>, CoreSegment>(other),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(other)
+    {
+    }
+
+    CoreSegment& CoreSegment::operator=(const CoreSegment& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    wm::CoreSegment CoreSegment::convert() const
+    {
+        wm::CoreSegment m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addProviderSegment(s.convert());
+        }
+        return m;
+    }
+
+    void CoreSegment::append(const wm::CoreSegment& m)
+    {
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.append(s);
+            }
+            else
+            {
+                auto wms = _container.emplace(std::make_pair(k, id().withCoreSegmentName(k)));
+                wms.first->second.append(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/CoreSegment.h b/source/RobotAPI/libraries/armem/core/longtermmemory/CoreSegment.h
new file mode 100644
index 0000000000000000000000000000000000000000..59bb7830d66e1b5ec2e15c904ae967a93534b8a3
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/CoreSegment.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "../base/CoreSegmentBase.h"
+
+#include "ProviderSegment.h"
+
+#include "../workingmemory/CoreSegment.h"
+
+
+namespace armarx::armem::ltm
+{
+
+    /**
+     * @brief Data of a core segment containing multiple provider segments.
+     */
+    class CoreSegment :
+        virtual public base::CoreSegmentBase<ProviderSegment, CoreSegment>
+    {
+        using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>;
+
+    public:
+        CoreSegment();
+        CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+
+        CoreSegment(const CoreSegment& other);
+        CoreSegment& operator=(const CoreSegment& other);
+
+        // Conversion
+        wm::CoreSegment convert() const;
+
+        // MongoDB connection
+        void append(const wm::CoreSegment&);
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..30c578d82a61a556720cb7089d033dc9120a16c8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp
@@ -0,0 +1,57 @@
+#include "Entity.h"
+
+namespace armarx::armem::ltm
+{
+
+    Entity::Entity()
+    {
+    }
+
+    Entity::Entity(const std::string& name, const MemoryID& parentID) :
+        base::detail::MemoryItem(parentID.withEntityName(name))
+    {
+    }
+
+    Entity::Entity(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    Entity::Entity(const Entity& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<Time, EntitySnapshot>, Entity>(other)
+    {
+    }
+
+    Entity& Entity::operator=(const Entity& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    wm::Entity Entity::convert() const
+    {
+        wm::Entity m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addSnapshot(s.convert());
+        }
+        return m;
+    }
+
+    void Entity::append(const wm::Entity& m)
+    {
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.setTo(s);
+            }
+            else
+            {
+                auto wms = _container.emplace(std::make_pair(k, id().withTimestamp(k)));
+                wms.first->second.setTo(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h
new file mode 100644
index 0000000000000000000000000000000000000000..79d81340e35381228ffa8875c8723a349bdb4035
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "../base/EntityBase.h"
+
+#include "EntitySnapshot.h"
+
+#include "../workingmemory/Entity.h"
+
+
+namespace armarx::armem::ltm
+{
+    /**
+     * @brief An entity over a period of time.
+     *
+     * An entity should be a physical thing or abstract concept existing
+     * (and potentially evolving) over some time.
+     *
+     * Examples are:
+     * - objects (the green box)
+     * - agents (robot, human)
+     * - locations (frige, sink)
+     * - grasp affordances (general, or for a specific object)
+     * - images
+     * - point clouds
+     * - other sensory values
+     *
+     * At each point in time (`EntitySnapshot`), the entity can have a
+     * (potentially variable) number of instances (`EntityInstance`),
+     * each containing a single `AronData` object of a specific `AronType`.
+     */
+    class Entity :
+        virtual public base::EntityBase<EntitySnapshot, Entity>
+    {
+        using Base = base::EntityBase<EntitySnapshot, Entity>;
+
+    public:
+        Entity();
+        Entity(const std::string& name, const MemoryID& parentID = {});
+        Entity(const MemoryID& id);
+
+        /// Copy the history from `other` to this.
+        Entity(const Entity& other);
+        /// Copy the history from `other` to this.
+        Entity& operator=(const Entity& other);
+
+        // Conversion
+        wm::Entity convert() const;
+
+        // MongoDB connection
+        void append(const wm::Entity&);
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/EntityInstance.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/EntityInstance.cpp
similarity index 54%
rename from source/RobotAPI/libraries/armem/core/EntityInstance.cpp
rename to source/RobotAPI/libraries/armem/core/longtermmemory/EntityInstance.cpp
index 416e56d740acb7701557e8ade3b98a4d1eb410b4..17535db36fda2e165df2e7a41489193699ac4754 100644
--- a/source/RobotAPI/libraries/armem/core/EntityInstance.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntityInstance.cpp
@@ -2,27 +2,46 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-
-namespace armarx::armem
+namespace armarx::armem::ltm
 {
 
+    bool EntityInstanceMetadata::operator==(const EntityInstanceMetadata& other) const
+    {
+        return timeCreated == other.timeCreated
+               && timeSent == other.timeSent
+               && timeArrived == other.timeArrived
+               && std::abs(confidence - other.confidence) < 1e-6f;
+    }
+
     EntityInstance::EntityInstance()
     {
     }
 
+    EntityInstance::EntityInstance(const EntityInstance& other) :
+        MemoryItem(other.id()),
+        _metadata(other._metadata)
+    {
+    }
+
     EntityInstance::EntityInstance(int index, const MemoryID& parentID) :
         EntityInstance(parentID.withInstanceIndex(index))
     {
     }
 
-    EntityInstance::EntityInstance(const MemoryID& id) : MemoryItem(id)
+    EntityInstance::EntityInstance(const MemoryID& id) :
+        base::detail::MemoryItem(id)
     {
     }
 
+    EntityInstance& EntityInstance::operator=(const EntityInstance& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
 
     bool EntityInstance::equalsDeep(const EntityInstance& other) const
     {
-        return _metadata == other.metadata() && _data->equalsDeep(other.data());
+        return id() == other.id() && _metadata == other.metadata();
     }
 
     void EntityInstance::update(const EntityUpdate& update, int index)
@@ -30,43 +49,34 @@ namespace armarx::armem
         ARMARX_CHECK_FITS_SIZE(index, update.instancesData.size());
 
         this->index() = index;
-        setData(update.instancesData.at(size_t(index)));
 
         this->_metadata.confidence = update.confidence;
-
         this->_metadata.timeCreated = update.timeCreated;
         this->_metadata.timeSent = update.timeSent;
         this->_metadata.timeArrived = update.timeArrived;
     }
 
-    EntityInstance EntityInstance::copy(bool withData) const
+    EntityInstance EntityInstance::copy() const
     {
-        EntityInstance other(id());
-        other._metadata = _metadata;
-        if (withData)
-        {
-            other.setData(_data);
-        }
-        return other;
+        EntityInstance d;
+        this->_copySelf(d);
+        return d;
     }
 
-    std::string EntityInstance::getKeyString() const
+    void EntityInstance::_copySelf(EntityInstance& other) const
     {
-        return std::to_string(index());
+        EntityInstanceBase<EntityInstance>::_copySelf(other);
+        other._metadata = _metadata;
     }
 
-    std::string EntityInstance::getLevelName() const
+    wm::EntityInstance EntityInstance::convert() const
     {
-        return "entity instance";
+        wm::EntityInstance m;
+        return m;
     }
 
-
-    bool EntityInstanceMetadata::operator==(const EntityInstanceMetadata& other) const
+    void EntityInstance::setTo(const wm::EntityInstance& m)
     {
-        return timeCreated == other.timeCreated
-               && timeSent == other.timeSent
-               && timeArrived == other.timeArrived
-               && std::abs(confidence - other.confidence) < 1e-6f;
+        ARMARX_IMPORTANT << "Longtermmemory received an entity instance: " << m.id().str();
     }
-
 }
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/EntityInstance.h b/source/RobotAPI/libraries/armem/core/longtermmemory/EntityInstance.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee94fbfbbe9e79dd74916612e49a4a6eee0b90cc
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntityInstance.h
@@ -0,0 +1,84 @@
+#pragma once
+
+#include "../base/EntityInstanceBase.h"
+
+#include "../workingmemory/EntityInstance.h"
+
+namespace armarx::armem::ltm
+{
+
+    /**
+     * @brief Metadata of an entity instance.
+     */
+    struct EntityInstanceMetadata
+    {
+        /// Time when this value was created.
+        Time timeCreated;
+        /// Time when this value was sent to the memory.
+        Time timeSent;
+        /// Time when this value has arrived at the memory.
+        Time timeArrived;
+
+        /// An optional confidence, may be used for things like decay.
+        float confidence = 1.0;
+
+
+        bool operator==(const EntityInstanceMetadata& other) const;
+        inline bool operator!=(const EntityInstanceMetadata& other) const
+        {
+            return !(*this == other);
+        }
+    };
+
+    /**
+     * @brief Data of a single entity instance.
+     */
+    class EntityInstance :
+        virtual public base::EntityInstanceBase<EntityInstance>
+    {
+        using Base = base::EntityInstanceBase<EntityInstance>;
+
+    public:
+        EntityInstance();
+        EntityInstance(const EntityInstance&);
+        EntityInstance(int index, const MemoryID& parentID = {});
+        EntityInstance(const MemoryID& id);
+
+        EntityInstance& operator=(const EntityInstance& other);
+
+        EntityInstanceMetadata& metadata()
+        {
+            return _metadata;
+        }
+        inline const EntityInstanceMetadata& metadata() const
+        {
+            return _metadata;
+        }
+
+
+        /**
+         * @brief Fill `*this` with the update's values.
+         * @param update The update.
+         * @param index The instances index.
+         */
+        virtual void update(const EntityUpdate& update, int index) override;
+
+        virtual bool equalsDeep(const EntityInstance& other) const override;
+
+        virtual EntityInstance copy() const override;
+
+        // Conversion
+        wm::EntityInstance convert() const;
+
+        // MongoDB connection
+        void setTo(const wm::EntityInstance&);
+
+    protected:
+        virtual void _copySelf(EntityInstance& other) const override;
+
+
+    private:
+        /// The metadata.
+        EntityInstanceMetadata _metadata;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f3272eb9ba94c5751ea0b2d4f1c0893802eb0d6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.cpp
@@ -0,0 +1,60 @@
+#include "EntitySnapshot.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::ltm
+{
+
+
+    EntitySnapshot::EntitySnapshot()
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(Time time, const MemoryID& parentID) :
+        EntitySnapshot(parentID.withTimestamp(time))
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(const MemoryID& id) :
+        MemoryItem(id)
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(const EntitySnapshot& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::vector<EntityInstance>, EntitySnapshot>(other)
+    {
+    }
+
+    EntitySnapshot& EntitySnapshot::operator=(const EntitySnapshot& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    wm::EntitySnapshot EntitySnapshot::convert() const
+    {
+        wm::EntitySnapshot m;
+        for (const auto& s : _container)
+        {
+            m.addInstance(s.convert());
+        }
+        return m;
+    }
+
+    void EntitySnapshot::setTo(const wm::EntitySnapshot& m)
+    {
+        // We remove the contente here and reset it with new values
+        _container.clear();
+
+        int i = 0;
+        for (const auto& s : m.container())
+        {
+            auto wms = _container.emplace_back(id().withInstanceIndex(i++));
+            wms.setTo(s);
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8c3f491dc8b87979856786abe931ab1fc7eaeb7
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/EntitySnapshot.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "../base/EntitySnapshotBase.h"
+
+#include "EntityInstance.h"
+
+#include "../workingmemory/EntitySnapshot.h"
+
+
+namespace armarx::armem::ltm
+{
+
+    /**
+     * @brief Data of an entity at one point in time.
+     */
+    class EntitySnapshot :
+        virtual public base::EntitySnapshotBase<EntityInstance, EntitySnapshot>
+    {
+        using Base = base::EntitySnapshotBase<EntityInstance, EntitySnapshot>;
+
+    public:
+        EntitySnapshot();
+        EntitySnapshot(Time time, const MemoryID& parentID = {});
+        EntitySnapshot(const MemoryID& id);
+
+        /// Copy the instances from `other` to this.
+        EntitySnapshot(const EntitySnapshot& other);
+
+        /// Copy the instances from `other` to this.
+        EntitySnapshot& operator=(const EntitySnapshot& other);
+
+        // Conversion
+        wm::EntitySnapshot convert() const;
+
+        // MongoDB connection
+        void setTo(const wm::EntitySnapshot&);
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f216cb0338fc9ff8b7f47fa430acf99bf0cb92c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
@@ -0,0 +1,70 @@
+#include "Memory.h"
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::ltm
+{
+
+    Memory::Memory()
+    {
+    }
+
+    Memory::Memory(const std::string& name) :
+        base::detail::MemoryItem(MemoryID().withMemoryName(name))
+    {
+    }
+
+    Memory::Memory(const MemoryID& id) :
+        MemoryItem(id)
+    {
+    }
+
+    Memory::Memory(const Memory& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, CoreSegment>, Memory>(other)
+    {
+        *this = other;
+    }
+
+    Memory& Memory::operator=(const Memory& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    wm::Memory Memory::convert() const
+    {
+        wm::Memory m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addCoreSegment(s.convert());
+        }
+        return m;
+    }
+
+    void Memory::reload(const MongoDBConnectionManager::MongoDBSettings& settings)
+    {
+        dbsettings = settings;
+        std::cout << "Setting connection to: " << settings.uniqueString() << std::endl;
+    }
+
+    void Memory::append(const wm::Memory& m)
+    {
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.append(s);
+            }
+            else
+            {
+                auto wms = _container.emplace(std::make_pair(k, id().withCoreSegmentName(k)));
+                wms.first->second.append(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..1085de776eda6ac8e913d24c840b867a7fef969d
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "../base/MemoryBase.h"
+
+#include "CoreSegment.h"
+
+#include "../workingmemory/Memory.h"
+#include "mongodb/MongoDBConnectionManager.h"
+
+namespace armarx::armem::ltm
+{
+    /**
+     * @brief Data of a memory consisting of multiple core segments.
+     */
+    class Memory :
+        virtual public base::MemoryBase<CoreSegment, Memory>
+    {
+        using Base = base::MemoryBase<CoreSegment, Memory>;
+
+    public:
+        Memory();
+        Memory(const std::string& name);
+        Memory(const MemoryID& id);
+
+        Memory(const Memory& other);
+        Memory& operator=(const Memory& other);
+
+
+        // Conversion
+        wm::Memory convert() const;
+
+        // MongoDB connection
+        void reload(const MongoDBConnectionManager::MongoDBSettings&);
+        void append(const wm::Memory&);
+
+
+    public:
+        MongoDBConnectionManager::MongoDBSettings dbsettings;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/ProviderSegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dbdbdb1189fd2efdac397992b3cad480da77f863
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/ProviderSegment.cpp
@@ -0,0 +1,71 @@
+#include "ProviderSegment.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::ltm
+{
+
+    ProviderSegment::ProviderSegment()
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withProviderSegmentName(name)),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(MemoryID().withProviderSegmentName(name), aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(parentID.withProviderSegmentName(name)),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(parentID.withProviderSegmentName(name), aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(id),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(id, aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const ProviderSegment& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, Entity>, ProviderSegment>(other),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(other)
+    {
+    }
+
+    ProviderSegment& ProviderSegment::operator=(const ProviderSegment& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    wm::ProviderSegment ProviderSegment::convert() const
+    {
+        wm::ProviderSegment m;
+        for (const auto& [_, s] : _container)
+        {
+            m.addEntity(s.convert());
+        }
+        return m;
+    }
+
+    void ProviderSegment::append(const wm::ProviderSegment& m)
+    {
+        for (const auto& [k, s] : m.container())
+        {
+            if (const auto& it = _container.find(k); it != _container.end())
+            {
+                it->second.append(s);
+            }
+            else
+            {
+                auto wms = _container.emplace(std::make_pair(k, id().withEntityName(k)));
+                wms.first->second.append(s);
+            }
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/ProviderSegment.h b/source/RobotAPI/libraries/armem/core/longtermmemory/ProviderSegment.h
new file mode 100644
index 0000000000000000000000000000000000000000..5ac77dad663e34a3b3da6d39c53629d6a9415864
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/ProviderSegment.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "../base/ProviderSegmentBase.h"
+
+#include "Entity.h"
+
+#include "../workingmemory/ProviderSegment.h"
+
+
+namespace armarx::armem::ltm
+{
+
+    /**
+     * @brief Data of a provider segment containing multiple entities.
+     */
+    class ProviderSegment :
+        virtual public base::ProviderSegmentBase<Entity, ProviderSegment>
+    {
+        using Base = base::ProviderSegmentBase<Entity, ProviderSegment>;
+
+    public:
+        ProviderSegment();
+        ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+
+        ProviderSegment(const ProviderSegment& other);
+        ProviderSegment& operator=(const ProviderSegment& other);
+
+        // Conversion
+        wm::ProviderSegment convert() const;
+
+        // MongoDB connection
+        void append(const wm::ProviderSegment&);
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h b/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..02c25965f9c6ae0c12f528c9e2a5c241a10a26d3
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include <map>
+#include <memory>
+
+namespace armarx::armem::ltm
+{
+
+    /**
+     * @brief Data of a memory consisting of multiple core segments.
+     */
+    class MongoDBConnectionManager
+    {
+    public:
+        struct MongoDBSettings
+        {
+            std::string host = "localhost";
+            std::string user = "root";
+            std::string password = "";
+
+            bool isSet() const
+            {
+                // we always need a user and a host
+                return !host.empty() and !user.empty();
+            }
+
+            std::string uniqueString() const
+            {
+                return host + "::" + user;
+            }
+        };
+
+        static int EstablishConnection(const MongoDBSettings& settings)
+        {
+            const auto str_rep = settings.uniqueString();
+            const auto& it = Connections.find(str_rep);
+            if (it == Connections.end())
+            {
+                auto con = Connections.emplace(str_rep, 0);
+                return con.first->second;
+            }
+            else
+            {
+                // A connection already exists. We do not need to open another one.
+                return it->second;
+            }
+        }
+
+    private:
+        static std::map<std::string, int> Connections;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ef52fd749f9106d4ea1e9204fd0574392c18387
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.cpp
@@ -0,0 +1,61 @@
+#include "CoreSegment.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::wm
+{
+
+    CoreSegment::CoreSegment()
+    {
+    }
+
+    CoreSegment::CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withCoreSegmentName(name)),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(MemoryID().withCoreSegmentName(name), aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withCoreSegmentName(name)),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(parentID.withCoreSegmentName(name), aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(id),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(id, aronType)
+    {
+    }
+
+    CoreSegment::CoreSegment(const CoreSegment& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, ProviderSegment>, CoreSegment>(other),
+        base::detail::TypedEntityContainerBase<ProviderSegment, Entity, CoreSegment>(other)
+    {
+    }
+
+    CoreSegment& CoreSegment::operator=(const CoreSegment& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    CoreSegment CoreSegment::copyWithoutData() const
+    {
+        CoreSegment m;
+        _copySelfWithoutData(m);
+        return m;
+    }
+
+    void CoreSegment::_copySelfWithoutData(CoreSegment& o) const
+    {
+        detail::TypedEntityContainer<ProviderSegment, CoreSegment>::_copySelfWithoutData(o);
+        for (const auto& [k, s] : o)
+        {
+            o.addProviderSegment(s.copyWithoutData());
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h
new file mode 100644
index 0000000000000000000000000000000000000000..d727b408bb9672afdbf842d742f27e889ea96489
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "../base/CoreSegmentBase.h"
+
+#include "ProviderSegment.h"
+#include "detail/TypedEntityContainer.h"
+
+
+namespace armarx::armem::wm
+{
+
+    /**
+     * @brief Data of a core segment containing multiple provider segments.
+     */
+    class CoreSegment :
+        virtual public base::CoreSegmentBase<ProviderSegment, CoreSegment>,
+        virtual public detail::TypedEntityContainer<ProviderSegment, CoreSegment>
+    {
+        using Base = base::CoreSegmentBase<ProviderSegment, CoreSegment>;
+
+    public:
+        CoreSegment();
+        CoreSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        CoreSegment(const std::string& name, const MemoryID& parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        CoreSegment(const MemoryID& id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+
+        CoreSegment(const CoreSegment& other);
+        CoreSegment& operator=(const CoreSegment& other);
+
+        CoreSegment copyWithoutData() const override;
+
+    protected:
+        virtual void _copySelfWithoutData(CoreSegment& o) const override;
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..37b930656d8810ea0445c412d8992c23db2458aa
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.cpp
@@ -0,0 +1,47 @@
+#include "Entity.h"
+
+namespace armarx::armem::wm
+{
+
+    Entity::Entity()
+    {
+    }
+
+    Entity::Entity(const std::string& name, const MemoryID& parentID) :
+        base::detail::MemoryItem(parentID.withEntityName(name))
+    {
+    }
+
+    Entity::Entity(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    Entity::Entity(const Entity& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<Time, EntitySnapshot>, Entity>(other)
+    {
+    }
+
+    Entity& Entity::operator=(const Entity& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    Entity Entity::copyWithoutData() const
+    {
+        Entity m;
+        _copySelfWithoutData(m);
+        return m;
+    }
+
+    void Entity::_copySelfWithoutData(Entity& o) const
+    {
+        detail::MemoryContainer<std::map<Time, EntitySnapshot>, Entity>::_copySelfWithoutData(o);
+        for (const auto& [k, s] : o)
+        {
+            o.addSnapshot(s.copyWithoutData());
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d213e92f0d6756e90cf9fd7090f472ce52effa5
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/Entity.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "../base/EntityBase.h"
+
+#include "EntitySnapshot.h"
+#include "detail/MemoryContainer.h"
+
+
+namespace armarx::armem::wm
+{
+    /**
+     * @brief An entity over a period of time.
+     *
+     * An entity should be a physical thing or abstract concept existing
+     * (and potentially evolving) over some time.
+     *
+     * Examples are:
+     * - objects (the green box)
+     * - agents (robot, human)
+     * - locations (frige, sink)
+     * - grasp affordances (general, or for a specific object)
+     * - images
+     * - point clouds
+     * - other sensory values
+     *
+     * At each point in time (`EntitySnapshot`), the entity can have a
+     * (potentially variable) number of instances (`EntityInstance`),
+     * each containing a single `AronData` object of a specific `AronType`.
+     */
+    class Entity :
+        virtual public base::EntityBase<EntitySnapshot, Entity>,
+        virtual public detail::MemoryContainer<std::map<Time, EntitySnapshot>, Entity>
+    {
+        using Base = base::EntityBase<EntitySnapshot, Entity>;
+
+    public:
+        Entity();
+        Entity(const std::string& name, const MemoryID& parentID = {});
+        Entity(const MemoryID& id);
+
+        /// Copy the history from `other` to this.
+        Entity(const Entity& other);
+        /// Copy the history from `other` to this.
+        Entity& operator=(const Entity& other);
+
+        Entity copyWithoutData() const override;
+
+    protected:
+        virtual void _copySelfWithoutData(Entity& o) const override;
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cc2aed88a9dd43f326cde8cc8448bbee466369b0
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.cpp
@@ -0,0 +1,91 @@
+#include "EntityInstance.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+
+namespace armarx::armem::wm
+{
+
+    bool EntityInstanceMetadata::operator==(const EntityInstanceMetadata& other) const
+    {
+        return timeCreated == other.timeCreated
+               && timeSent == other.timeSent
+               && timeArrived == other.timeArrived
+               && std::abs(confidence - other.confidence) < 1e-6f;
+    }
+
+    EntityInstance::EntityInstance()
+    {
+    }
+
+    EntityInstance::EntityInstance(const EntityInstance& other) :
+        base::detail::MemoryItem(other.id()),
+        _metadata(other._metadata),
+        _data(other._data)
+    {
+    }
+
+    EntityInstance::EntityInstance(int index, const MemoryID& parentID) :
+        EntityInstance(parentID.withInstanceIndex(index))
+    {
+    }
+
+    EntityInstance::EntityInstance(const MemoryID& id) :
+        base::detail::MemoryItem(id)
+    {
+    }
+
+    EntityInstance& EntityInstance::operator=(const EntityInstance& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+
+    bool EntityInstance::equalsDeep(const EntityInstance& other) const
+    {
+        return id() == other.id()
+               && _metadata == other.metadata()
+               && _data->equalsDeep(other.data());
+    }
+
+    void EntityInstance::update(const EntityUpdate& update, int index)
+    {
+        ARMARX_CHECK_FITS_SIZE(index, update.instancesData.size());
+
+        this->index() = index;
+        setData(update.instancesData.at(size_t(index)));
+
+        this->_metadata.confidence = update.confidence;
+
+        this->_metadata.timeCreated = update.timeCreated;
+        this->_metadata.timeSent = update.timeSent;
+        this->_metadata.timeArrived = update.timeArrived;
+    }
+
+    EntityInstance EntityInstance::copy() const
+    {
+        EntityInstance d;
+        this->_copySelf(d);
+        return d;
+    }
+
+    EntityInstance EntityInstance::copyWithoutData() const
+    {
+        EntityInstance d;
+        this->_copySelfWithoutData(d);
+        return d;
+    }
+
+    void EntityInstance::_copySelf(EntityInstance& other) const
+    {
+        EntityInstanceBase<EntityInstance>::_copySelf(other);
+        other._metadata = _metadata;
+        other._data = _data;
+    }
+
+    void EntityInstance::_copySelfWithoutData(EntityInstance& other) const
+    {
+        EntityInstanceBase<EntityInstance>::_copySelf(other);
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/EntityInstance.h b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h
similarity index 68%
rename from source/RobotAPI/libraries/armem/core/EntityInstance.h
rename to source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h
index 25311339e6429d62b4f7de77476804a553574a7f..cbfe38200b129cdcbd32819560fda6cfb2cbdaa0 100644
--- a/source/RobotAPI/libraries/armem/core/EntityInstance.h
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h
@@ -1,15 +1,8 @@
 #pragma once
 
-#include <RobotAPI/interface/aron.h>
-#include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
+#include "../base/EntityInstanceBase.h"
 
-#include "../core/Time.h"
-
-#include "Commit.h"
-#include "detail/MemoryItem.h"
-
-
-namespace armarx::armem
+namespace armarx::armem::wm
 {
 
     /**
@@ -35,27 +28,21 @@ namespace armarx::armem
         }
     };
 
-
     /**
      * @brief Data of a single entity instance.
      */
-    class EntityInstance : public detail::MemoryItem
+    class EntityInstance :
+        virtual public base::EntityInstanceBase<EntityInstance>
     {
-    public:
+        using Base = base::EntityInstanceBase<EntityInstance>;
 
+    public:
         EntityInstance();
+        EntityInstance(const EntityInstance&);
         EntityInstance(int index, const MemoryID& parentID = {});
         EntityInstance(const MemoryID& id);
 
-
-        inline int& index()
-        {
-            return id().instanceIndex;
-        }
-        inline int index() const
-        {
-            return id().instanceIndex;
-        }
+        EntityInstance& operator=(const EntityInstance& other);
 
         EntityInstanceMetadata& metadata()
         {
@@ -70,6 +57,7 @@ namespace armarx::armem
         {
             return _data;
         }
+
         void setData(const aron::datanavigator::DictNavigatorPtr& data)
         {
             this->_data = data;
@@ -81,28 +69,23 @@ namespace armarx::armem
          * @param update The update.
          * @param index The instances index.
          */
-        void update(const EntityUpdate& update, int index);
+        virtual void update(const EntityUpdate& update, int index) override;
 
+        virtual bool equalsDeep(const EntityInstance& other) const override;
 
-        EntityInstance copy(bool withData = true) const;
+        virtual EntityInstance copy() const override;
+        virtual EntityInstance copyWithoutData() const;
 
-        bool equalsDeep(const EntityInstance& other) const;
-
-
-        // MemoryItem interface
-    public:
-        std::string getKeyString() const override;
-        std::string getLevelName() const override;
+    protected:
+        virtual void _copySelf(EntityInstance& other) const override;
+        virtual void _copySelfWithoutData(EntityInstance& other) const;
 
 
     private:
-
         /// The metadata.
         EntityInstanceMetadata _metadata;
 
         /// The data. May be nullptr.
         armarx::aron::datanavigator::DictNavigatorPtr _data;
-
     };
-
 }
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c33dd71b23b3c2c16c4b95894af63b46485d8ca2
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.cpp
@@ -0,0 +1,57 @@
+#include "EntitySnapshot.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::wm
+{
+
+
+    EntitySnapshot::EntitySnapshot()
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(Time time, const MemoryID& parentID) :
+        EntitySnapshot(parentID.withTimestamp(time))
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(const MemoryID& id) :
+        MemoryItem(id)
+    {
+    }
+
+    EntitySnapshot::~EntitySnapshot()
+    {
+    }
+
+    EntitySnapshot::EntitySnapshot(const EntitySnapshot& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::vector<EntityInstance>, EntitySnapshot>(other)
+    {
+    }
+
+    EntitySnapshot& EntitySnapshot::operator=(const EntitySnapshot& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    EntitySnapshot EntitySnapshot::copyWithoutData() const
+    {
+        EntitySnapshot m;
+        _copySelfWithoutData(m);
+        return m;
+    }
+
+    void EntitySnapshot::_copySelfWithoutData(EntitySnapshot& o) const
+    {
+        detail::MemoryContainer<std::vector<EntityInstance>, EntitySnapshot>::_copySelfWithoutData(o);
+        for (const auto& s : o)
+        {
+            o.addInstance(s.copyWithoutData());
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h
new file mode 100644
index 0000000000000000000000000000000000000000..50332bf163f4b4595b0e53b64f3acf3497f3332c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/EntitySnapshot.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "../base/EntitySnapshotBase.h"
+
+#include "EntityInstance.h"
+#include "detail/MemoryContainer.h"
+
+
+namespace armarx::armem::wm
+{
+
+    /**
+     * @brief Data of an entity at one point in time.
+     */
+    class EntitySnapshot :
+        virtual public base::EntitySnapshotBase<EntityInstance, EntitySnapshot>,
+        virtual public detail::MemoryContainer<std::vector<EntityInstance>, EntitySnapshot>
+    {
+        using Base = base::EntitySnapshotBase<EntityInstance, EntitySnapshot>;
+
+    public:
+
+        EntitySnapshot();
+        EntitySnapshot(Time time, const MemoryID& parentID = {});
+        EntitySnapshot(const MemoryID& id);
+
+        virtual ~EntitySnapshot() override;
+
+
+        /// Copy the instances from `other` to this.
+        EntitySnapshot(const EntitySnapshot& other);
+
+        /// Copy the instances from `other` to this.
+        EntitySnapshot& operator=(const EntitySnapshot& other);
+
+        EntitySnapshot copyWithoutData() const override;
+
+
+    protected:
+
+        virtual void _copySelfWithoutData(EntitySnapshot& o) const override;
+
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a5b1e4ab1346ed3b3d041320c4eade4d31176ced
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.cpp
@@ -0,0 +1,54 @@
+#include "Memory.h"
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::wm
+{
+
+    Memory::Memory()
+    {
+    }
+
+    Memory::Memory(const std::string& name) :
+        base::detail::MemoryItem(MemoryID().withMemoryName(name))
+    {
+    }
+
+    Memory::Memory(const MemoryID& id) :
+        MemoryItem(id)
+    {
+    }
+
+    Memory::Memory(const Memory& other) :
+        base::detail::MemoryItem(other),
+        MemoryContainerBase<std::map<std::string, CoreSegment>, Memory>(other)
+    {
+        *this = other;
+    }
+
+    Memory& Memory::operator=(const Memory& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    Memory Memory::copyWithoutData() const
+    {
+        Memory m;
+        _copySelfWithoutData(m);
+        return m;
+    }
+
+    void Memory::_copySelfWithoutData(Memory& o) const
+    {
+        detail::EntityContainer<CoreSegment, Memory>::_copySelfWithoutData(o);
+        for (const auto& [k, s] : o)
+        {
+            o.addCoreSegment(s.copyWithoutData());
+        }
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..d747ded5ef9618a9c4a2c891c493e3816c15a851
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/Memory.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "../base/MemoryBase.h"
+
+#include "CoreSegment.h"
+#include "detail/EntityContainer.h"
+
+namespace armarx::armem::wm
+{
+
+    /**
+     * @brief Data of a memory consisting of multiple core segments.
+     */
+    class Memory :
+        virtual public base::MemoryBase<CoreSegment, Memory>,
+        virtual public detail::EntityContainer<CoreSegment, Memory>
+    {
+        using Base = base::MemoryBase<CoreSegment, Memory>;
+
+    public:
+        Memory();
+        Memory(const std::string& name);
+        Memory(const MemoryID& id);
+
+        Memory(const Memory& other);
+        Memory& operator=(const Memory& other);
+
+        Memory copyWithoutData() const override;
+
+    protected:
+        virtual void _copySelfWithoutData(Memory& o) const override;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b90c745c53a60c5d95feda1adc131c300d61beb
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.cpp
@@ -0,0 +1,62 @@
+#include "ProviderSegment.h"
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "error.h"
+
+
+namespace armarx::armem::wm
+{
+
+    ProviderSegment::ProviderSegment()
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(MemoryID().withProviderSegmentName(name)),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(MemoryID().withProviderSegmentName(name), aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(parentID.withProviderSegmentName(name)),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(parentID.withProviderSegmentName(name), aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType) :
+        base::detail::MemoryItem(id),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(id, aronType)
+    {
+    }
+
+    ProviderSegment::ProviderSegment(const ProviderSegment& other) :
+        base::detail::MemoryItem(other),
+        base::detail::MemoryContainerBase<std::map<std::string, Entity>, ProviderSegment>(other),
+        base::detail::TypedEntityContainerBase<Entity, Entity, ProviderSegment>(other)
+    {
+    }
+
+    ProviderSegment& ProviderSegment::operator=(const ProviderSegment& other)
+    {
+        other._copySelf(*this);
+        return *this;
+    }
+
+    ProviderSegment ProviderSegment::copyWithoutData() const
+    {
+        ProviderSegment m;
+        _copySelfWithoutData(m);
+        return m;
+    }
+
+    void ProviderSegment::_copySelfWithoutData(ProviderSegment& o) const
+    {
+        detail::TypedEntityContainer<Entity, ProviderSegment>::_copySelfWithoutData(o);
+        for (const auto& [k, s] : o)
+        {
+            o.addEntity(s.copyWithoutData());
+        }
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h
new file mode 100644
index 0000000000000000000000000000000000000000..542ec3dc5ee0fc2dcbbface02bf11006eaa497a1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "../base/ProviderSegmentBase.h"
+
+#include "Entity.h"
+#include "detail/TypedEntityContainer.h"
+
+
+namespace armarx::armem::wm
+{
+
+    /**
+     * @brief Data of a provider segment containing multiple entities.
+     */
+    class ProviderSegment :
+        virtual public base::ProviderSegmentBase<Entity, ProviderSegment>,
+        virtual public detail::TypedEntityContainer<Entity, ProviderSegment>
+    {
+        using Base = base::ProviderSegmentBase<Entity, ProviderSegment>;
+
+    public:
+        ProviderSegment();
+        ProviderSegment(const std::string& name, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        ProviderSegment(const std::string& name, const MemoryID parentID, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        ProviderSegment(const MemoryID id, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+
+        ProviderSegment(const ProviderSegment& other);
+        ProviderSegment& operator=(const ProviderSegment& other);
+
+        ProviderSegment copyWithoutData() const override;
+
+    protected:
+        virtual void _copySelfWithoutData(ProviderSegment& o) const override;
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/detail/EntityContainer.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/detail/EntityContainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20872a805368246aca047563e0094b055568e8db
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/detail/EntityContainer.cpp
@@ -0,0 +1 @@
+#include "EntityContainer.h"
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/detail/EntityContainer.h b/source/RobotAPI/libraries/armem/core/workingmemory/detail/EntityContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..431d13624ab3f004020d13ba77c3fdf4a60c380d
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/detail/EntityContainer.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "../../base/detail/EntityContainerBase.h"
+#include "MemoryContainer.h"
+
+#include "../Entity.h"
+#include "../EntitySnapshot.h"
+#include "../EntityInstance.h"
+
+
+namespace armarx::armem::wm::detail
+{
+
+    /**
+     * @brief A container of entities at some point in the hierarchy.
+     *
+     * Can be updated by multiple entity updates.
+     */
+    template <class _ValueT, class _Derived>
+    class EntityContainer :
+        virtual public base::detail::EntityContainerBase<_ValueT, Entity, _Derived>,
+        virtual public MemoryContainer<std::map<std::string, _ValueT>, _Derived>
+    {
+    public:
+        EntityContainer& operator=(const EntityContainer& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/detail/MemoryContainer.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/detail/MemoryContainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..733cd6f240a52944d6c18fb60bab928242b5b122
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/detail/MemoryContainer.cpp
@@ -0,0 +1 @@
+#include "MemoryContainer.h"
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/detail/MemoryContainer.h b/source/RobotAPI/libraries/armem/core/workingmemory/detail/MemoryContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..a915c8714a299ab18a671c18814c77441d6b28af
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/detail/MemoryContainer.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include "../../error.h"
+
+#include "../../base/detail/MemoryContainerBase.h"
+
+
+namespace armarx::armem::wm::detail
+{
+
+    /**
+     * @class Provides default implmentations of `MemoryContainer`, as well as
+     * iterators (which requires a template).
+     */
+    template <class _ContainerT, class _Derived>
+    class MemoryContainer :
+        virtual public base::detail::MemoryContainerBase<_ContainerT, _Derived>
+    {
+        using Base = base::detail::MemoryContainerBase<_ContainerT, _Derived>;
+
+    public:
+        MemoryContainer& operator=(const MemoryContainer& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+
+        // Copying
+        virtual _Derived copyWithoutData() const
+        {
+            _Derived t;
+            _copySelfWithoutData(t);
+            return t;
+        }
+
+    protected:
+        virtual void _copySelfWithoutData(_Derived& o) const
+        {
+            Base::_copySelfEmpty(o);
+        }
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/detail/TypedEntityContainer.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/detail/TypedEntityContainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7bec77f349c1e45f7a434d499a5a8b1c952b3317
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/detail/TypedEntityContainer.cpp
@@ -0,0 +1 @@
+#include "TypedEntityContainer.h"
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/detail/TypedEntityContainer.h b/source/RobotAPI/libraries/armem/core/workingmemory/detail/TypedEntityContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..f90925ff1de57a63542dd70adadff1e762224783
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/detail/TypedEntityContainer.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "../../base/detail/TypedEntityContainerBase.h"
+#include "EntityContainer.h"
+
+#include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
+
+namespace armarx::armem::wm::detail
+{
+
+    /**
+     * @brief An entity container with a specific (Aron) type.
+     */
+    template <class _ValueT, class _Derived>
+    class TypedEntityContainer :
+        virtual public base::detail::TypedEntityContainerBase<_ValueT, Entity, _Derived>,
+        virtual public EntityContainer<_ValueT, _Derived>
+    {
+    public:
+        TypedEntityContainer& operator=(const TypedEntityContainer& other)
+        {
+            other._copySelf(*this);
+            return *this;
+        }
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp b/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7dded894331809986a991351f0eb7c7675b11812
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.cpp
@@ -0,0 +1,124 @@
+#include "ice_conversions.h"
+
+namespace armarx::armem
+{
+    void toIce(armarx::armem::data::EntityInstanceMetadata& ice, const armarx::armem::wm::EntityInstanceMetadata& metadata)
+    {
+        ice.confidence = metadata.confidence;
+        toIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
+        toIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
+        toIce(ice.timeSentMicroSeconds, metadata.timeSent);
+    }
+    void fromIce(const armarx::armem::data::EntityInstanceMetadata& ice, armarx::armem::wm::EntityInstanceMetadata& metadata)
+    {
+        metadata.confidence = ice.confidence;
+        fromIce(ice.timeArrivedMicroSeconds, metadata.timeArrived);
+        fromIce(ice.timeCreatedMicroSeconds, metadata.timeCreated);
+        fromIce(ice.timeSentMicroSeconds, metadata.timeSent);
+    }
+
+    void toIce(data::EntityInstance& ice, const wm::EntityInstance& data)
+    {
+        detail::toIceItem(ice, data);
+
+        if (data.data())
+        {
+            ice.data = data.data()->toAronDictPtr();
+        }
+        toIce(ice.metadata, data.metadata());
+    }
+    void fromIce(const data::EntityInstance& ice, wm::EntityInstance& data)
+    {
+        detail::fromIceItem(ice, data);
+
+        if (ice.data)
+        {
+            data.setData(aron::datanavigator::DictNavigator::FromAronDictPtr(ice.data));
+        }
+        fromIce(ice.metadata, data.metadata());
+    }
+
+
+    void toIce(data::EntitySnapshot& ice, const wm::EntitySnapshot& snapshot)
+    {
+        detail::toIceItem(ice, snapshot);
+
+        toIce(ice.instances, snapshot.instances());
+    }
+    void fromIce(const data::EntitySnapshot& ice, wm::EntitySnapshot& snapshot)
+    {
+        detail::fromIceItem(ice, snapshot);
+
+        fromIce(ice.instances, snapshot.instances());
+    }
+
+    void toIce(data::Entity& ice, const wm::Entity& entity)
+    {
+        detail::toIceItem(ice, entity);
+
+        toIce(ice.history, entity.history());
+    }
+    void fromIce(const data::Entity& ice, wm::Entity& entity)
+    {
+        detail::fromIceItem(ice, entity);
+
+        fromIce(ice.history, entity.history());
+    }
+
+
+    void toIce(data::ProviderSegment& ice, const wm::ProviderSegment& providerSegment)
+    {
+        detail::toIceItem(ice, providerSegment);
+
+        if (providerSegment.hasAronType())
+        {
+            ice.aronType = providerSegment.aronType()->getResult();
+        }
+        toIce(ice.entities, providerSegment.entities());
+    }
+    void fromIce(const data::ProviderSegment& ice, wm::ProviderSegment& providerSegment)
+    {
+        detail::fromIceItem(ice, providerSegment);
+
+        if (ice.aronType)
+        {
+            providerSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice.aronType));
+        }
+        fromIce(ice.entities, providerSegment.entities());
+    }
+
+    void toIce(data::CoreSegment& ice, const wm::CoreSegment& coreSegment)
+    {
+        detail::toIceItem(ice, coreSegment);
+
+        if (coreSegment.hasAronType())
+        {
+            ice.aronType = coreSegment.aronType()->getResult();
+        }
+        toIce(ice.providerSegments, coreSegment.providerSegments());
+    }
+    void fromIce(const data::CoreSegment& ice, wm::CoreSegment& coreSegment)
+    {
+        detail::fromIceItem(ice, coreSegment);
+
+        if (ice.aronType)
+        {
+            coreSegment.aronType() = aron::typenavigator::ObjectNavigator::DynamicCastAndCheck(aron::typenavigator::Navigator::FromAronType(ice.aronType));
+        }
+        fromIce(ice.providerSegments, coreSegment.providerSegments());
+    }
+
+    void toIce(data::Memory& ice, const wm::Memory& memory)
+    {
+        detail::toIceItem(ice, memory);
+
+        toIce(ice.coreSegments, memory.coreSegments());
+    }
+    void fromIce(const data::Memory& ice, wm::Memory& memory)
+    {
+        detail::fromIceItem(ice, memory);
+
+        fromIce(ice.coreSegments, memory.coreSegments());
+    }
+
+}
diff --git a/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h b/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d14e6b0d04e9086e701cc38a159e516e533d95c
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/commit.h>
+#include <RobotAPI/interface/armem/memory.h>
+
+#include "Memory.h"
+
+
+namespace armarx::armem
+{
+    void toIce(data::EntityInstanceMetadata& ice, const wm::EntityInstanceMetadata& metadata);
+    void fromIce(const data::EntityInstanceMetadata& ice, wm::EntityInstanceMetadata& metadata);
+
+    void toIce(data::EntityInstance& ice, const wm::EntityInstance& data);
+    void fromIce(const data::EntityInstance& ice, wm::EntityInstance& data);
+
+
+    void toIce(data::EntitySnapshot& ice, const wm::EntitySnapshot& snapshot);
+    void fromIce(const data::EntitySnapshot& ice, wm::EntitySnapshot& snapshot);
+
+    void toIce(data::Entity& ice, const wm::Entity& entity);
+    void fromIce(const data::Entity& ice, wm::Entity& entity);
+
+
+    void toIce(data::ProviderSegment& ice, const wm::ProviderSegment& providerSegment);
+    void fromIce(const data::ProviderSegment& ice, wm::ProviderSegment& providerSegment);
+
+    void toIce(data::CoreSegment& ice, const wm::CoreSegment& coreSegment);
+    void fromIce(const data::CoreSegment& ice, wm::CoreSegment& coreSegment);
+
+    void toIce(data::Memory& ice, const wm::Memory& memory);
+    void fromIce(const data::Memory& ice, wm::Memory& memory);
+}
+
+// Must be included after the prototypes. Otherwise the compiler cannot find the correct methods in ice_coversion_templates.h
+#include "../ice_conversions.h"
diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
index de811a33125e672a0a57e266ef5ca9b59971b083..c5aff2156b36fc76b06920ba82a2db44539b1f19 100644
--- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.cpp
@@ -6,10 +6,10 @@
 
 #include "MemoryToIceAdapter.h"
 
+//#include <RobotAPI/libraries/armem/core/io/diskWriter/NlohmannJSON/NlohmannJSONDiskWriter.h>
 
 namespace armarx::armem::server::plugins
 {
-
     ComponentPlugin::~ComponentPlugin()
     {}
 
@@ -18,17 +18,30 @@ namespace armarx::armem::server::plugins
     {
         ClientPlugin::postCreatePropertyDefinitions(properties);
         properties->topic(memoryListener, this->parent<ComponentPluginUser>().memoryListenerDefaultName);
+
+        properties->optional(longTermMemoryDatabaseHost, this->parent<ComponentPluginUser>().longTermMemoryDatabaseHostDefault);
+        properties->optional(longTermMemoryDatabaseUser, this->parent<ComponentPluginUser>().longTermMemoryDatabaseUserDefault);
+        properties->optional(longTermMemoryDatabasePassword, this->parent<ComponentPluginUser>().longTermMemoryDatabasePasswordDefault);
     }
 
 
     void ComponentPlugin::postOnConnectComponent()
     {
         ComponentPluginUser& parent = this->parent<ComponentPluginUser>();
+
         if (isMemoryNameSystemEnabled() && parent.memoryNameSystem)
         {
             registerMemory(parent);
         }
         parent.iceMemory.setMemoryListener(memoryListener);
+
+        // establishing connection to ltm and mongodb
+        ltm::MongoDBConnectionManager::MongoDBSettings settings;
+        settings.host = longTermMemoryDatabaseHost;
+        settings.user = longTermMemoryDatabaseUser;
+        settings.password = longTermMemoryDatabasePassword;
+
+        parent.longtermmemory.reload(settings);
     }
 
 
@@ -45,7 +58,7 @@ namespace armarx::armem::server::plugins
     data::RegisterMemoryResult ComponentPlugin::registerMemory(ComponentPluginUser& parent)
     {
         data::RegisterMemoryInput input;
-        input.name = parent.memory.name();
+        input.name = parent.workingmemory.name();
         input.proxy = MemoryInterfacePrx::checkedCast(parent.getProxy());
         ARMARX_CHECK_NOT_NULL(input.proxy);
         data::RegisterMemoryResult result = parent.memoryNameSystem->registerMemory(input);
@@ -68,7 +81,7 @@ namespace armarx::armem::server::plugins
         try
         {
             data::RemoveMemoryInput input;
-            input.name = parent.memory.name();
+            input.name = parent.workingmemory.name();
             result = parent.memoryNameSystem->removeMemory(input);
             if (result.success)
             {
@@ -94,7 +107,6 @@ namespace armarx::armem::server::plugins
 
 namespace armarx::armem::server
 {
-
     ComponentPluginUser::ComponentPluginUser()
     {
         addPlugin(plugin);
@@ -102,7 +114,6 @@ namespace armarx::armem::server
 
 
     // WRITING
-
     data::AddSegmentsResult ComponentPluginUser::addSegments(const data::AddSegmentsInput& input, const Ice::Current&)
     {
         bool addCoreSegmentOnUsage = false;
@@ -111,7 +122,7 @@ namespace armarx::armem::server
 
     data::AddSegmentsResult ComponentPluginUser::addSegments(const data::AddSegmentsInput& input, bool addCoreSegments)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(workingmemoryMutex);
         data::AddSegmentsResult result = iceMemory.addSegments(input, addCoreSegments);
         return result;
     }
@@ -119,17 +130,32 @@ namespace armarx::armem::server
 
     data::CommitResult ComponentPluginUser::commit(const data::Commit& commitIce, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(workingmemoryMutex);
         return iceMemory.commit(commitIce);
     }
 
 
     // READING
-
     armem::query::data::Result ComponentPluginUser::query(const armem::query::data::Input& input, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(workingmemoryMutex);
         return iceMemory.query(input);
     }
 
+    // LTM LOADING
+    data::StoreResult ComponentPluginUser::store(const data::StoreInput& input, const Ice::Current&)
+    {
+        std::scoped_lock lock(workingmemoryMutex);
+        std::scoped_lock lock2(longtermmemoryMutex);
+        return iceMemory.store(input);
+    }
+
+
+    // LTM STORING
+    armem::query::data::Result ComponentPluginUser::load(const armem::query::data::Input& input, const Ice::Current&)
+    {
+        std::scoped_lock lock(longtermmemoryMutex);
+        return iceMemory.load(input);
+    }
+
 }
diff --git a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
index ca0958b3c93203ef519c2c5311b71c1b0f54cd98..c051995c4c6790731850bc4294e9dba59155a795 100644
--- a/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
+++ b/source/RobotAPI/libraries/armem/server/ComponentPlugin.h
@@ -8,7 +8,9 @@
 #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
 
-#include "../core/Memory.h"
+#include "../core/workingmemory/Memory.h"
+#include "../core/longtermmemory/Memory.h"
+
 #include "../mns/ClientPlugin.h"
 #include "MemoryToIceAdapter.h"
 
@@ -47,6 +49,10 @@ namespace armarx::armem::server::plugins
         data::RemoveMemoryResult removeMemory(ComponentPluginUser& parent);
 
         client::MemoryListenerInterfacePrx memoryListener;
+
+        std::string longTermMemoryDatabaseHost;
+        std::string longTermMemoryDatabaseUser;
+        std::string longTermMemoryDatabasePassword;
     };
 
 }
@@ -80,24 +86,35 @@ namespace armarx::armem::server
         virtual armem::query::data::Result query(const armem::query::data::Input& input, const Ice::Current& = Ice::emptyCurrent) override;
 
 
-    public:
+        // StoringInterface interface
+        virtual data::StoreResult store(const data::StoreInput&, const Ice::Current& = Ice::emptyCurrent) override;
+
+
+        // LoadingInterface interface
+        virtual armem::query::data::Result load(const armem::query::data::Input&, const Ice::Current& = Ice::emptyCurrent) override;
 
+
+    public:
         /// The actual memory.
-        Memory memory;
-        std::mutex memoryMutex;
+        wm::Memory workingmemory;
+        std::mutex workingmemoryMutex;
+
+        ltm::Memory longtermmemory;
+        std::mutex longtermmemoryMutex;
 
-        /// property defauls
+        /// property defaults
         std::string memoryListenerDefaultName = "MemoryUpdates";
+        std::string longTermMemoryDatabaseHostDefault = "";
+        std::string longTermMemoryDatabaseUserDefault = "";
+        std::string longTermMemoryDatabasePasswordDefault = "";
 
         /// Helps connecting `memory` to ice. Used to handle Ice callbacks.
-        MemoryToIceAdapter iceMemory { &memory };
+        MemoryToIceAdapter iceMemory { &workingmemory, &longtermmemory};
 
 
     private:
-
         plugins::ComponentPlugin* plugin = nullptr;
 
-
     };
 
 
diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
index b2ada310d271e5c9161d2f3f74e12ca16ee66ae6..9ab34efd946541a37ae825d6338a355aec0dd722 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.cpp
@@ -13,16 +13,16 @@
 namespace armarx::armem::server
 {
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const Memory& memory) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::Memory& memory) const
     {
         GroupBox group;
-        group.setLabel(makeGroupLabel("Memory", memory.name(), memory.coreSegments.size()));
+        group.setLabel(makeGroupLabel("Memory", memory.name(), memory.coreSegments().size()));
 
-        if (memory.coreSegments.empty())
+        if (memory.coreSegments().empty())
         {
             group.addChild(Label(makeNoItemsMessage("core segments")));
         }
-        for (const auto& [name, coreSegment] : memory.coreSegments)
+        for (const auto& [name, coreSegment] : memory.coreSegments())
         {
             group.addChild(makeGroupBox(coreSegment));
         }
@@ -32,16 +32,16 @@ namespace armarx::armem::server
 
 
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const CoreSegment& coreSegment) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::CoreSegment& coreSegment) const
     {
         GroupBox group;
-        group.setLabel(makeGroupLabel("Core Segment", coreSegment.name(), coreSegment.providerSegments.size()));
+        group.setLabel(makeGroupLabel("Core Segment", coreSegment.name(), coreSegment.providerSegments().size()));
 
-        if (coreSegment.providerSegments.empty())
+        if (coreSegment.providerSegments().empty())
         {
             group.addChild(Label(makeNoItemsMessage("provider segments")));
         }
-        for (const auto& [name, providerSegment] : coreSegment.providerSegments)
+        for (const auto& [name, providerSegment] : coreSegment.providerSegments())
         {
             group.addChild(makeGroupBox(providerSegment));
         }
@@ -51,16 +51,16 @@ namespace armarx::armem::server
 
 
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const ProviderSegment& providerSegment) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::ProviderSegment& providerSegment) const
     {
         GroupBox group;
-        group.setLabel(makeGroupLabel("Provider Segment", providerSegment.name(), providerSegment.entities.size()));
+        group.setLabel(makeGroupLabel("Provider Segment", providerSegment.name(), providerSegment.entities().size()));
 
-        if (providerSegment.entities.empty())
+        if (providerSegment.entities().empty())
         {
             group.addChild(Label(makeNoItemsMessage("entities")));
         }
-        for (const auto& [name, entity] : providerSegment.entities)
+        for (const auto& [name, entity] : providerSegment.entities())
         {
             group.addChild(makeGroupBox(entity));
         }
@@ -70,18 +70,18 @@ namespace armarx::armem::server
 
 
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const Entity& entity) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::Entity& entity) const
     {
         GroupBox group;
-        group.setLabel(makeGroupLabel("Entity", entity.name(), entity.history.size()));
+        group.setLabel(makeGroupLabel("Entity", entity.name(), entity.history().size()));
 
-        if (entity.history.empty())
+        if (entity.history().empty())
         {
             group.addChild(Label(makeNoItemsMessage("snapshots")));
         }
-        if (int(entity.history.size()) <= maxHistorySize)
+        if (int(entity.history().size()) <= maxHistorySize)
         {
-            for (const auto& [time, snapshot] : entity.history)
+            for (const auto& [time, snapshot] : entity.history())
             {
                 group.addChild(makeGroupBox(snapshot));
             }
@@ -89,8 +89,8 @@ namespace armarx::armem::server
         else
         {
             int margin = 2;
-            auto it = entity.history.begin();
-            auto rit = entity.history.end();
+            auto it = entity.history().begin();
+            auto rit = entity.history().end();
             --rit;
             for (int i = 0; i < margin; ++i, ++it)
             {
@@ -98,7 +98,7 @@ namespace armarx::armem::server
                 --rit;
             }
             group.addChild(Label("..."));
-            for (; rit != entity.history.end(); ++rit)
+            for (; rit != entity.history().end(); ++rit)
             {
                 group.addChild(makeGroupBox(rit->second));
             }
@@ -110,17 +110,17 @@ namespace armarx::armem::server
 
 
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const EntitySnapshot& snapshot) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::EntitySnapshot& snapshot) const
     {
         GroupBox group;
         group.setLabel(makeGroupLabel("t", armem::toDateTimeMilliSeconds(snapshot.time()),
-                                      snapshot.instances.size(), " = ", ""));
+                                      snapshot.instances().size(), " = ", ""));
 
-        if (snapshot.instances.empty())
+        if (snapshot.instances().empty())
         {
             group.addChild(Label(makeNoItemsMessage("instances")));
         }
-        for (const EntityInstance& instance : snapshot.instances)
+        for (const wm::EntityInstance& instance : snapshot.instances())
         {
             group.addChild(makeGroupBox(instance));
         }
@@ -129,7 +129,7 @@ namespace armarx::armem::server
         return group;
     }
 
-    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const EntityInstance& instance) const
+    MemoryRemoteGui::GroupBox MemoryRemoteGui::makeGroupBox(const wm::EntityInstance& instance) const
     {
         GroupBox group;
 
diff --git a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h
index 4ce866f15b52a9c2505f5081adcbe87451695966..f4a7fad95f1efa38d8ad7044d661e77fef60be31 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h
+++ b/source/RobotAPI/libraries/armem/server/MemoryRemoteGui.h
@@ -2,7 +2,7 @@
 
 #include <ArmarXGui/libraries/RemoteGui/Client/Widgets.h>
 
-#include "../core/Memory.h"
+#include "../core/workingmemory/Memory.h"
 
 
 namespace armarx::armem::server
@@ -17,12 +17,12 @@ namespace armarx::armem::server
         using GroupBox = armarx::RemoteGui::Client::GroupBox;
         using Label = armarx::RemoteGui::Client::Label;
 
-        GroupBox makeGroupBox(const Memory& memory) const;
-        GroupBox makeGroupBox(const CoreSegment& coreSegment) const;
-        GroupBox makeGroupBox(const ProviderSegment& providerSegment) const;
-        GroupBox makeGroupBox(const Entity& entity) const;
-        GroupBox makeGroupBox(const EntitySnapshot& entitySnapshot) const;
-        GroupBox makeGroupBox(const EntityInstance& instance) const;
+        GroupBox makeGroupBox(const wm::Memory& memory) const;
+        GroupBox makeGroupBox(const wm::CoreSegment& coreSegment) const;
+        GroupBox makeGroupBox(const wm::ProviderSegment& providerSegment) const;
+        GroupBox makeGroupBox(const wm::Entity& entity) const;
+        GroupBox makeGroupBox(const wm::EntitySnapshot& entitySnapshot) const;
+        GroupBox makeGroupBox(const wm::EntityInstance& instance) const;
 
 
         std::string makeGroupLabel(const std::string& term, const std::string& name, size_t size,
diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
index 0d8bbbc0794b9f78c912b891ebd2d596ce57016a..259c0ca97ed7b8e3c05cac1d878ba2b0164378a3 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp
@@ -3,14 +3,16 @@
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
 #include "../error.h"
-#include "../core/ice_conversions.h"
-#include "query_proc/MemoryQueryProcessor.h"
+#include "../core/workingmemory/ice_conversions.h"
+#include "query_proc/workingmemory/MemoryQueryProcessor.h"
 
+//#include "../core/io/diskWriter/NlohmannJSON/NlohmannJSONDiskWriter.h"
+//#include "../core/io/diskReader/NlohmannJSON/NlohmannJSONDiskReader.h"
 
 namespace armarx::armem::server
 {
 
-    MemoryToIceAdapter::MemoryToIceAdapter(Memory* memory) : memory(memory)
+    MemoryToIceAdapter::MemoryToIceAdapter(wm::Memory* workingmemory, ltm::Memory* longtermmemory) : workingMemory(workingmemory), longtermMemory(longtermmemory)
     {
     }
 
@@ -18,30 +20,29 @@ namespace armarx::armem::server
     void
     MemoryToIceAdapter::setMemoryListener(client::MemoryListenerInterfacePrx memoryListener)
     {
-        this->memoryListener = memoryListener;
+        this->memoryListenerTopic = memoryListener;
     }
 
 
     // WRITING
-
     data::AddSegmentResult
     MemoryToIceAdapter::addSegment(const data::AddSegmentInput& input, bool addCoreSegments)
     {
         ARMARX_DEBUG << "Adding segment '" << input.coreSegmentName << "/" << input.providerSegmentName << "'.";
-        ARMARX_CHECK_NOT_NULL(memory);
+        ARMARX_CHECK_NOT_NULL(workingMemory);
 
         data::AddSegmentResult output;
 
-        armem::CoreSegment* coreSegment = nullptr;
+        armem::wm::CoreSegment* coreSegment = nullptr;
         try
         {
-            coreSegment = &memory->getCoreSegment(input.coreSegmentName);
+            coreSegment = &workingMemory->getCoreSegment(input.coreSegmentName);
         }
         catch (const armem::error::MissingEntry& e)
         {
             if (addCoreSegments)
             {
-                coreSegment = &memory->addCoreSegment(input.coreSegmentName);
+                coreSegment = &workingMemory->addCoreSegment(input.coreSegmentName);
             }
             else
             {
@@ -63,14 +64,14 @@ namespace armarx::armem::server
                 // This is ok.
                 if (input.clearWhenExists)
                 {
-                    ProviderSegment& provider = coreSegment->getProviderSegment(input.providerSegmentName);
+                    wm::ProviderSegment& provider = coreSegment->getProviderSegment(input.providerSegmentName);
                     provider.clear();
                 }
             }
         }
 
         armem::MemoryID segmentID;
-        segmentID.memoryName = memory->name();
+        segmentID.memoryName = workingMemory->name();
         segmentID.coreSegmentName = input.coreSegmentName;
         segmentID.providerSegmentName = input.providerSegmentName;
 
@@ -83,7 +84,7 @@ namespace armarx::armem::server
     data::AddSegmentsResult
     MemoryToIceAdapter::addSegments(const data::AddSegmentsInput& input, bool addCoreSegments)
     {
-        ARMARX_CHECK_NOT_NULL(memory);
+        ARMARX_CHECK_NOT_NULL(workingMemory);
 
         data::AddSegmentsResult output;
         for (const auto& i : input)
@@ -96,7 +97,7 @@ namespace armarx::armem::server
     data::CommitResult
     MemoryToIceAdapter::commit(const data::Commit& commitIce, Time timeArrived)
     {
-        ARMARX_CHECK_NOT_NULL(memory);
+        ARMARX_CHECK_NOT_NULL(workingMemory);
 
         armem::Commit commit;
         armem::fromIce(commitIce, commit, timeArrived);
@@ -120,7 +121,7 @@ namespace armarx::armem::server
     MemoryToIceAdapter::commit(const armem::Commit& commit)
     {
         std::vector<data::MemoryID> updatedIDs;
-        const bool publishUpdates = memoryListener;
+        const bool publishUpdates = memoryListenerTopic;
 
         CommitResult commitResult;
         for (const EntityUpdate& update : commit.updates)
@@ -128,7 +129,7 @@ namespace armarx::armem::server
             EntityUpdateResult& result = commitResult.results.emplace_back();
             try
             {
-                MemoryID snapshotID = memory->update(update);
+                MemoryID snapshotID = workingMemory->update(update);
 
                 result.success = true;
                 result.snapshotID = snapshotID;
@@ -149,7 +150,7 @@ namespace armarx::armem::server
 
         if (publishUpdates)
         {
-            memoryListener->memoryUpdated(updatedIDs);
+            memoryListenerTopic->memoryUpdated(updatedIDs);
         }
 
         return commitResult;
@@ -157,16 +158,48 @@ namespace armarx::armem::server
 
 
     // READING
-
     armem::query::data::Result
     MemoryToIceAdapter::query(const armem::query::data::Input& input)
     {
-        ARMARX_CHECK_NOT_NULL(memory);
+        ARMARX_CHECK_NOT_NULL(workingMemory);
 
-        armem::query_proc::MemoryQueryProcessor processor(
+        armem::wm::query_proc::MemoryQueryProcessor processor(
             input.withData ? armem::DataMode::WithData
             : armem::DataMode::NoData);
-        return processor.process(input, *memory);
+        return processor.process(input, *workingMemory);
+    }
+
+    // LTM LOADING
+    query::data::Result MemoryToIceAdapter::load(const armem::query::data::Input& query)
+    {
+        ARMARX_CHECK_NOT_NULL(longtermMemory);
+        query::data::Result output;
+
+        output.success = true;
+        return output;
+    }
+
+    // LTM STORING
+    data::StoreResult MemoryToIceAdapter::store(const armem::data::StoreInput& input)
+    {
+        ARMARX_CHECK_NOT_NULL(workingMemory);
+        ARMARX_CHECK_NOT_NULL(longtermMemory);
+        data::StoreResult output;
+
+        armem::query::data::Result queryResult = this->query(input.query);
+        if (queryResult.success)
+        {
+            wm::Memory m;
+            fromIce(queryResult.memory, m);
+            longtermMemory->append(m);
+        }
+        else
+        {
+            output.success = false;
+        }
+
+        ARMARX_IMPORTANT << "Finsihed";
+        return output;
     }
 
     client::QueryResult MemoryToIceAdapter::query(const client::QueryInput& input)
diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h
index ac123807142b39e21bb16bdc72157553640a31c1..919c5fc8dc74ec3f742ac1c33365bc2c680ac768 100644
--- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h
+++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.h
@@ -3,7 +3,8 @@
 #include <RobotAPI/interface/armem/server/MemoryInterface.h>
 #include <RobotAPI/interface/armem/client/MemoryListenerInterface.h>
 
-#include <RobotAPI/libraries/armem/core/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
 #include <RobotAPI/libraries/armem/client/Query.h>
 
 
@@ -22,13 +23,12 @@ namespace armarx::armem::server
     public:
 
         /// Construct an MemoryToIceAdapter from an existing Memory.
-        MemoryToIceAdapter(Memory* memory = nullptr);
+        MemoryToIceAdapter(wm::Memory* workingMemory = nullptr, ltm::Memory* longtermMemory = nullptr);
 
-        void setMemoryListener(client::MemoryListenerInterfacePrx memoryListener);
+        void setMemoryListener(client::MemoryListenerInterfacePrx memoryListenerTopic);
 
 
         // WRITING
-
         data::AddSegmentResult addSegment(
             const data::AddSegmentInput& input, bool addCoreSegments = false);
 
@@ -40,18 +40,22 @@ namespace armarx::armem::server
         data::CommitResult commit(const data::Commit& commitIce);
         armem::CommitResult commit(const armem::Commit& commit);
 
-
         // READING
-
         query::data::Result query(const armem::query::data::Input& input);
         client::QueryResult query(const client::QueryInput& input);
 
+        // LTM LOADING
+        query::data::Result load(const armem::query::data::Input& input);
+
+        // LTM STORING
+        data::StoreResult store(const armem::data::StoreInput& input);
 
     public:
 
-        Memory* memory;
+        wm::Memory* workingMemory;
+        ltm::Memory* longtermMemory;
 
-        client::MemoryListenerInterfacePrx memoryListener;
+        client::MemoryListenerInterfacePrx memoryListenerTopic;
 
     };
 
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/BaseQueryProcessor.cpp
deleted file mode 100644
index c9f25c5d279a896f34f4d72e252a427b24549e07..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/BaseQueryProcessor.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "BaseQueryProcessor.h"
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
-
-namespace armarx::armem::query_proc
-{
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/CoreSegmentQueryProcessor.cpp
deleted file mode 100644
index 9cdb9050876af48a2c48f670b0772507aa688670..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/CoreSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "CoreSegmentQueryProcessor.h"
-
-#include <regex>
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-#include <RobotAPI/libraries/armem/core/error.h>
-
-
-namespace armarx::armem::query_proc
-{
-
-    void CoreSegmentQueryProcessor::process(CoreSegment& result, const armem::query::data::CoreSegmentQuery& query, const CoreSegment& coreSegment) const
-    {
-        if (auto q = dynamic_cast<const armem::query::data::core::All*>(&query))
-        {
-            process(result, *q, coreSegment);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::core::Single*>(&query))
-        {
-            process(result, *q, coreSegment);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::core::Regex*>(&query))
-        {
-            process(result, *q, coreSegment);
-        }
-        else
-        {
-            throw armem::error::UnknownQueryType("core segment", query);
-        }
-    }
-
-
-    void CoreSegmentQueryProcessor::process(CoreSegment& result,
-                                            const armem::query::data::core::All& query, const CoreSegment& coreSegment) const
-    {
-        for (const auto& [name, providerSegment] : coreSegment.providerSegments)
-        {
-            result.addProviderSegment(providerSegmentProcessor.process(query.providerSegmentQueries, providerSegment));
-        }
-    }
-
-    void CoreSegmentQueryProcessor::process(CoreSegment& result,
-                                            const armem::query::data::core::Single& query, const CoreSegment& coreSegment) const
-    {
-        try
-        {
-            const ProviderSegment& providerSegment = coreSegment.getProviderSegment(query.providerSegmentName);
-            result.addProviderSegment(providerSegmentProcessor.process(query.providerSegmentQueries, providerSegment));
-        }
-        catch (const error::MissingEntry&)
-        {
-            // Leave empty.
-        }
-    }
-
-    void CoreSegmentQueryProcessor::process(CoreSegment& result,
-                                            const armem::query::data::core::Regex& query, const CoreSegment& coreSegment) const
-    {
-        std::regex regex(query.providerSegmentNameRegex);
-        for (const auto& [name, providerSegment] : coreSegment.providerSegments)
-        {
-            if (std::regex_search(providerSegment.name(), regex))
-            {
-                result.addProviderSegment(providerSegmentProcessor.process(query.providerSegmentQueries, providerSegment));
-            }
-        }
-    }
-
-
-    data::CoreSegment CoreSegmentQueryProcessor::processToIce(
-        const armem::query::data::CoreSegmentQuery& query, const CoreSegment& coreSegment) const
-    {
-        return toIce<data::CoreSegment>(process(query, coreSegment));
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/CoreSegmentQueryProcessor.h
deleted file mode 100644
index 4a59e546da57ff720a9dcce627319bc8edcb1e35..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/CoreSegmentQueryProcessor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-
-#include <RobotAPI/libraries/armem/core/Memory.h>
-
-#include "BaseQueryProcessor.h"
-#include "ProviderSegmentQueryProcessor.h"
-
-
-
-namespace armarx::armem::query_proc
-{
-
-    /**
-     * @brief Handles memory queries.
-     */
-    class CoreSegmentQueryProcessor : public BaseQueryProcessor<CoreSegment, armem::query::data::CoreSegmentQuery>
-    {
-    public:
-
-        CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData) :
-            BaseQueryProcessor(dataMode), providerSegmentProcessor(dataMode)
-        {}
-
-
-        using BaseQueryProcessor::process;
-
-        void process(CoreSegment& result, const armem::query::data::CoreSegmentQuery& query, const CoreSegment& coreSegment) const;
-
-        void process(CoreSegment& result, const armem::query::data::core::All& query, const CoreSegment& coreSegment) const;
-        void process(CoreSegment& result, const armem::query::data::core::Single& query, const CoreSegment& coreSegment) const;
-        void process(CoreSegment& result, const armem::query::data::core::Regex& query, const CoreSegment& coreSegment) const;
-
-
-        data::CoreSegment processToIce(const armem::query::data::CoreSegmentQuery& query, const CoreSegment& coreSegment) const;
-
-
-    private:
-
-        ProviderSegmentQueryProcessor providerSegmentProcessor;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/EntityQueryProcessor.cpp
deleted file mode 100644
index c062c089e31f8cf5c1314e4e4fcd7608ee5f2a48..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/EntityQueryProcessor.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "EntityQueryProcessor.h"
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
-
-namespace armarx::armem::query_proc
-{
-
-    void EntityQueryProcessor::process(Entity& result, const armem::query::data::EntityQuery& query, const Entity& entity) const
-    {
-        if (auto q = dynamic_cast<const armem::query::data::entity::All*>(&query))
-        {
-            process(result, *q, entity);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::entity::Single*>(&query))
-        {
-            process(result, *q, entity);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::entity::TimeRange*>(&query))
-        {
-            process(result, *q, entity);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::entity::IndexRange*>(&query))
-        {
-            process(result, *q, entity);
-        }
-        else
-        {
-            throw armem::error::UnknownQueryType("entity snapshot", query);
-        }
-    }
-
-    void EntityQueryProcessor::process(Entity& result, const armem::query::data::entity::All& query, const Entity& entity) const
-    {
-        (void) query;
-        // Copy this entitiy and its contents.
-
-        for (const auto& [time, snapshot] : entity)
-        {
-            addResultSnapshot(result, snapshot);
-        }
-    }
-
-    void EntityQueryProcessor::process(Entity& result, const armem::query::data::entity::Single& query, const Entity& entity) const
-    {
-        if (query.timestamp < 0)
-        {
-            try
-            {
-                addResultSnapshot(result, entity.getLatestSnapshot());
-            }
-            catch (const armem::error::EntityHistoryEmpty&)
-            {
-                // Leave empty.
-            }
-        }
-        else
-        {
-            Time time = fromIce<Time>(query.timestamp);
-            try
-            {
-                addResultSnapshot(result, entity.getSnapshot(time));
-            }
-            catch (const armem::error::MissingEntry&)
-            {
-                // Leave empty.
-            }
-        }
-    }
-
-    void EntityQueryProcessor::process(Entity& result, const armem::query::data::entity::IndexRange& query, const Entity& entity) const
-    {
-        if (entity.empty())
-        {
-            return;
-        }
-
-        size_t first = negativeIndexSemantics(query.first, entity.history.size());
-        size_t last = negativeIndexSemantics(query.last, entity.history.size());
-
-        if (first <= last)
-        {
-            auto it = entity.begin();
-            std::advance(it, first);
-
-            size_t num = last - first + 1;  // +1 to make last inclusive
-            for (size_t i = 0; i < num; ++i, ++it)
-            {
-                addResultSnapshot(result, it);
-            }
-        }
-    }
-
-    void EntityQueryProcessor::process(Entity& result, const armem::query::data::entity::TimeRange& query, const Entity& entity) const
-    {
-        if (query.minTimestamp <= query.maxTimestamp || query.minTimestamp < 0 || query.maxTimestamp < 0)
-        {
-            Time min = fromIce<Time>(query.minTimestamp);
-            Time max = fromIce<Time>(query.maxTimestamp);
-            process(result, min, max, entity, query);
-        }
-    }
-
-    void EntityQueryProcessor::process(Entity& result, const Time& min, const Time& max, const Entity& entity,
-                                       const armem::query::data::EntityQuery& query) const
-    {
-        (void) query;
-
-        // Returns an iterator pointing to the first element that is not less than (i.e. greater or equal to) key.
-        auto begin = min.toMicroSeconds() > 0 ? entity.history.lower_bound(min) : entity.history.begin();
-        // Returns an iterator pointing to the first element that is *greater than* key.
-        auto end = max.toMicroSeconds() > 0 ? entity.history.upper_bound(max) : entity.history.end();
-
-        for (auto it = begin; it != end && it != entity.history.end(); ++it)
-        {
-            addResultSnapshot(result, it);
-        }
-    }
-
-    data::Entity EntityQueryProcessor::processToIce(const armem::query::data::EntityQuery& query, const Entity& entity) const
-    {
-        return toIce<data::Entity>(process(query, entity));
-    }
-
-    size_t EntityQueryProcessor::negativeIndexSemantics(long index, size_t size)
-    {
-        const size_t max = size > 0 ? size - 1 : 0;
-        if (index >= 0)
-        {
-            return std::clamp<size_t>(static_cast<size_t>(index), 0, max);
-        }
-        else
-        {
-            return static_cast<size_t>(std::clamp<long>(static_cast<long>(size) + index, 0, static_cast<long>(max)));
-        }
-    }
-
-    void EntityQueryProcessor::addResultSnapshot(Entity& result, Entity::ContainerT::const_iterator it) const
-    {
-        addResultSnapshot(result, it->second);
-    }
-
-    void EntityQueryProcessor::addResultSnapshot(Entity& result, const EntitySnapshot& snapshot) const
-    {
-        bool withData = (dataMode == DataMode::WithData);
-        result.addSnapshot(snapshot.copy(withData));
-    }
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/EntityQueryProcessor.h
deleted file mode 100644
index 594022ffb82e227a87c793db29c54f462e66aaaa..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/EntityQueryProcessor.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-
-#include <RobotAPI/libraries/armem/core/Memory.h>
-
-#include "BaseQueryProcessor.h"
-
-
-namespace armarx::armem::query_proc
-{
-
-    /**
-     * @brief Handles memory queries.
-     */
-    class EntityQueryProcessor : public BaseQueryProcessor<Entity, armem::query::data::EntityQuery>
-    {
-    public:
-
-        EntityQueryProcessor(DataMode dataMode = DataMode::WithData) :
-            BaseQueryProcessor(dataMode)
-        {}
-
-
-        using BaseQueryProcessor::process;
-
-        void process(Entity& result, const armem::query::data::EntityQuery& query, const Entity& entity) const override;
-
-        void process(Entity& result, const armem::query::data::entity::All& query, const Entity& entity) const;
-        void process(Entity& result, const armem::query::data::entity::Single& query, const Entity& entity) const;
-        void process(Entity& result, const armem::query::data::entity::TimeRange& query, const Entity& entity) const;
-        void process(Entity& result, const armem::query::data::entity::IndexRange& query, const Entity& entity) const;
-
-        void process(Entity& result, const Time& min, const Time& max, const Entity& entity,
-                     const armem::query::data::EntityQuery& query) const;
-
-
-        data::Entity processToIce(const armem::query::data::EntityQuery& query, const Entity& entity) const;
-
-
-        static size_t negativeIndexSemantics(long index, size_t size);
-
-    private:
-
-        void addResultSnapshot(Entity& result, Entity::ContainerT::const_iterator it) const;
-        void addResultSnapshot(Entity& result, const EntitySnapshot& snapshot) const;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/MemoryQueryProcessor.cpp
deleted file mode 100644
index 129892339524ca76cc602dbea1b8cfe0524b3a1a..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/MemoryQueryProcessor.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "MemoryQueryProcessor.h"
-
-#include <regex>
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
-
-namespace armarx::armem::query_proc
-{
-
-    armem::query::data::Result MemoryQueryProcessor::process(const armem::query::data::Input& input, const Memory& memory) const
-    {
-        armem::query::data::Result result;
-        result.memory = processToIce(input.memoryQueries, memory);
-        result.success = true;
-        return result;
-    }
-
-    data::MemoryPtr MemoryQueryProcessor::processToIce(
-        const armem::query::data::MemoryQuery& query, const Memory& memory) const
-    {
-        return toIce<data::MemoryPtr>(process(query, memory));
-    }
-
-    data::MemoryPtr MemoryQueryProcessor::processToIce(const armem::query::data::MemoryQuerySeq& queries, const Memory& memory) const
-    {
-        return toIce<data::MemoryPtr>(process(queries, memory));
-    }
-
-    void MemoryQueryProcessor::process(Memory& result, const armem::query::data::MemoryQuery& query, const Memory& memory) const
-    {
-        if (auto q = dynamic_cast<const armem::query::data::memory::All*>(&query))
-        {
-            process(result, *q, memory);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::memory::Single*>(&query))
-        {
-            process(result, *q, memory);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::memory::Regex*>(&query))
-        {
-            process(result, *q, memory);
-        }
-        else
-        {
-            throw armem::error::UnknownQueryType("memory segment", query);
-        }
-    }
-
-
-    void MemoryQueryProcessor::process(Memory& result, const armem::query::data::memory::All& query, const Memory& memory) const
-    {
-        for (const auto& [name, coreSegment] : memory.coreSegments)
-        {
-            result.addCoreSegment(coreSegmentProcessor.process(query.coreSegmentQueries, coreSegment));
-        }
-    }
-
-    void MemoryQueryProcessor::process(Memory& result, const armem::query::data::memory::Single& query, const Memory& memory) const
-    {
-        try
-        {
-            const CoreSegment& coreSegment = memory.getCoreSegment(query.coreSegmentName);
-            result.addCoreSegment(coreSegmentProcessor.process(query.coreSegmentQueries, coreSegment));
-        }
-        catch (const error::MissingEntry&)
-        {
-            // Leave empty.
-        }
-    }
-
-    void MemoryQueryProcessor::process(Memory& result, const armem::query::data::memory::Regex& query, const Memory& memory) const
-    {
-        std::regex regex(query.coreSegmentNameRegex);
-        for (const auto& [name, coreSegment] : memory.coreSegments)
-        {
-            if (std::regex_search(coreSegment.name(), regex))
-            {
-                result.addCoreSegment(coreSegmentProcessor.process(query.coreSegmentQueries, coreSegment));
-            }
-        }
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/MemoryQueryProcessor.h
deleted file mode 100644
index de16c9433bdf5af97fee33e929930519cc490187..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/MemoryQueryProcessor.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-
-#include <RobotAPI/libraries/armem/core/Memory.h>
-
-#include "BaseQueryProcessor.h"
-#include "CoreSegmentQueryProcessor.h"
-
-
-
-namespace armarx::armem::query_proc
-{
-
-    /**
-     * @brief Handles memory queries.
-     */
-    class MemoryQueryProcessor : public BaseQueryProcessor<Memory, armem::query::data::MemoryQuery>
-    {
-    public:
-
-        MemoryQueryProcessor(DataMode dataMode = DataMode::WithData) :
-            BaseQueryProcessor(dataMode), coreSegmentProcessor(dataMode)
-        {}
-
-
-        using BaseQueryProcessor::process;
-
-        armem::query::data::Result process(const armem::query::data::Input& input, const Memory& memory) const;
-
-
-        void process(Memory& result, const armem::query::data::MemoryQuery& query, const Memory& memory) const;
-
-        void process(Memory& result, const armem::query::data::memory::All& query, const Memory& memory) const;
-        void process(Memory& result, const armem::query::data::memory::Single& query, const Memory& memory) const;
-        void process(Memory& result, const armem::query::data::memory::Regex& query, const Memory& memory) const;
-
-
-        data::MemoryPtr processToIce(const armem::query::data::MemoryQuery& query, const Memory& memory) const;
-        data::MemoryPtr processToIce(const armem::query::data::MemoryQuerySeq& query, const Memory& memory) const;
-
-
-    private:
-
-        CoreSegmentQueryProcessor coreSegmentProcessor;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/ProviderSegmentQueryProcessor.cpp
deleted file mode 100644
index 36bfe8765fe2fedb092b93e4a6d607ab1a026cda..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/ProviderSegmentQueryProcessor.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "ProviderSegmentQueryProcessor.h"
-
-#include <regex>
-
-#include <ArmarXCore/core/logging/Logging.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-
-#include <RobotAPI/libraries/armem/core/error.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
-
-
-namespace armarx::armem::query_proc
-{
-
-    void ProviderSegmentQueryProcessor::process(ProviderSegment& result, const armem::query::data::ProviderSegmentQuery& query, const ProviderSegment& providerSegment) const
-    {
-        if (auto q = dynamic_cast<const armem::query::data::provider::All*>(&query))
-        {
-            process(result, *q, providerSegment);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::provider::Single*>(&query))
-        {
-            process(result, *q, providerSegment);
-        }
-        else if (auto q = dynamic_cast<const armem::query::data::provider::Regex*>(&query))
-        {
-            process(result, *q, providerSegment);
-        }
-        else
-        {
-            throw armem::error::UnknownQueryType("provider segment", query);
-        }
-    }
-
-
-    void ProviderSegmentQueryProcessor::process(ProviderSegment& result,
-            const armem::query::data::provider::All& query, const ProviderSegment& providerSegment) const
-    {
-        for (const auto& [name, entity] : providerSegment.entities)
-        {
-            result.addEntity(entityProcessor.process(query.entityQueries, entity));
-        }
-    }
-
-    void ProviderSegmentQueryProcessor::process(ProviderSegment& result,
-            const armem::query::data::provider::Single& query, const ProviderSegment& providerSegment) const
-    {
-        try
-        {
-            const Entity& entity = providerSegment.getEntity(query.entityName);
-            result.addEntity(entityProcessor.process(query.entityQueries, entity));
-        }
-        catch (const error::MissingEntry&)
-        {
-            // Leave empty.
-        }
-    }
-
-    void ProviderSegmentQueryProcessor::process(ProviderSegment& result,
-            const armem::query::data::provider::Regex& query, const ProviderSegment& providerSegment) const
-    {
-        std::regex regex(query.entityNameRegex);
-        for (const auto& [name, entity] : providerSegment.entities)
-        {
-            if (std::regex_search(entity.name(), regex))
-            {
-                result.addEntity(entityProcessor.process(query.entityQueries, entity));
-            }
-        }
-    }
-
-
-    data::ProviderSegment ProviderSegmentQueryProcessor::processToIce(
-        const armem::query::data::ProviderSegmentQuery& query, const ProviderSegment& providerSegment) const
-    {
-        return toIce<data::ProviderSegment>(process(query, providerSegment));
-    }
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/ProviderSegmentQueryProcessor.h
deleted file mode 100644
index da5c200bfbe66752aff5bb88324e44220bb7faea..0000000000000000000000000000000000000000
--- a/source/RobotAPI/libraries/armem/server/query_proc/ProviderSegmentQueryProcessor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-#include <RobotAPI/interface/armem/query.h>
-
-#include <RobotAPI/libraries/armem/core/Memory.h>
-
-#include "BaseQueryProcessor.h"
-#include "EntityQueryProcessor.h"
-
-
-
-namespace armarx::armem::query_proc
-{
-
-    /**
-     * @brief Handles memory queries.
-     */
-    class ProviderSegmentQueryProcessor : public BaseQueryProcessor<ProviderSegment, armem::query::data::ProviderSegmentQuery>
-    {
-    public:
-
-        ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData) :
-            BaseQueryProcessor(dataMode), entityProcessor(dataMode)
-        {}
-
-
-        using BaseQueryProcessor::process;
-
-        void process(ProviderSegment& result, const armem::query::data::ProviderSegmentQuery& query, const ProviderSegment& providerSegment) const;
-
-        void process(ProviderSegment& result, const armem::query::data::provider::All& query, const ProviderSegment& providerSegment) const;
-        void process(ProviderSegment& result, const armem::query::data::provider::Single& query, const ProviderSegment& providerSegment) const;
-        void process(ProviderSegment& result, const armem::query::data::provider::Regex& query, const ProviderSegment& providerSegment) const;
-
-
-        data::ProviderSegment processToIce(const armem::query::data::ProviderSegmentQuery& query, const ProviderSegment& providerSegment) const;
-
-
-    private:
-
-        EntityQueryProcessor entityProcessor;
-
-    };
-
-}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ce437fd67bdd2ba3aa6ac9943093525db99a581e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.cpp
@@ -0,0 +1 @@
+#include "BaseQueryProcessorBase.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h
similarity index 82%
rename from source/RobotAPI/libraries/armem/server/query_proc/BaseQueryProcessor.h
rename to source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h
index 7858b2b7120fb5239c375d0c398334d8381c538b..3ea2b0bdd45230dab810bd628cf338d2b685662b 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/BaseQueryProcessor.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h
@@ -5,37 +5,28 @@
 #include <RobotAPI/libraries/armem/core/DataMode.h>
 
 
-namespace armarx::armem::query_proc
+namespace armarx::armem::base::query_proc
 {
 
     /**
      * @brief Base class for memory query processors.
      */
     template <class DataT, class QueryT>
-    class BaseQueryProcessor
+    class BaseQueryProcessorBase
     {
     public:
-
         using QueryPtrT = ::IceInternal::Handle<QueryT>;
         using QuerySeqT = std::vector<QueryPtrT>;
 
-
     public:
 
-        BaseQueryProcessor(DataMode dataMode = DataMode::WithData) :
-            dataMode(dataMode)
-        {}
-
-        virtual ~BaseQueryProcessor()
-        {}
-
-
         DataT process(const QueryT& query, const DataT& data) const
         {
             DataT result = data.copyEmpty();
             this->process(result, query, data);
             return result;
         }
+
         DataT process(const QueryPtrT& query, const DataT& data) const
         {
             return this->process(*query, *data);
@@ -48,7 +39,6 @@ namespace armarx::armem::query_proc
             return result;
         }
 
-
         void process(DataT& result, const QuerySeqT& queries, const DataT& data) const
         {
             for (const auto& query : queries)
@@ -58,12 +48,6 @@ namespace armarx::armem::query_proc
         }
 
         virtual void process(DataT& result, const QueryT& query, const DataT& data) const = 0;
-
-
-    protected:
-
-        DataMode dataMode;
-
     };
 
 }
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63e7ff349207a6891d26c0dde081572f0e53d3a5
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.cpp
@@ -0,0 +1 @@
+#include "CoreSegmentQueryProcessorBase.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8ab8c113e510e57a1ab2b53af6a06e60e393ce1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/CoreSegmentQueryProcessorBase.h
@@ -0,0 +1,100 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/query.h>
+
+#include "BaseQueryProcessorBase.h"
+#include "ProviderSegmentQueryProcessorBase.h"
+
+#include <regex>
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include <RobotAPI/libraries/armem/core/error.h>
+
+
+
+namespace armarx::armem::base::query_proc
+{
+
+    /**
+     * @brief Handles memory queries.
+     */
+    template <class _CoreSegmentT>
+    class CoreSegmentQueryProcessorBase :
+        virtual public BaseQueryProcessorBase<_CoreSegmentT, armem::query::data::CoreSegmentQuery>
+    {
+        using Base = BaseQueryProcessorBase<_CoreSegmentT, armem::query::data::CoreSegmentQuery>;
+
+    public:
+        using CoreSegmentT = _CoreSegmentT;
+        using ProviderSegmentT = typename _CoreSegmentT::ProviderSegmentT;
+        using EntityT = typename ProviderSegmentT::EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+
+        using Base::process;
+        void process(_CoreSegmentT& result,
+                     const armem::query::data::CoreSegmentQuery& query,
+                     const _CoreSegmentT& coreSegment) const override
+        {
+            if (auto q = dynamic_cast<const armem::query::data::core::All*>(&query))
+            {
+                process(result, *q, coreSegment);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::core::Single*>(&query))
+            {
+                process(result, *q, coreSegment);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::core::Regex*>(&query))
+            {
+                process(result, *q, coreSegment);
+            }
+            else
+            {
+                throw armem::error::UnknownQueryType("core segment", query);
+            }
+        }
+
+        void process(_CoreSegmentT& result,
+                     const armem::query::data::core::All& query,
+                     const _CoreSegmentT& coreSegment) const
+        {
+            for (const auto& [name, providerSegment] : coreSegment.providerSegments())
+            {
+                result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment));
+            }
+        }
+
+        void process(_CoreSegmentT& result,
+                     const armem::query::data::core::Single& query,
+                     const _CoreSegmentT& coreSegment) const
+        {
+            try
+            {
+                const ProviderSegmentT& providerSegment = coreSegment.getProviderSegment(query.providerSegmentName);
+                result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment));
+            }
+            catch (const error::MissingEntry&)
+            {
+                // Leave empty.
+            }
+        }
+
+        void process(_CoreSegmentT& result,
+                     const armem::query::data::core::Regex& query,
+                     const _CoreSegmentT& coreSegment) const
+        {
+            std::regex regex(query.providerSegmentNameRegex);
+            for (const auto& [name, providerSegment] : coreSegment.providerSegments())
+            {
+                if (std::regex_search(providerSegment.name(), regex))
+                {
+                    result.addProviderSegment(providerSegmentProcessorProcess(query.providerSegmentQueries, providerSegment));
+                }
+            }
+        }
+
+    protected:
+        virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& a, const ProviderSegmentT& o) const = 0;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5cbac85a8dc5f8899e7c72434516063121a2b4c1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.cpp
@@ -0,0 +1 @@
+#include "EntityQueryProcessorBase.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..447bd259a2c24a3ca80c91c59a518daed56c18f1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
@@ -0,0 +1,174 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/query.h>
+
+#include "BaseQueryProcessorBase.h"
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include <RobotAPI/libraries/armem/core/error.h>
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+
+
+namespace armarx::armem::base::query_proc
+{
+
+    /**
+     * @brief Handles memory queries.
+     */
+    template <class _EntityT>
+    class EntityQueryProcessorBase :
+        virtual public BaseQueryProcessorBase<_EntityT, armem::query::data::EntityQuery>
+    {
+        using Base = BaseQueryProcessorBase<_EntityT, armem::query::data::EntityQuery>;
+
+    public:
+        using EntityT = _EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+
+        using Base::process;
+        void process(_EntityT& result,
+                     const armem::query::data::EntityQuery& query,
+                     const _EntityT& entity) const override
+        {
+            if (auto q = dynamic_cast<const armem::query::data::entity::All*>(&query))
+            {
+                process(result, *q, entity);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::entity::Single*>(&query))
+            {
+                process(result, *q, entity);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::entity::TimeRange*>(&query))
+            {
+                process(result, *q, entity);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::entity::IndexRange*>(&query))
+            {
+                process(result, *q, entity);
+            }
+            else
+            {
+                throw armem::error::UnknownQueryType("entity snapshot", query);
+            }
+        }
+
+        void process(_EntityT& result,
+                     const armem::query::data::entity::All& query,
+                     const _EntityT& entity) const
+        {
+            (void) query;
+            // Copy this entitiy and its contents.
+
+            for (const auto& [time, snapshot] : entity)
+            {
+                addResultSnapshot(result, snapshot);
+            }
+        }
+
+        void process(_EntityT& result,
+                     const armem::query::data::entity::Single& query,
+                     const _EntityT& entity) const
+        {
+            if (query.timestamp < 0)
+            {
+                try
+                {
+                    addResultSnapshot(result, entity.getLatestSnapshot());
+                }
+                catch (const armem::error::EntityHistoryEmpty&)
+                {
+                    // Leave empty.
+                }
+            }
+            else
+            {
+                Time time = fromIce<Time>(query.timestamp);
+                try
+                {
+                    addResultSnapshot(result, entity.getSnapshot(time));
+                }
+                catch (const armem::error::MissingEntry&)
+                {
+                    // Leave empty.
+                }
+            }
+        }
+
+        void process(_EntityT& result,
+                     const armem::query::data::entity::TimeRange& query,
+                     const _EntityT& entity) const
+        {
+            if (query.minTimestamp <= query.maxTimestamp || query.minTimestamp < 0 || query.maxTimestamp < 0)
+            {
+                Time min = fromIce<Time>(query.minTimestamp);
+                Time max = fromIce<Time>(query.maxTimestamp);
+                process(result, min, max, entity, query);
+            }
+        }
+
+        void process(_EntityT& result,
+                     const armem::query::data::entity::IndexRange& query,
+                     const _EntityT& entity) const
+        {
+            if (entity.empty())
+            {
+                return;
+            }
+
+            size_t first = negativeIndexSemantics(query.first, entity.history().size());
+            size_t last = negativeIndexSemantics(query.last, entity.history().size());
+
+            if (first <= last)
+            {
+                auto it = entity.begin();
+                std::advance(it, first);
+
+                size_t num = last - first + 1;  // +1 to make last inclusive
+                for (size_t i = 0; i < num; ++i, ++it)
+                {
+                    addResultSnapshot(result, it);
+                }
+            }
+        }
+
+        void process(_EntityT& result,
+                     const Time& min,
+                     const Time& max,
+                     const _EntityT& entity,
+                     const armem::query::data::EntityQuery& query) const
+        {
+            (void) query;
+
+            // Returns an iterator pointing to the first element that is not less than (i.e. greater or equal to) key.
+            auto begin = min.toMicroSeconds() > 0 ? entity.history().lower_bound(min) : entity.history().begin();
+            // Returns an iterator pointing to the first element that is *greater than* key.
+            auto end = max.toMicroSeconds() > 0 ? entity.history().upper_bound(max) : entity.history().end();
+
+            for (auto it = begin; it != end && it != entity.history().end(); ++it)
+            {
+                addResultSnapshot(result, it);
+            }
+        }
+
+
+        static size_t negativeIndexSemantics(long index, size_t size)
+        {
+            const size_t max = size > 0 ? size - 1 : 0;
+            if (index >= 0)
+            {
+                return std::clamp<size_t>(static_cast<size_t>(index), 0, max);
+            }
+            else
+            {
+                return static_cast<size_t>(std::clamp<long>(static_cast<long>(size) + index, 0, static_cast<long>(max)));
+            }
+        }
+
+    protected:
+        virtual void addResultSnapshot(_EntityT& result, typename _EntityT::ContainerT::const_iterator it) const = 0;
+        virtual void addResultSnapshot(_EntityT& result, const typename _EntityT::EntitySnapshotT& snapshot) const = 0;
+
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c51a6336c440e44fe637df89700136687d03f294
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.cpp
@@ -0,0 +1 @@
+#include "MemoryQueryProcessorBase.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..c50086b553164b70f10ed1559a18420649eb3892
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
@@ -0,0 +1,98 @@
+#pragma once
+
+#include <regex>
+
+#include <RobotAPI/interface/armem/query.h>
+
+#include "BaseQueryProcessorBase.h"
+#include "CoreSegmentQueryProcessorBase.h"
+
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include <RobotAPI/libraries/armem/core/error.h>
+
+
+namespace armarx::armem::base::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    template <class _MemoryT>
+    class MemoryQueryProcessorBase :
+        virtual public BaseQueryProcessorBase<_MemoryT, armem::query::data::MemoryQuery>
+    {
+        using Base = BaseQueryProcessorBase<_MemoryT, armem::query::data::MemoryQuery>;
+
+    public:
+        using MemoryT = _MemoryT;
+        using CoreSegmentT = typename MemoryT::CoreSegmentT;
+        using ProviderSegmentT = typename CoreSegmentT::ProviderSegmentT;
+        using EntityT = typename ProviderSegmentT::EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+
+        void process(_MemoryT& result,
+                     const armem::query::data::MemoryQuery& query,
+                     const _MemoryT& memory) const override
+        {
+            if (auto q = dynamic_cast<const armem::query::data::memory::All*>(&query))
+            {
+                process(result, *q, memory);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::memory::Single*>(&query))
+            {
+                process(result, *q, memory);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::memory::Regex*>(&query))
+            {
+                process(result, *q, memory);
+            }
+            else
+            {
+                throw armem::error::UnknownQueryType("memory segment", query);
+            }
+        }
+
+        void process(_MemoryT& result,
+                     const armem::query::data::memory::All& query,
+                     const _MemoryT& memory) const
+        {
+            for (const auto& [name, coreSegment] : memory.coreSegments())
+            {
+                result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
+            }
+        }
+
+        void process(_MemoryT& result,
+                     const armem::query::data::memory::Single& query,
+                     const _MemoryT& memory) const
+        {
+            try
+            {
+                const CoreSegmentT& coreSegment = memory.getCoreSegment(query.coreSegmentName);
+                result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
+            }
+            catch (const error::MissingEntry&)
+            {
+            }
+        }
+
+        void process(_MemoryT& result,
+                     const armem::query::data::memory::Regex& query,
+                     const _MemoryT& memory) const
+        {
+            std::regex regex(query.coreSegmentNameRegex);
+            for (const auto& [name, coreSegment] : memory.coreSegments())
+            {
+                if (std::regex_search(coreSegment.name(), regex))
+                {
+                    result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
+                }
+            }
+        }
+
+    protected:
+        virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& a, const CoreSegmentT& o) const = 0;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.cpp b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..67db9e1429d8aa9c797790f4290a9feb512d41c6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.cpp
@@ -0,0 +1 @@
+#include "ProviderSegmentQueryProcessorBase.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3b7da7ffa9cc1d06aeadabef58c5aebba3974de
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
@@ -0,0 +1,98 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/query.h>
+
+#include "BaseQueryProcessorBase.h"
+#include "EntityQueryProcessorBase.h"
+
+#include <regex>
+
+#include <ArmarXCore/core/logging/Logging.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+
+#include <RobotAPI/libraries/armem/core/error.h>
+
+
+namespace armarx::armem::base::query_proc
+{
+
+    /**
+     * @brief Handles memory queries.
+     */
+    template <class _ProviderSegmentT>
+    class ProviderSegmentQueryProcessorBase :
+        virtual public BaseQueryProcessorBase<_ProviderSegmentT, armem::query::data::ProviderSegmentQuery>
+    {
+        using Base = BaseQueryProcessorBase<_ProviderSegmentT, armem::query::data::ProviderSegmentQuery>;
+
+    public:
+        using ProviderSegmentT = _ProviderSegmentT;
+        using EntityT = typename ProviderSegmentT::EntityT;
+        using EntitySnapshotT = typename EntityT::EntitySnapshotT;
+
+        using Base::process;
+        void process(_ProviderSegmentT& result,
+                     const armem::query::data::ProviderSegmentQuery& query,
+                     const _ProviderSegmentT& providerSegment) const override
+        {
+            if (auto q = dynamic_cast<const armem::query::data::provider::All*>(&query))
+            {
+                process(result, *q, providerSegment);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::provider::Single*>(&query))
+            {
+                process(result, *q, providerSegment);
+            }
+            else if (auto q = dynamic_cast<const armem::query::data::provider::Regex*>(&query))
+            {
+                process(result, *q, providerSegment);
+            }
+            else
+            {
+                throw armem::error::UnknownQueryType("provider segment", query);
+            }
+        }
+
+        void process(_ProviderSegmentT& result,
+                     const armem::query::data::provider::All& query,
+                     const _ProviderSegmentT& providerSegment) const
+        {
+            for (const auto& [name, entity] : providerSegment.entities())
+            {
+                result.addEntity(entityProcessorProcess(query.entityQueries, entity));
+            }
+        }
+
+        void process(_ProviderSegmentT& result,
+                     const armem::query::data::provider::Single& query,
+                     const _ProviderSegmentT& providerSegment) const
+        {
+            try
+            {
+                const EntityT& entity = providerSegment.getEntity(query.entityName);
+                result.addEntity(entityProcessorProcess(query.entityQueries, entity));
+            }
+            catch (const error::MissingEntry&)
+            {
+                // Leave empty.
+            }
+        }
+
+        void process(_ProviderSegmentT& result,
+                     const armem::query::data::provider::Regex& query,
+                     const _ProviderSegmentT& providerSegment) const
+        {
+            std::regex regex(query.entityNameRegex);
+            for (const auto& [name, entity] : providerSegment.entities())
+            {
+                if (std::regex_search(entity.name(), regex))
+                {
+                    result.addEntity(entityProcessorProcess(query.entityQueries, entity));
+                }
+            }
+        }
+
+    protected:
+        virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& a, const EntityT& o) const = 0;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68821bcd95cdf2aaccf7126d4055495d39d0393d
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "BaseQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..458128e5305139db33a6c25d6ff19e3e92772fd5
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/BaseQueryProcessor.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <RobotAPI/interface/armem/query.h>
+#include <RobotAPI/libraries/armem/core/DataMode.h>
+
+#include "../base/BaseQueryProcessorBase.h"
+
+
+namespace armarx::armem::ltm::query_proc
+{
+    /**
+     * @brief Base class for memory query processors.
+     */
+    template <class DataT, class QueryT>
+    class BaseQueryProcessor :
+        virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT>
+    {
+        using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>;
+
+    public:
+        BaseQueryProcessor()
+        {}
+
+    protected:
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "CoreSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc379f1d88fa82bbe886e412e0341079fa43fce9
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/CoreSegmentQueryProcessorBase.h"
+
+#include "../../../core/longtermmemory/CoreSegment.h"
+
+#include "ProviderSegmentQueryProcessor.h"
+
+
+namespace armarx::armem::ltm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class CoreSegmentQueryProcessor :
+        virtual public BaseQueryProcessor<ltm::CoreSegment, armem::query::data::CoreSegmentQuery>,
+        virtual public base::query_proc::CoreSegmentQueryProcessorBase<ltm::CoreSegment>
+    {
+        using Base = BaseQueryProcessor<ltm::CoreSegment, armem::query::data::CoreSegmentQuery>;
+
+    public:
+        CoreSegmentQueryProcessor() :
+            Base()
+        {}
+
+    protected:
+        virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override
+        {
+            return providerSegmentProcessor.process(q, s);
+        }
+
+    private:
+        ProviderSegmentQueryProcessor providerSegmentProcessor;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c1c321b026b173c6552758fb9d8b9fdf722ea5a4
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "EntityQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..5ec4c5dde481e16f0af30589d57ff2a447d81221
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/EntityQueryProcessorBase.h"
+
+#include "../../../core/longtermmemory/Entity.h"
+
+#include "EntityQueryProcessor.h"
+
+namespace armarx::armem::ltm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class EntityQueryProcessor :
+        virtual public BaseQueryProcessor<ltm::Entity, armem::query::data::EntityQuery>,
+        virtual public base::query_proc::EntityQueryProcessorBase<ltm::Entity>
+    {
+        using Base = BaseQueryProcessor<ltm::Entity, armem::query::data::EntityQuery>;
+
+    public:
+        EntityQueryProcessor() :
+            Base()
+        {}
+
+    private:
+        void addResultSnapshot(ltm::Entity& result, ltm::Entity::ContainerT::const_iterator it) const override
+        {
+            addResultSnapshot(result, it->second);
+        }
+
+        void addResultSnapshot(ltm::Entity& result, const ltm::EntitySnapshot& snapshot) const override
+        {
+            result.addSnapshot(snapshot.copy());
+        }
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..69b04de6c9e623286a5bda836dddfdc8b551b64a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "MemoryQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..a5129417262515975efa247398602272865ee5ec
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/MemoryQueryProcessorBase.h"
+
+#include "../../../core/longtermmemory/Memory.h"
+
+#include "CoreSegmentQueryProcessor.h"
+
+namespace armarx::armem::ltm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class MemoryQueryProcessor :
+        virtual public BaseQueryProcessor<ltm::Memory, armem::query::data::MemoryQuery>,
+        virtual public base::query_proc::MemoryQueryProcessorBase<ltm::Memory>
+    {
+        using Base = BaseQueryProcessor<ltm::Memory, armem::query::data::MemoryQuery>;
+
+    public:
+        MemoryQueryProcessor() :
+            Base()
+        {}
+
+    protected:
+        virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override
+        {
+            return coreSegmentProcessor.process(q, s);
+        }
+
+    private:
+        CoreSegmentQueryProcessor coreSegmentProcessor;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9a2a4405001f0904b74fc6afcf96813eef0879cd
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "ProviderSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0c6db9e3ef06e6241e9af8c572bb7fc78eec452
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/ProviderSegmentQueryProcessorBase.h"
+
+#include "../../../core/longtermmemory/ProviderSegment.h"
+
+#include "EntityQueryProcessor.h"
+
+namespace armarx::armem::ltm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class ProviderSegmentQueryProcessor :
+        virtual public BaseQueryProcessor<ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>,
+        virtual public base::query_proc::ProviderSegmentQueryProcessorBase<ltm::ProviderSegment>
+    {
+        using Base = BaseQueryProcessor<ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>;
+
+    public:
+        ProviderSegmentQueryProcessor() :
+            Base()
+        {}
+
+    protected:
+        virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override
+        {
+            return entityProcessor.process(q, s);
+        }
+
+    private:
+        EntityQueryProcessor entityProcessor;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68821bcd95cdf2aaccf7126d4055495d39d0393d
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "BaseQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..99811dcc72d168dfecb0c5864f0760c4d5634a6e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/BaseQueryProcessor.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
+
+#include <RobotAPI/interface/armem/query.h>
+#include <RobotAPI/libraries/armem/core/DataMode.h>
+
+#include "../base/BaseQueryProcessorBase.h"
+
+
+namespace armarx::armem::wm::query_proc
+{
+    /**
+     * @brief Base class for memory query processors.
+     */
+    template <class DataT, class QueryT>
+    class BaseQueryProcessor :
+        virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT>
+    {
+        using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>;
+
+    public:
+        BaseQueryProcessor(DataMode dataMode = DataMode::WithData) :
+            dataMode(dataMode)
+        {}
+
+    protected:
+        DataMode dataMode;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "CoreSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..079f63ac59928f2bd4ace9ab7ab033bef93c04a1
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/CoreSegmentQueryProcessorBase.h"
+
+#include "ProviderSegmentQueryProcessor.h"
+
+
+namespace armarx::armem::wm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class CoreSegmentQueryProcessor :
+        virtual public BaseQueryProcessor<wm::CoreSegment, armem::query::data::CoreSegmentQuery>,
+        virtual public base::query_proc::CoreSegmentQueryProcessorBase<wm::CoreSegment>
+    {
+        using Base = BaseQueryProcessor<wm::CoreSegment, armem::query::data::CoreSegmentQuery>;
+
+    public:
+        CoreSegmentQueryProcessor(DataMode dataMode = DataMode::WithData) :
+            Base(dataMode), providerSegmentProcessor(dataMode)
+        {}
+
+        using Base::process;
+        data::CoreSegment processToIce(const armem::query::data::CoreSegmentQuery& query, const wm::CoreSegment& coreSegment) const
+        {
+            return toIce<data::CoreSegment>(process(query, coreSegment));
+        }
+
+    protected:
+        virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override
+        {
+            return providerSegmentProcessor.process(q, s);
+        }
+
+    private:
+        ProviderSegmentQueryProcessor providerSegmentProcessor;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c1c321b026b173c6552758fb9d8b9fdf722ea5a4
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "EntityQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..94dc905e489be501257be508cff03c7efee8f8b8
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/EntityQueryProcessor.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/EntityQueryProcessorBase.h"
+
+#include "EntityQueryProcessor.h"
+
+namespace armarx::armem::wm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class EntityQueryProcessor :
+        virtual public BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>,
+        virtual public base::query_proc::EntityQueryProcessorBase<wm::Entity>
+    {
+        using Base = BaseQueryProcessor<wm::Entity, armem::query::data::EntityQuery>;
+
+    public:
+        EntityQueryProcessor(DataMode dataMode = DataMode::WithData) :
+            Base(dataMode)
+        {}
+
+        data::Entity processToIce(const armem::query::data::EntityQuery& query, const wm::Entity& entity) const
+        {
+            return toIce<data::Entity>(process(query, entity));
+        }
+
+    private:
+        void addResultSnapshot(wm::Entity& result, wm::Entity::ContainerT::const_iterator it) const override
+        {
+            addResultSnapshot(result, it->second);
+        }
+
+        void addResultSnapshot(wm::Entity& result, const wm::EntitySnapshot& snapshot) const override
+        {
+            bool withData = (dataMode == DataMode::WithData);
+            if (withData)
+            {
+                result.addSnapshot(snapshot.copy());
+            }
+            else
+            {
+                result.addSnapshot(snapshot.copyWithoutData());
+            }
+        }
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..69b04de6c9e623286a5bda836dddfdc8b551b64a
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "MemoryQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..b017c3b561569c1da5d3d7f661ee604bbb1cae12
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h
@@ -0,0 +1,56 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/MemoryQueryProcessorBase.h"
+
+#include "CoreSegmentQueryProcessor.h"
+
+namespace armarx::armem::wm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class MemoryQueryProcessor :
+        virtual public BaseQueryProcessor<wm::Memory, armem::query::data::MemoryQuery>,
+        virtual public base::query_proc::MemoryQueryProcessorBase<wm::Memory>
+    {
+        using Base = BaseQueryProcessor<wm::Memory, armem::query::data::MemoryQuery>;
+
+    public:
+        MemoryQueryProcessor(DataMode dataMode = DataMode::WithData) :
+            Base(dataMode), coreSegmentProcessor(dataMode)
+        {}
+
+        armem::query::data::Result process(const armem::query::data::Input& input,
+                                           const wm::Memory& memory) const
+        {
+            armem::query::data::Result result;
+            result.memory = processToIce(input.memoryQueries, memory);
+            result.success = true;
+            return result;
+        }
+
+        using Base::process;
+        data::MemoryPtr processToIce(const armem::query::data::MemoryQuery& query,
+                                     const wm::Memory& memory) const
+        {
+            return toIce<data::MemoryPtr>(process(query, memory));
+        }
+
+        data::MemoryPtr processToIce(const armem::query::data::MemoryQuerySeq& queries,
+                                     const wm::Memory& memory) const
+        {
+            return toIce<data::MemoryPtr>(process(queries, memory));
+        }
+
+    protected:
+        virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override
+        {
+            return coreSegmentProcessor.process(q, s);
+        }
+
+
+    private:
+        CoreSegmentQueryProcessor coreSegmentProcessor;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9a2a4405001f0904b74fc6afcf96813eef0879cd
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.cpp
@@ -0,0 +1 @@
+#include "ProviderSegmentQueryProcessor.h"
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b2e9ba97850ed1f62f2d761a51996f3b2bb2665
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "BaseQueryProcessor.h"
+#include "../base/ProviderSegmentQueryProcessorBase.h"
+
+#include "EntityQueryProcessor.h"
+
+namespace armarx::armem::wm::query_proc
+{
+    /**
+     * @brief Handles memory queries.
+     */
+    class ProviderSegmentQueryProcessor :
+        virtual public BaseQueryProcessor<wm::ProviderSegment, armem::query::data::ProviderSegmentQuery>,
+        virtual public base::query_proc::ProviderSegmentQueryProcessorBase<wm::ProviderSegment>
+    {
+        using Base = BaseQueryProcessor<wm::ProviderSegment, armem::query::data::ProviderSegmentQuery>;
+
+    public:
+        ProviderSegmentQueryProcessor(DataMode dataMode = DataMode::WithData) :
+            Base(dataMode), entityProcessor(dataMode)
+        {}
+
+        using Base::process;
+        data::ProviderSegment processToIce(const armem::query::data::ProviderSegmentQuery& query, const wm::ProviderSegment& providerSegment) const
+        {
+            return toIce<data::ProviderSegment>(process(query, providerSegment));
+        }
+
+    protected:
+        virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override
+        {
+            return entityProcessor.process(q, s);
+        }
+
+    private:
+        EntityQueryProcessor entityProcessor;
+    };
+}
diff --git a/source/RobotAPI/libraries/armem/test/ArMemIceConversionsTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemIceConversionsTest.cpp
index e139931d828f69494299b69fb4bd87677fd40465..a835f39bef74f745b22c4ee167e4755a031fec50 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemIceConversionsTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemIceConversionsTest.cpp
@@ -25,7 +25,8 @@
 #define ARMARX_BOOST_TEST
 
 #include <RobotAPI/Test.h>
-#include "../core/ice_conversions.h"
+#include "../core/workingmemory/ice_conversions.h"
+
 
 #include <iostream>
 #include <SimoxUtility/algorithm/get_map_keys_values.h>
@@ -37,11 +38,11 @@ namespace aron = armarx::aron;
 
 BOOST_AUTO_TEST_CASE(test_entity)
 {
-    armem::Entity entity("entity");
+    armem::wm::Entity entity("entity");
 
     std::vector<armem::Time> expectedTimestamps;
 
-    armem::EntitySnapshot snapshot;
+    armem::wm::EntitySnapshot snapshot;
     snapshot.time() = armem::Time::milliSeconds(100);
     expectedTimestamps.push_back(snapshot.time());
     entity.addSnapshot(snapshot);
@@ -53,13 +54,19 @@ BOOST_AUTO_TEST_CASE(test_entity)
     armem::data::EntityPtr ice;
     armem::toIce(ice, entity);
 
-    armem::Entity entityOut;
+    BOOST_CHECK_EQUAL(ice->id.memoryName, entity.id().memoryName);
+    BOOST_CHECK_EQUAL(ice->id.coreSegmentName, entity.id().coreSegmentName);
+    BOOST_CHECK_EQUAL(ice->id.providerSegmentName, entity.id().providerSegmentName);
+    BOOST_CHECK_EQUAL(ice->id.entityName, entity.id().entityName);
+
+    BOOST_CHECK_EQUAL(ice->history.size(), entity.history().size());
+
+    armem::wm::Entity entityOut;
     armem::fromIce(ice, entityOut);
 
-    BOOST_CHECK_EQUAL(entityOut.history.size(), entity.history.size());
+    BOOST_CHECK_EQUAL(entityOut.history().size(), entity.history().size());
 
     std::vector<armem::Time> timestamps = entityOut.getTimestamps();
-    BOOST_CHECK_EQUAL_COLLECTIONS(timestamps.begin(), timestamps.end(),
-                                  expectedTimestamps.begin(), expectedTimestamps.end());
+    BOOST_CHECK_EQUAL_COLLECTIONS(timestamps.begin(), timestamps.end(), expectedTimestamps.begin(), expectedTimestamps.end());
 }
 
diff --git a/source/RobotAPI/libraries/armem/test/ArMemLTMTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemLTMTest.cpp
index dea566c5ee235868f23334f381095e1949f4f044..f6271553eddfe787162841ba7c428f7f74aa1626 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemLTMTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemLTMTest.cpp
@@ -25,16 +25,19 @@
 #define ARMARX_BOOST_TEST
 
 #include <RobotAPI/Test.h>
-#include "../core/Memory.h"
+#include "../core/workingmemory/Memory.h"
 #include "../core/error.h"
 
 #include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h>
 #include <RobotAPI/libraries/aron/core/navigator/type/AllNavigators.h>
-#include <RobotAPI/libraries/armem/core/io/MemoryFileSystemStorage.h>
 #include <RobotAPI/libraries/aron/core/Randomizer.h>
 
 #include <RobotAPI/libraries/aron/core/Debug.h>
 
+#include "../core/longtermmemory/Memory.h"
+
+//#include "../core/io/diskWriter/NlohmannJSON/NlohmannJSONDiskWriter.h"
+
 #include <filesystem>
 #include <iostream>
 
@@ -46,15 +49,26 @@ namespace ArMemLTMTest
 {
     struct Fixture
     {
-        fs::path storagePath = "./TestMemoryExport";
+        fs::path storagePath = "/tmp/TestMemoryExport";
 
         Fixture()
         {
             clearStoragePath();
+            assureStoragePath();
         }
         ~Fixture()
         {
-            clearStoragePath();
+            //clearStoragePath();
+        }
+
+        void assureStoragePath()
+        {
+            if (!fs::is_directory(storagePath))
+            {
+                fs::create_directory(storagePath);
+            }
+            BOOST_TEST_INFO("Storage path: " << storagePath);
+            BOOST_REQUIRE(fs::exists(storagePath) && fs::is_directory(storagePath));
         }
 
         void clearStoragePath()
@@ -68,7 +82,7 @@ namespace ArMemLTMTest
         }
 
 
-        static armem::Memory setupMemoryWithType(
+        static armem::wm::Memory setupMemoryWithType(
             const std::string& memoryName,
             const aron::typenavigator::ObjectNavigatorPtr& t1,
             const aron::typenavigator::ObjectNavigatorPtr& t2,
@@ -77,19 +91,19 @@ namespace ArMemLTMTest
         {
             aron::Randomizer r;
 
-            armem::Memory memory(memoryName);
+            armem::wm::Memory memory(memoryName);
             BOOST_CHECK_EQUAL(memory.name(), memoryName);
 
-            armem::CoreSegment& coreSegment = memory.addCoreSegment("TestCoreSegment");
+            armem::wm::CoreSegment& coreSegment = memory.addCoreSegment("TestCoreSegment");
             BOOST_CHECK_EQUAL(coreSegment.name(), "TestCoreSegment");
             BOOST_CHECK(memory.hasCoreSegment(coreSegment.name()));
 
-            armem::ProviderSegment& providerSegment = coreSegment.addProviderSegment("TestProvider");
+            armem::wm::ProviderSegment& providerSegment = coreSegment.addProviderSegment("TestProvider");
             BOOST_CHECK_EQUAL(providerSegment.name(), "TestProvider");
             BOOST_CHECK(coreSegment.hasProviderSegment(providerSegment.name()));
 
-            coreSegment.aronType() = t1;
-            providerSegment.aronType() = t2;
+            //coreSegment.aronType() = t1;
+            //providerSegment.aronType() = t2;
 
             aron::typenavigator::ObjectNavigatorPtr t = t2 != nullptr ? t2 : t1;
 
@@ -108,7 +122,7 @@ namespace ArMemLTMTest
                 update.instancesData = q;
                 update.timeCreated = armem::Time::now();
                 BOOST_CHECK_NO_THROW(providerSegment.update(update));
-                BOOST_CHECK_EQUAL(providerSegment.entities.size(), 1);
+                BOOST_CHECK_EQUAL(providerSegment.entities().size(), 1);
             }
             BOOST_CHECK(providerSegment.hasEntity("TestEntity"));
 
@@ -128,186 +142,72 @@ namespace ArMemLTMTest
 
             return t;
         }
-    };
-}
 
-BOOST_FIXTURE_TEST_SUITE(ArMemLTMTest, Fixture)
+        template <class TypeNavigatorT>
+        void run(const std::string& memoryName, const std::string& memberNamePrefix)
+        {
+            /*aron::typenavigator::ObjectNavigatorPtr t = makeType<TypeNavigatorT>(memberNamePrefix);
+            armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
 
-/*
-BOOST_AUTO_TEST_CASE(test_memory_export__easy_int_setup)
-{
-    std::string memoryName = "TestMemory_IntSetup";
+            // create reader and writer
+            armem::io::DiskWriterPtr w = std::make_shared<armem::io::NlohmannJSONDiskWriter>();
 
-    aron::typenavigator::ObjectNavigatorPtr t = makeType<aron::typenavigator::AronIntTypeNavigator>("theInt");
-    armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
+            // export memory
+            BOOST_REQUIRE(fs::exists(storagePath));
+            armem::io::DiskMemory dMem(memory);
+            std::string mfs_str = dMem.toString();
 
-    // export memory
-    BOOST_REQUIRE(!fs::exists(storagePath));
-    armem::io::FileSystemMemoryManager mfs(storagePath, true);
-    mfs.writeOnDisk(memory);
+            armem::io::DiskMemory dMem2();
+            std::string mfs2_str = dMem2.toString();
 
-    std::string mfs_str = mfs.toString();
+            //std::cout << "MFS1: " << std::endl;
+            //std::cout << mfs_str << std::endl;
+            //std::cout << "MFS2: " << std::endl;
+            //std::cout << mfs2_str << std::endl;
+            BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
 
-    armem::io::FileSystemMemoryManager mfs2(storagePath);
-    mfs2.update();
+            armem::Memory memory2 = dMem2.toMemory();
+            memory2.name() = memoryName;
 
-    std::string mfs2_str = mfs2.toString();
+            BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);*/
+        }
+    };
+}
 
-    //std::cout << "MFS1: " << std::endl;
-    //std::cout << mfs_str << std::endl;
-    //std::cout << "MFS2: " << std::endl;
-    //std::cout << mfs2_str << std::endl;
-    BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
+BOOST_FIXTURE_TEST_SUITE(ArMemLTMTest, Fixture)
 
-    armem::Memory memory2 = mfs.readMemoryFromDisk(memoryName);
-    BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);
+
+BOOST_AUTO_TEST_CASE(test_memory_export__easy_int_setup)
+{
+    run<aron::typenavigator::IntNavigator>("TestMemory_IntSetup", "theInt");
 }
 
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_long_setup)
 {
-    std::string memoryName = "TestMemory_LongSetup";
-
-    aron::typenavigator::ObjectNavigatorPtr t = makeType<aron::typenavigator::AronLongTypeNavigator>("theLong");
-    armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
-
-    // export memory
-    BOOST_REQUIRE(!fs::exists(storagePath));
-    armem::io::FileSystemMemoryManager mfs(storagePath, true);
-    mfs.writeOnDisk(memory);
-
-    std::string mfs_str = mfs.toString();
-
-    armem::io::FileSystemMemoryManager mfs2(storagePath);
-    mfs2.update();
-
-    std::string mfs2_str = mfs2.toString();
-
-    //std::cout << "MFS1: " << std::endl;
-    //std::cout << mfs_str << std::endl;
-    //std::cout << "MFS2: " << std::endl;
-    //std::cout << mfs2_str << std::endl;
-    BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
-
-    armem::Memory memory2 = mfs.readMemoryFromDisk(memoryName);
-    BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);
+    run<aron::typenavigator::LongNavigator>("TestMemory_LongSetup", "theLong");
 }
 
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_float_setup)
 {
-    std::string memoryName = "TestMemory_FloatSetup";
-
-    aron::typenavigator::ObjectNavigatorPtr t = makeType<aron::typenavigator::AronFloatTypeNavigator>("theFloat");
-    armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
-
-    // export memory
-    BOOST_REQUIRE(!fs::exists(storagePath));
-    armem::io::FileSystemMemoryManager mfs(storagePath, true);
-    mfs.writeOnDisk(memory);
-
-    std::string mfs_str = mfs.toString();
-
-    armem::io::FileSystemMemoryManager mfs2(storagePath);
-    mfs2.update();
-
-    std::string mfs2_str = mfs2.toString();
-
-    //std::cout << "MFS1: " << std::endl;
-    //std::cout << mfs_str << std::endl;
-    //std::cout << "MFS2: " << std::endl;
-    //std::cout << mfs2_str << std::endl;
-    BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
-
-    armem::Memory memory2 = mfs.readMemoryFromDisk(memoryName);
-    BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);
+    run<aron::typenavigator::FloatNavigator>("TestMemory_FloatSetup", "theFloat");
 }
 
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_double_setup)
 {
-    std::string memoryName = "TestMemory_DoubleSetup";
-
-    aron::typenavigator::ObjectNavigatorPtr t = makeType<aron::typenavigator::AronDoubleTypeNavigator>("theDouble");
-    armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
-
-    // export memory
-    BOOST_REQUIRE(!fs::exists(storagePath));
-    armem::io::FileSystemMemoryManager mfs(storagePath, true);
-    mfs.writeOnDisk(memory);
-
-    std::string mfs_str = mfs.toString();
-
-    armem::io::FileSystemMemoryManager mfs2(storagePath);
-    mfs2.update();
-
-    std::string mfs2_str = mfs2.toString();
-
-    //std::cout << "MFS1: " << std::endl;
-    //std::cout << mfs_str << std::endl;
-    //std::cout << "MFS2: " << std::endl;
-    //std::cout << mfs2_str << std::endl;
-    BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
-
-    armem::Memory memory2 = mfs.readMemoryFromDisk(memoryName);
-    BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);
+    run<aron::typenavigator::DoubleNavigator>("TestMemory_DoubleSetup", "theDouble");
 }
 
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_string_setup)
 {
-    std::string memoryName = "TestMemory_StringSetup";
-
-    aron::typenavigator::ObjectNavigatorPtr t = makeType<aron::typenavigator::AronStringTypeNavigator>("theString");
-    armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
-
-    // export memory
-    BOOST_REQUIRE(!fs::exists(storagePath));
-    armem::io::FileSystemMemoryManager mfs(storagePath, true);
-    mfs.writeOnDisk(memory);
-
-    std::string mfs_str = mfs.toString();
-
-    armem::io::FileSystemMemoryManager mfs2(storagePath);
-    mfs2.update();
-
-    std::string mfs2_str = mfs2.toString();
-
-    //std::cout << "MFS1: " << std::endl;
-    //std::cout << mfs_str << std::endl;
-    //std::cout << "MFS2: " << std::endl;
-    //std::cout << mfs2_str << std::endl;
-    BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
-
-    armem::Memory memory2 = mfs.readMemoryFromDisk(memoryName);
-    BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);
+    run<aron::typenavigator::StringNavigator>("TestMemory_StringSetup", "theString");
 }
 
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_bool_setup)
 {
-    std::string memoryName = "TestMemory_BoolSetup";
-
-    aron::typenavigator::ObjectNavigatorPtr t = makeType<aron::typenavigator::AronBoolTypeNavigator>("theBool");
-    armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
-
-    // export memory
-    BOOST_REQUIRE(!fs::exists(storagePath));
-    armem::io::FileSystemMemoryManager mfs(storagePath, true);
-    mfs.writeOnDisk(memory);
-
-    std::string mfs_str = mfs.toString();
-
-    armem::io::FileSystemMemoryManager mfs2(storagePath);
-    mfs2.update();
-
-    std::string mfs2_str = mfs2.toString();
-
-    //std::cout << "MFS1: " << std::endl;
-    //std::cout << mfs_str << std::endl;
-    //std::cout << "MFS2: " << std::endl;
-    //std::cout << mfs2_str << std::endl;
-    BOOST_CHECK_EQUAL(mfs_str == mfs2_str, true);
-
-    armem::Memory memory2 = mfs.readMemoryFromDisk(memoryName);
-    BOOST_CHECK_EQUAL(memory.equalsDeep(memory2), true);
+    run<aron::typenavigator::BoolNavigator>("TestMemory_BoolSetup", "theBool");
 }
 
+/*
 BOOST_AUTO_TEST_CASE(test_memory_export__easy_rainer_setup)
 {
     std::string memoryName = "TestMemory_RainerSetup";
@@ -316,17 +216,17 @@ BOOST_AUTO_TEST_CASE(test_memory_export__easy_rainer_setup)
     t->setObjectName("TestRainerType1");
 
     aron::typenavigator::DictNavigatorPtr tm1(new aron::typenavigator::DictNavigator(aron::Path()));
-    aron::typenavigator::AronFloatTypeNavigatorPtr tm1m1(new aron::typenavigator::AronFloatTypeNavigator(aron::Path()));
+    aron::typenavigator::FloatNavigatorPtr tm1m1(new aron::typenavigator::FloatNavigator(aron::Path()));
     tm1->setAcceptedType(tm1m1);
-    aron::typenavigator::AronStringTypeNavigatorPtr tm2(new aron::typenavigator::AronStringTypeNavigator(aron::Path()));
+    aron::typenavigator::StringNavigatorPtr tm2(new aron::typenavigator::StringNavigator(aron::Path()));
     aron::typenavigator::DictNavigatorPtr tm3(new aron::typenavigator::DictNavigator(aron::Path()));
-    aron::typenavigator::AronStringTypeNavigatorPtr tm3m1(new aron::typenavigator::AronStringTypeNavigator(aron::Path()));
+    aron::typenavigator::StringNavigatorPtr tm3m1(new aron::typenavigator::StringNavigator(aron::Path()));
     tm3->setAcceptedType(tm3m1);
-    aron::typenavigator::AronStringTypeNavigatorPtr tm4(new aron::typenavigator::AronStringTypeNavigator(aron::Path()));
-    t->addAcceptedType("float_params", tm1);
-    t->addAcceptedType("name", tm2);
-    //t->addAcceptedType("string_params", tm3);
-    t->addAcceptedType("type", tm4);
+    aron::typenavigator::StringNavigatorPtr tm4(new aron::typenavigator::StringNavigator(aron::Path()));
+    t->addMemberType("float_params", tm1);
+    t->addMemberType("name", tm2);
+    //t->addMemberType("string_params", tm3);
+    t->addMemberType("type", tm4);
 
     armem::Memory memory = setupMemoryWithType(memoryName, t, nullptr, 15, 1);
 
diff --git a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
index b7ba95c633d7d561024b848c1afa862e0bc51caa..a30132549aacc14b80fd913dc83b302ba917a6c2 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemMemoryTest.cpp
@@ -26,13 +26,15 @@
 
 #include <RobotAPI/Test.h>
 
-#include "../core/Memory.h"
-#include "../core/error.h"
-
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/diskmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/error.h>
 
 #include <iostream>
 #include <RobotAPI/libraries/aron/core/navigator/data/container/Dict.h>
 
+
 namespace armem = armarx::armem;
 namespace aron = armarx::aron;
 
@@ -76,11 +78,33 @@ BOOST_AUTO_TEST_CASE(test_time_to_string)
 }
 
 
+BOOST_AUTO_TEST_CASE(test_key_ctors)
+{
+    armem::wm::EntityInstance instance(10);
+    BOOST_CHECK_EQUAL(instance.index(), 10);
+
+    armem::wm::EntitySnapshot snapshot(armem::Time::milliSeconds(100));
+    BOOST_CHECK_EQUAL(snapshot.time(), armem::Time::milliSeconds(100));
+
+    armem::wm::Entity entity("entity");
+    BOOST_CHECK_EQUAL(entity.name(), "entity");
+
+    armem::wm::ProviderSegment provSeg("provSeg");
+    BOOST_CHECK_EQUAL(provSeg.name(), "provSeg");
+
+    armem::wm::CoreSegment coreSeg("coreSeg");
+    BOOST_CHECK_EQUAL(coreSeg.name(), "coreSeg");
+
+    armem::wm::Memory memory("memory");
+    BOOST_CHECK_EQUAL(memory.name(), "memory");
+}
+
+
 BOOST_AUTO_TEST_CASE(test_segment_setup)
 {
     armem::EntityUpdate update;
 
-    armem::Memory memory("Memory");
+    armem::wm::Memory memory("Memory");
     BOOST_CHECK_EQUAL(memory.name(), "Memory");
     {
         update.entityID = armem::MemoryID::fromString("OtherMemory/SomeSegment");
@@ -89,7 +113,7 @@ BOOST_AUTO_TEST_CASE(test_segment_setup)
         BOOST_CHECK_THROW(memory.update(update), armem::error::MissingEntry);
     }
 
-    armem::CoreSegment& coreSegment = memory.addCoreSegment("ImageRGB");
+    armem::wm::CoreSegment& coreSegment = memory.addCoreSegment("ImageRGB");
     BOOST_CHECK_EQUAL(coreSegment.name(), "ImageRGB");
     BOOST_CHECK(memory.hasCoreSegment(coreSegment.name()));
     {
@@ -99,7 +123,7 @@ BOOST_AUTO_TEST_CASE(test_segment_setup)
         BOOST_CHECK_THROW(coreSegment.update(update), armem::error::MissingEntry);
     }
 
-    armem::ProviderSegment& providerSegment = coreSegment.addProviderSegment("SomeRGBImageProvider");
+    armem::wm::ProviderSegment& providerSegment = coreSegment.addProviderSegment("SomeRGBImageProvider");
     BOOST_CHECK_EQUAL(providerSegment.name(), "SomeRGBImageProvider");
     BOOST_CHECK(coreSegment.hasProviderSegment(providerSegment.name()));
     {
@@ -119,17 +143,17 @@ BOOST_AUTO_TEST_CASE(test_segment_setup)
     update.timeCreated = armem::Time::milliSeconds(1000);
     BOOST_CHECK_NO_THROW(providerSegment.update(update));
 
-    BOOST_CHECK_EQUAL(providerSegment.entities.size(), 1);
+    BOOST_CHECK_EQUAL(providerSegment.entities().size(), 1);
     BOOST_CHECK(providerSegment.hasEntity("image"));
     BOOST_CHECK(!providerSegment.hasEntity("other_image"));
 
-    armem::Entity& entity = providerSegment.getEntity("image");
+    armem::wm::Entity& entity = providerSegment.getEntity("image");
     BOOST_CHECK_EQUAL(entity.name(), "image");
-    BOOST_CHECK_EQUAL(entity.history.size(), 1);
-    BOOST_CHECK_EQUAL(entity.history.count(update.timeCreated), 1);
+    BOOST_CHECK_EQUAL(entity.history().size(), 1);
+    BOOST_CHECK_EQUAL(entity.history().count(update.timeCreated), 1);
 
-    armem::EntitySnapshot& entitySnapshot = entity.history.at(update.timeCreated);
-    BOOST_CHECK_EQUAL(entitySnapshot.instances.size(), update.instancesData.size());
+    armem::wm::EntitySnapshot& entitySnapshot = entity.history().at(update.timeCreated);
+    BOOST_CHECK_EQUAL(entitySnapshot.instances().size(), update.instancesData.size());
 
 
     // Another update (on memory).
@@ -137,16 +161,16 @@ BOOST_AUTO_TEST_CASE(test_segment_setup)
     update.instancesData = { std::make_shared<aron::datanavigator::DictNavigator>() };
     update.timeCreated = armem::Time::milliSeconds(2000);
     memory.update(update);
-    BOOST_CHECK_EQUAL(entity.history.size(), 2);
-    BOOST_CHECK_EQUAL(entity.history.count(update.timeCreated), 1);
-    BOOST_CHECK_EQUAL(entity.history.at(update.timeCreated).instances.size(), update.instancesData.size());
+    BOOST_CHECK_EQUAL(entity.history().size(), 2);
+    BOOST_CHECK_EQUAL(entity.history().count(update.timeCreated), 1);
+    BOOST_CHECK_EQUAL(entity.history().at(update.timeCreated).instances().size(), update.instancesData.size());
 
 
     // A third update (on entity).
     update.instancesData = { std::make_shared<aron::datanavigator::DictNavigator>() };
     update.timeCreated = armem::Time::milliSeconds(3000);
     entity.update(update);
-    BOOST_CHECK_EQUAL(entity.history.size(), 3);
+    BOOST_CHECK_EQUAL(entity.history().size(), 3);
 
 }
 
@@ -154,7 +178,7 @@ BOOST_AUTO_TEST_CASE(test_segment_setup)
 
 BOOST_AUTO_TEST_CASE(test_history_size_in_entity)
 {
-    armem::Entity entity("entity");
+    armem::wm::Entity entity("entity");
 
     armem::EntityUpdate update;
     update.entityID.entityName = entity.name();
@@ -166,38 +190,38 @@ BOOST_AUTO_TEST_CASE(test_history_size_in_entity)
     entity.update(update);
     update.timeCreated = armem::Time::milliSeconds(3000);
     entity.update(update);
-    BOOST_CHECK_EQUAL(entity.history.size(), 3);
+    BOOST_CHECK_EQUAL(entity.history().size(), 3);
 
     // Now with maximum history size.
     entity.setMaxHistorySize(2);
-    BOOST_CHECK_EQUAL(entity.history.size(), 2);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(1000)), 0);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(2000)), 1);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(3000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().size(), 2);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(1000)), 0);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(2000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(3000)), 1);
 
 
     update.timeCreated = armem::Time::milliSeconds(4000);
     entity.update(update);
-    BOOST_CHECK_EQUAL(entity.history.size(), 2);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(2000)), 0);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(3000)), 1);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(4000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().size(), 2);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(2000)), 0);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(3000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(4000)), 1);
 
     // Disable maximum history size.
     entity.setMaxHistorySize(-1);
 
     update.timeCreated = armem::Time::milliSeconds(5000);
     entity.update(update);
-    BOOST_CHECK_EQUAL(entity.history.size(), 3);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(3000)), 1);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(4000)), 1);
-    BOOST_CHECK_EQUAL(entity.history.count(armem::Time::milliSeconds(5000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().size(), 3);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(3000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(4000)), 1);
+    BOOST_CHECK_EQUAL(entity.history().count(armem::Time::milliSeconds(5000)), 1);
 }
 
 
 BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment)
 {
-    armem::ProviderSegment providerSegment("SomeRGBImageProvider");
+    armem::wm::ProviderSegment providerSegment("SomeRGBImageProvider");
 
     armem::EntityUpdate update;
     update.entityID.providerSegmentName = providerSegment.name();
@@ -220,22 +244,22 @@ BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment)
     update.timeCreated = armem::Time::milliSeconds(4000);
     providerSegment.update(update);
 
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history.size(), 3);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history.size(), 4);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 3);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 4);
 
 
     // Employ maximum history size.
     providerSegment.setMaxHistorySize(3);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history.size(), 3);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history.size(), 3);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 3);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 3);
 
     providerSegment.setMaxHistorySize(2);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history.size(), 2);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history.size(), 2);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 2);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 2);
 
     providerSegment.setMaxHistorySize(3);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history.size(), 2);
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history.size(), 2);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("A").history().size(), 2);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("B").history().size(), 2);
 
     // Add new entity.
     providerSegment.setMaxHistorySize(2);
@@ -249,9 +273,9 @@ BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment)
     providerSegment.update(update);
 
     // Check correctly inherited history size.
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("C").maxHistorySize, 2);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("C").getMaxHistorySize(), 2);
     // Check actual history size.
-    BOOST_CHECK_EQUAL(providerSegment.getEntity("C").history.size(), 2);
+    BOOST_CHECK_EQUAL(providerSegment.getEntity("C").history().size(), 2);
 
     // Remove maximum.
     providerSegment.setMaxHistorySize(-1);
@@ -262,6 +286,48 @@ BOOST_AUTO_TEST_CASE(test_history_size_in_provider_segment)
         update.entityID.entityName = name;
         update.timeCreated = armem::Time::milliSeconds(5000);
         providerSegment.update(update);
-        BOOST_CHECK_EQUAL(providerSegment.getEntity(name).history.size(), 3);
+        BOOST_CHECK_EQUAL(providerSegment.getEntity(name).history().size(), 3);
     }
 }
+
+
+template <class T>
+void test_the_copy_move_ctors_ops()
+{
+    T t1;
+    {
+        T t2 { t1 };
+        t2 = t1;
+    }
+    {
+        T t2 { std::move(t1) };
+        t2 = std::move(t1);
+    }
+}
+
+
+BOOST_AUTO_TEST_CASE(test_copy_move_ctors_ops)
+{
+    test_the_copy_move_ctors_ops<armem::wm::EntityInstance>();
+    test_the_copy_move_ctors_ops<armem::wm::EntitySnapshot>();
+    test_the_copy_move_ctors_ops<armem::wm::Entity>();
+    test_the_copy_move_ctors_ops<armem::wm::ProviderSegment>();
+    test_the_copy_move_ctors_ops<armem::wm::CoreSegment>();
+    test_the_copy_move_ctors_ops<armem::wm::Memory>();
+
+    test_the_copy_move_ctors_ops<armem::ltm::EntityInstance>();
+    test_the_copy_move_ctors_ops<armem::ltm::EntitySnapshot>();
+    test_the_copy_move_ctors_ops<armem::ltm::Entity>();
+    test_the_copy_move_ctors_ops<armem::ltm::ProviderSegment>();
+    test_the_copy_move_ctors_ops<armem::ltm::CoreSegment>();
+    test_the_copy_move_ctors_ops<armem::ltm::Memory>();
+
+    test_the_copy_move_ctors_ops<armem::d_ltm::EntityInstance>();
+    test_the_copy_move_ctors_ops<armem::d_ltm::EntitySnapshot>();
+    test_the_copy_move_ctors_ops<armem::d_ltm::Entity>();
+    test_the_copy_move_ctors_ops<armem::d_ltm::ProviderSegment>();
+    test_the_copy_move_ctors_ops<armem::d_ltm::CoreSegment>();
+    test_the_copy_move_ctors_ops<armem::d_ltm::Memory>();
+
+    BOOST_CHECK(true);
+}
diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp
index 5b9a09f097cc55f3e8343b55c58d0aa09109e890..535735b09eeb61d41cdf0dbaf658cebcdb08f4db 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp
@@ -27,7 +27,7 @@
 #include <RobotAPI/Test.h>
 #include "../client/query/Builder.h"
 #include "../client/query/query_fns.h"
-#include "../core/ice_conversions.h"
+#include "../core/workingmemory/ice_conversions.h"
 
 #include <iostream>
 
diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
index b35fb39452fd014e7d9a7bec6353ca181b5a14e2..42d357b005ae9c4c4663bc72fa91ed4fc459b78a 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp
@@ -25,7 +25,7 @@
 #define ARMARX_BOOST_TEST
 
 #include <RobotAPI/Test.h>
-#include "../server/query_proc/EntityQueryProcessor.h"
+#include "../server/query_proc/workingmemory/EntityQueryProcessor.h"
 #include "../error.h"
 
 
@@ -38,7 +38,7 @@
 namespace armem = armarx::armem;
 namespace aron = armarx::aron;
 namespace query = armarx::armem::query::data;
-using EntityQueryProcessor = armarx::armem::query_proc::EntityQueryProcessor;
+using EntityQueryProcessor = armarx::armem::wm::query_proc::EntityQueryProcessor;
 
 
 namespace ArMemQueryTest
@@ -50,19 +50,19 @@ namespace ArMemQueryTest
 
     struct Fixture
     {
-        armem::Entity entity;
+        armem::wm::Entity entity;
 
-        armem::query_proc::EntityQueryProcessor processor;
+        armem::wm::query_proc::EntityQueryProcessor processor;
         query::EntityQueryPtr entityQuery;
 
-        std::vector<armem::Entity> results;
+        std::vector<armem::wm::Entity> results;
 
 
         Fixture()
         {
-            entity = armem::Entity("entity");
+            entity = armem::wm::Entity("entity");
 
-            armem::EntitySnapshot snapshot;
+            armem::wm::EntitySnapshot snapshot;
             snapshot.time() = armem::Time::microSeconds(1000);
             entity.addSnapshot(snapshot);
             snapshot.time() = armem::Time::microSeconds(2000);
@@ -119,12 +119,12 @@ BOOST_AUTO_TEST_CASE(test_entity_Single_latest)
     addResults(query::entity::Single());
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
         BOOST_CHECK_EQUAL(result.size(), 1);
-        BOOST_CHECK_EQUAL(result.history.begin()->second.time(), entity.getLatestSnapshot().time());
-        BOOST_CHECK_NE(&result.history.begin()->second, &entity.history.rbegin()->second);
+        BOOST_CHECK_EQUAL(result.history().begin()->second.time(), entity.getLatestSnapshot().time());
+        BOOST_CHECK_NE(&result.history().begin()->second, &entity.history().rbegin()->second);
     }
 }
 
@@ -134,11 +134,11 @@ BOOST_AUTO_TEST_CASE(test_entity_Single_existing)
     addResults(query::entity::Single { 3000 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
         BOOST_CHECK_EQUAL(result.size(), 1);
-        BOOST_CHECK_EQUAL(result.history.begin()->second.time(), armem::Time::microSeconds(3000));
+        BOOST_CHECK_EQUAL(result.history().begin()->second.time(), armem::Time::microSeconds(3000));
     }
 }
 
@@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(test_entity_Single_non_existing)
     addResults(query::entity::Single { 3500 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
         BOOST_CHECK_EQUAL(result.size(), 0);
@@ -161,12 +161,12 @@ BOOST_AUTO_TEST_CASE(test_entity_All)
     addResults(query::entity::All());
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
         BOOST_CHECK_EQUAL(result.size(), entity.size());
-        auto jt = entity.history.begin();
-        for (auto it = result.history.begin(); it != result.history.end(); ++it, ++jt)
+        auto jt = entity.history().begin();
+        for (auto it = result.history().begin(); it != result.history().end(); ++it, ++jt)
         {
             BOOST_CHECK_EQUAL(it->first, jt->first);
             BOOST_CHECK_EQUAL(it->second.time(), jt->second.time());
@@ -182,13 +182,13 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_slice)
     addResults(query::entity::TimeRange{ 1500, 3500 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), 2);
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
         std::vector<armem::Time> expected
         {
             armem::Time::microSeconds(2000), armem::Time::microSeconds(3000)
@@ -203,13 +203,13 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_exact)
     addResults(query::entity::TimeRange{ 2000, 4000 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), 3);
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
         std::vector<armem::Time> expected
         {
             armem::Time::microSeconds(2000), armem::Time::microSeconds(3000), armem::Time::microSeconds(4000)
@@ -224,14 +224,14 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_all)
     addResults(query::entity::TimeRange{ -1, -1 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), entity.size());
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
-        std::vector<armem::Time> expected = simox::alg::get_keys(entity.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
+        std::vector<armem::Time> expected = simox::alg::get_keys(entity.history());
         BOOST_CHECK_EQUAL_COLLECTIONS(times.begin(), times.end(), expected.begin(), expected.end());
     }
 }
@@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_empty)
     addResults(query::entity::TimeRange{ 6000, 1000 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
@@ -257,13 +257,13 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_from_start)
     addResults(query::entity::TimeRange{ -1, 2500 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), 2);
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
         std::vector<armem::Time> expected
         {
             armem::Time::microSeconds(1000), armem::Time::microSeconds(2000)
@@ -278,13 +278,13 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_to_end)
     addResults(query::entity::TimeRange{ 2500, -1 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), 3);
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
         std::vector<armem::Time> expected
         {
             armem::Time::microSeconds(3000), armem::Time::microSeconds(4000), armem::Time::microSeconds(5000)
@@ -332,14 +332,14 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_all_default)
     addResults(query::entity::IndexRange(0, -1));
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), entity.size());
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
-        std::vector<armem::Time> expected = simox::alg::get_keys(entity.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
+        std::vector<armem::Time> expected = simox::alg::get_keys(entity.history());
         BOOST_CHECK_EQUAL_COLLECTIONS(times.begin(), times.end(), expected.begin(), expected.end());
     }
 
@@ -355,13 +355,13 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_slice)
     addResults(query::entity::IndexRange{ -4, -2 });
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
         BOOST_CHECK_EQUAL(result.size(), 3);
 
-        std::vector<armem::Time> times = simox::alg::get_keys(result.history);
+        std::vector<armem::Time> times = simox::alg::get_keys(result.history());
         std::vector<armem::Time> expected
         {
             armem::Time::microSeconds(2000), armem::Time::microSeconds(3000), armem::Time::microSeconds(4000)
@@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_empty_range)
 
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
 
@@ -405,7 +405,7 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_empty_entity)
 
     BOOST_REQUIRE_GT(results.size(), 0);
 
-    for (const armem::Entity& result : results)
+    for (const armem::wm::Entity& result : results)
     {
         BOOST_CHECK_EQUAL(result.name(), entity.name());
         BOOST_CHECK_EQUAL(result.size(), 0);
diff --git a/source/RobotAPI/libraries/armem/util/util.h b/source/RobotAPI/libraries/armem/util/util.h
index 4fa457ab679a0f970974101a53ba04a92b3fc241..91a31651cf055572dd6c3e8fcbb27163e4d30918 100644
--- a/source/RobotAPI/libraries/armem/util/util.h
+++ b/source/RobotAPI/libraries/armem/util/util.h
@@ -26,8 +26,8 @@
 #include <vector>
 #include <optional>
 
-#include <RobotAPI/libraries/armem/core/Entity.h>
-#include <RobotAPI/libraries/armem/core/EntityInstance.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Entity.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h>
 #include <RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h>
 
 namespace armarx::armem
@@ -41,7 +41,7 @@ namespace armarx::armem
      * @return std::optional<AronClass>
      */
     template <typename AronClass>
-    std::optional<AronClass> tryCast(const EntityInstance& item)
+    std::optional<AronClass> tryCast(const wm::EntityInstance& item)
     {
         static_assert(std::is_base_of<armarx::aron::cppcodegenerator::AronCppClass,
                       AronClass>::value);
@@ -67,7 +67,7 @@ namespace armarx::armem
      */
     template <typename AronClass>
     std::vector<AronClass>
-    allOfType(const std::map<std::string, Entity>& entities)
+    allOfType(const std::map<std::string, wm::Entity>& entities)
     {
         static_assert(std::is_base_of<armarx::aron::cppcodegenerator::AronCppClass,
                       AronClass>::value);
@@ -77,9 +77,9 @@ namespace armarx::armem
         // loop over all entities and their snapshots
         for (const auto &[s, entity] : entities)
         {
-            for (const auto &[ss, entitySnapshot] : entity.history)
+            for (const auto &[ss, entitySnapshot] : entity.history())
             {
-                for (const auto& entityInstance : entitySnapshot.instances)
+                for (const auto& entityInstance : entitySnapshot.instances())
                 {
                     const auto o = tryCast<AronClass>(entityInstance);
 
@@ -113,7 +113,7 @@ namespace armarx::armem
      * @return vector of "pred"-transformed elements that can be cast to AronClass
      */
     template <typename AronClass>
-    auto transformAllOfType(const std::map<std::string, Entity>& entities,
+    auto transformAllOfType(const std::map<std::string, wm::Entity>& entities,
                             auto pred) -> std::vector<decltype(pred(AronClass()))>
     {
         static_assert(std::is_base_of<armarx::aron::cppcodegenerator::AronCppClass,
@@ -129,16 +129,16 @@ namespace armarx::armem
         // loop over all entities and their snapshots
         for (const auto &[s, entity] : entities)
         {
-            if (entity.history.empty())
+            if (entity.history().empty())
             {
                 ARMARX_WARNING << "Empty history for " << s;
             }
 
-            ARMARX_INFO << "History size: " << entity.history.size();
+            ARMARX_INFO << "History size: " << entity.history().size();
 
-            for (const auto &[ss, entitySnapshot] : entity.history)
+            for (const auto &[ss, entitySnapshot] : entity.history())
             {
-                for (const auto& entityInstance : entitySnapshot.instances)
+                for (const auto& entityInstance : entitySnapshot.instances())
                 {
                     const auto o = tryCast<AronClass>(entityInstance);
 
@@ -153,4 +153,4 @@ namespace armarx::armem
         return outV;
     }
 
-} // namespace armarx::armem
\ No newline at end of file
+} // namespace armarx::armem
diff --git a/source/RobotAPI/libraries/armem_gui/CMakeLists.txt b/source/RobotAPI/libraries/armem_gui/CMakeLists.txt
index 3a448d8735b7ba46487e24e3f0d7a33aec0654be..d90a90aa04a3fcc2c3d891bfab8727a991522f44 100644
--- a/source/RobotAPI/libraries/armem_gui/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem_gui/CMakeLists.txt
@@ -17,6 +17,7 @@ set(SOURCES
     MemoryViewer.cpp
 
     PeriodicUpdateWidget.cpp
+    LTMControlWidget.cpp
     gui_utils.cpp
     lifecycle.cpp
 
@@ -48,6 +49,7 @@ set(HEADERS
     MemoryViewer.h
 
     PeriodicUpdateWidget.h
+    LTMControlWidget.h
     TreeWidgetBuilder.h
     gui_utils.h
     lifecycle.h
diff --git a/source/RobotAPI/libraries/armem_gui/LTMControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/LTMControlWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..257e43d3a3f0df224b4632449c97aa4336c9f184
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_gui/LTMControlWidget.cpp
@@ -0,0 +1,60 @@
+#include "LTMControlWidget.h"
+
+#include <QPushButton>
+#include <QLineEdit>
+#include <QTimer>
+#include <QHBoxLayout>
+
+#include <cmath>
+
+
+namespace armarx::armem::gui
+{
+
+    LTMControlWidget::LTMControlWidget()
+    {
+        setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Fixed);
+
+        QLayout* layout = new QHBoxLayout();
+        this->setLayout(layout);
+
+        const int margin = 0;
+        layout->setContentsMargins(margin, margin, margin, margin);
+
+        _lineEdit = new QLineEdit("/tmp/MemoryExport", this);
+        _exportHereButton = new QPushButton("Export here", this);
+
+        _storeButton = new QPushButton("Store in LTM", this);
+
+        layout->addWidget(_lineEdit);
+        layout->addWidget(_storeButton);
+        layout->addWidget(_exportHereButton);
+
+        // Private connections.
+
+        // Public connections.
+        connect(_storeButton, &QPushButton::pressed, this, &This::store);
+        connect(_exportHereButton, &QPushButton::pressed, this, &This::exportHere);
+    }
+
+    QLineEdit* LTMControlWidget::pathInputBox()
+    {
+        return _lineEdit;
+    }
+
+    QString LTMControlWidget::getEnteredPath()
+    {
+        return _lineEdit->text();
+    }
+
+    QPushButton* LTMControlWidget::storeButton()
+    {
+        return _storeButton;
+    }
+
+    QPushButton* LTMControlWidget::exportHereButton()
+    {
+        return _exportHereButton;
+    }
+}
+
diff --git a/source/RobotAPI/libraries/armem_gui/LTMControlWidget.h b/source/RobotAPI/libraries/armem_gui/LTMControlWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c827b01173aa7b724fcfe7e700691d5a093e36e
--- /dev/null
+++ b/source/RobotAPI/libraries/armem_gui/LTMControlWidget.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <QWidget>
+
+class QPushButton;
+class QLineEdit;
+
+namespace armarx::armem::gui
+{
+
+    class LTMControlWidget : public QWidget
+    {
+        Q_OBJECT
+        using This = LTMControlWidget;
+
+    public:
+
+        LTMControlWidget();
+
+        QLineEdit* pathInputBox();
+        QString getEnteredPath();
+
+        QPushButton* storeButton();
+        QPushButton* exportHereButton();
+
+    public slots:
+
+    signals:
+
+        void store();
+        void exportHere();
+
+    private slots:
+
+
+    signals:
+
+
+    private:
+
+        QLineEdit* _lineEdit;
+
+        QPushButton* _storeButton;
+        QPushButton* _exportHereButton;
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
index 818aa79a6bb4d11cd717d6d58432380330e0f2ae..3f40956a61149b1aca6af0b0fa2a9c3f129a18da 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp
@@ -1,8 +1,10 @@
 #include "MemoryViewer.h"
 
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 #include <RobotAPI/libraries/armem_gui/gui_utils.h>
 
+#include <RobotAPI/libraries/armem/core/diskmemory/Memory.h>
+
 #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h>
 
 #include <ArmarXCore/core/ManagedIceObject.h>
@@ -19,11 +21,13 @@
 #include <QLayout>
 #include <QSettings>
 
+#include <filesystem>
+
 
 namespace armarx::armem::gui
 {
-
     MemoryViewer::MemoryViewer(
+        QBoxLayout* ltmControlWidgetLayout,
         QBoxLayout* updateWidgetLayout,
         QGroupBox* _memoryGroupBox, QLayout* memoryGroupBoxParentLayout,
         QGroupBox* _instanceGroupBox, QLayout* instanceGroupBoxParentLayout,
@@ -34,6 +38,11 @@ namespace armarx::armem::gui
         this->statusLabel = statusLabel;
         this->statusLabel->clear();
 
+        // LTM Control
+        this->ltmControlWidgetLayout = ltmControlWidgetLayout;
+        ltmControlWidget = new armem::gui::LTMControlWidget();
+        ltmControlWidgetLayout->insertWidget(0, ltmControlWidget);
+
         // Update timer
         this->updateWidgetLayout = updateWidgetLayout;
         updateWidget = new armem::gui::PeriodicUpdateWidget(2.0, 60);
@@ -48,6 +57,10 @@ namespace armarx::armem::gui
         this->instanceGroup->setStatusLabel(statusLabel);
         ARMARX_CHECK_NULL(_instanceGroupBox);
 
+        //connect(this, &This::connected, this, &This::updateMemory);
+
+        connect(ltmControlWidget, &armem::gui::LTMControlWidget::store, this, &This::store);
+        connect(ltmControlWidget, &armem::gui::LTMControlWidget::exportHere, this, &This::exportHere);
 
         connect(this, &This::connected, this, &This::updateMemories);
         connect(updateWidget, &armem::gui::PeriodicUpdateWidget::update, this, &This::updateMemories);
@@ -107,6 +120,50 @@ namespace armarx::armem::gui
         emit disconnected();
     }
 
+    void MemoryViewer::store()
+    {
+        TIMING_START(MemoryStore);
+
+        for (auto& [name, reader] : memoryReaders)
+        {
+            data::StoreInput input;
+            input.query = memoryGroup->queryWidget()->queryInput().toIce();
+            reader.readAndStore(input);
+        }
+
+        TIMING_END_STREAM(MemoryStore, ARMARX_VERBOSE);
+    }
+
+    void MemoryViewer::exportHere()
+    {
+        TIMING_START(MemoryExport);
+        QString qs = ltmControlWidget->getEnteredPath();
+        std::string utf8_text = qs.toUtf8().constData();
+
+        ARMARX_IMPORTANT << "Exporting all memories at '" << utf8_text << "'.";
+
+        std::filesystem::path p(utf8_text);
+        if (std::filesystem::is_regular_file(p))
+        {
+            ARMARX_WARNING << "Could not export a memory at '" << utf8_text << "'. Skipping export.";
+            return;
+        }
+
+        std::filesystem::create_directories(p);
+        for (auto& [name, reader] : memoryReaders)
+        {
+            armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput();
+            armem::client::QueryResult result = reader.query(input);
+
+            armem::d_ltm::Memory dMem(name);
+            ARMARX_IMPORTANT << "RELOAD";
+            dMem.reload(p / name);
+            ARMARX_IMPORTANT << "APPEND";
+            dMem.append(result.memory);
+        }
+
+        TIMING_END_STREAM(MemoryExport, ARMARX_VERBOSE);
+    }
 
     void MemoryViewer::updateMemories()
     {
@@ -177,7 +234,7 @@ namespace armarx::armem::gui
             return;
         }
 
-        const std::optional<armem::Memory>& data = memoryData.at(selectedID.memoryName);
+        const std::optional<armem::wm::Memory>& data = memoryData.at(selectedID.memoryName);
 
         if (data)
         {
@@ -186,10 +243,10 @@ namespace armarx::armem::gui
                 return;
             }
             armem::MemoryID id = selectedID;
-            const armem::EntitySnapshot* snapshot = nullptr;
+            const armem::wm::EntitySnapshot* snapshot = nullptr;
             if (!id.hasTimestamp())
             {
-                const armem::Entity& entity = data->getEntity(id);
+                const armem::wm::Entity& entity = data->getEntity(id);
                 if (entity.empty())
                 {
                     return;
@@ -227,7 +284,7 @@ namespace armarx::armem::gui
 
     void MemoryViewer::updateMemoryTree()
     {
-        std::map<std::string, const armem::Memory*> convMap;
+        std::map<std::string, const armem::wm::Memory*> convMap;
         for (auto& [name, data] : memoryData)
         {
             if (data.has_value())
@@ -251,7 +308,6 @@ namespace armarx::armem::gui
         }
     }
 
-
     const static std::string CONFIG_KEY_MEMORY = "MemoryViewer.MemoryNameSystem";
     const static std::string CONFIG_KEY_DEBUG_OBSERVER = "MemoryViewer.DebugObserverName";
 
@@ -271,6 +327,7 @@ namespace armarx::armem::gui
         dialog->addProxyFinder<armarx::armem::mns::MemoryNameSystemInterfacePrx>({CONFIG_KEY_MEMORY, "MemoryNameSystem", "*"});
         dialog->addProxyFinder<armarx::DebugObserverInterfacePrx>({CONFIG_KEY_DEBUG_OBSERVER, "Debug Observer", "DebugObserver"});
     }
+
     void MemoryViewer::readConfigDialog(SimpleConfigDialog* dialog)
     {
         mnsName = dialog->getProxyName(CONFIG_KEY_MEMORY);
diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h
index 5c8f4b2f182f798a3c076a89e6a30ff24d10050c..c2c2e6f4c7d251f23f19cb2f7275878940a603d5 100644
--- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h
+++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h
@@ -13,7 +13,7 @@
 #include <RobotAPI/libraries/armem_gui/instance/GroupBox.h>
 #include <RobotAPI/libraries/armem_gui/memory/GroupBox.h>
 #include <RobotAPI/libraries/armem_gui/PeriodicUpdateWidget.h>
-
+#include <RobotAPI/libraries/armem_gui/LTMControlWidget.h>
 
 class QBoxLayout;
 class QDialog;
@@ -44,6 +44,7 @@ namespace armarx::armem::gui
     public:
 
         MemoryViewer(
+            QBoxLayout* ltmControlWidgetLayout,
             QBoxLayout* updateWidgetLayout,
             QGroupBox* _memoryGroupBox, QLayout* memoryGroupBoxParentLayout,
             QGroupBox* _instanceGroupBox, QLayout* instanceGroupBoxParentLayout,
@@ -62,6 +63,11 @@ namespace armarx::armem::gui
 
     public slots:
 
+        // LTMControlWidget
+        void store();
+        void exportHere();
+
+        // Other
         void updateMemories();
         void updateInstanceTree(const armem::MemoryID& selectedID);
 
@@ -98,8 +104,10 @@ namespace armarx::armem::gui
         armem::mns::MemoryNameSystemInterfacePrx mns;
 
         std::map<std::string, armem::client::Reader> memoryReaders;
-        std::map<std::string, std::optional<armem::Memory>> memoryData;
+        std::map<std::string, std::optional<armem::wm::Memory>> memoryData;
 
+        QLayout* ltmControlWidgetLayout;
+        armem::gui::LTMControlWidget* ltmControlWidget;
 
         QLayout* updateWidgetLayout;
         armem::gui::PeriodicUpdateWidget* updateWidget;
diff --git a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
index ce0b625977833afb5235a5060e9f9f0699f8382e..429d2f3603967f64728e59113841b85c862b8d46 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
+++ b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.cpp
@@ -91,10 +91,10 @@ namespace armarx::armem::gui::instance
     }
 
 
-    void InstanceView::update(const MemoryID& id, const Memory& memory)
+    void InstanceView::update(const MemoryID& id, const wm::Memory& memory)
     {
         aron::typenavigator::ObjectNavigatorPtr aronType = nullptr;
-        const armem::EntityInstance* instance = nullptr;
+        const armem::wm::EntityInstance* instance = nullptr;
         try
         {
             instance = &memory.getEntityInstance(id);
@@ -115,7 +115,7 @@ namespace armarx::armem::gui::instance
     }
 
 
-    void InstanceView::update(const EntityInstance& instance, aron::typenavigator::ObjectNavigatorPtr aronType)
+    void InstanceView::update(const wm::EntityInstance& instance, aron::typenavigator::ObjectNavigatorPtr aronType)
     {
         currentInstance = instance;
         currentAronType = aronType;
@@ -170,7 +170,7 @@ namespace armarx::armem::gui::instance
         treeItemData->setExpanded(true);
     }
 
-    void InstanceView::updateMetaData(const EntityInstanceMetadata& metadata)
+    void InstanceView::updateMetaData(const wm::EntityInstanceMetadata& metadata)
     {
         std::vector<std::string> items =
         {
diff --git a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h
index 00027a3e0cc4c826e24c62262bf4404f645e1bdf..0b0a0ee2655f506fa09f15b99dd0edc149e88470 100644
--- a/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h
+++ b/source/RobotAPI/libraries/armem_gui/instance/InstanceView.h
@@ -6,7 +6,7 @@
 
 #include <RobotAPI/libraries/aron/core/navigator/type/container/Object.h>
 
-#include <RobotAPI/libraries/armem/core/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
 
 
 class QGroupBox;
@@ -34,8 +34,8 @@ namespace armarx::armem::gui::instance
         void setStatusLabel(QLabel* statusLabel);
         void setUseTypeInfo(bool enable);
 
-        void update(const MemoryID& id, const Memory& memory);
-        void update(const EntityInstance& instance, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
+        void update(const MemoryID& id, const wm::Memory& memory);
+        void update(const wm::EntityInstance& instance, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
         void update();
 
 
@@ -56,7 +56,7 @@ namespace armarx::armem::gui::instance
 
         void updateInstanceID(const MemoryID& id);
         void updateData(const aron::datanavigator::DictNavigatorPtr& data, aron::typenavigator::ObjectNavigatorPtr aronType = nullptr);
-        void updateMetaData(const EntityInstanceMetadata& metadata);
+        void updateMetaData(const wm::EntityInstanceMetadata& metadata);
         void updateImageView(const aron::datanavigator::DictNavigatorPtr& data);
 
         void showErrorMessage(const std::string& message);
@@ -71,7 +71,7 @@ namespace armarx::armem::gui::instance
             TYPE = 2,
         };
 
-        std::optional<EntityInstance> currentInstance;
+        std::optional<wm::EntityInstance> currentInstance;
         aron::typenavigator::ObjectNavigatorPtr currentAronType = nullptr;
         bool useTypeInfo = true;
 
diff --git a/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.cpp b/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.cpp
index 44133ed4df908cd9da7d49d3bbc5a01aef0e78bd..3d4c50f66c6263ec474acd552233b86f895a7862 100644
--- a/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.cpp
+++ b/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.cpp
@@ -51,12 +51,12 @@ namespace armarx::armem::gui::memory
 
     void TreeWidget::initBuilders()
     {
-        memoryBuilder.setExpand(true);
-        memoryBuilder.setMakeItemFn([this](const std::string & name, const Memory * memory)
+        workingmemoryBuilder.setExpand(true);
+        workingmemoryBuilder.setMakeItemFn([this](const std::string & name, const wm::Memory * memory)
         {
             return makeItem(name, *memory);
         });
-        memoryBuilder.setUpdateItemFn([this](const std::string&, const Memory * memory, QTreeWidgetItem * memoryItem)
+        workingmemoryBuilder.setUpdateItemFn([this](const std::string&, const wm::Memory * memory, QTreeWidgetItem * memoryItem)
         {
             updateContainerItem(*memory, memoryItem);
             if (memoryItem)
@@ -67,24 +67,24 @@ namespace armarx::armem::gui::memory
         });
 
 
-        coreSegmentBuilder.setExpand(true);
-        coreSegmentBuilder.setMakeItemFn([this](const std::string & name, const CoreSegment & coreSeg)
+        workingmemoryCoreSegmentBuilder.setExpand(true);
+        workingmemoryCoreSegmentBuilder.setMakeItemFn([this](const std::string & name, const wm::CoreSegment & coreSeg)
         {
             return makeItem(name, coreSeg);
         });
-        coreSegmentBuilder.setUpdateItemFn([this](const std::string&, const CoreSegment & coreSeg, QTreeWidgetItem * coreSegItem)
+        workingmemoryCoreSegmentBuilder.setUpdateItemFn([this](const std::string&, const wm::CoreSegment & coreSeg, QTreeWidgetItem * coreSegItem)
         {
             updateTypedContainerItem(coreSeg, coreSegItem);
             updateChildren(coreSeg, coreSegItem);
             return true;
         });
 
-        provSegmentBuilder.setExpand(true);
-        provSegmentBuilder.setMakeItemFn([this](const std::string & name, const ProviderSegment & provSeg)
+        workingmemoryProvSegmentBuilder.setExpand(true);
+        workingmemoryProvSegmentBuilder.setMakeItemFn([this](const std::string & name, const wm::ProviderSegment & provSeg)
         {
             return makeItem(name, provSeg);
         });
-        provSegmentBuilder.setUpdateItemFn([this](const std::string&, const ProviderSegment & provSeg, QTreeWidgetItem * provSegItem)
+        workingmemoryProvSegmentBuilder.setUpdateItemFn([this](const std::string&, const wm::ProviderSegment & provSeg, QTreeWidgetItem * provSegItem)
         {
             updateTypedContainerItem(provSeg, provSegItem);
             updateChildren(provSeg, provSegItem);
@@ -92,46 +92,46 @@ namespace armarx::armem::gui::memory
         });
 
         // entityBuilder.setExpand(true);
-        entityBuilder.setMakeItemFn([this](const std::string & name, const Entity & entity)
+        workingmemoryEntityBuilder.setMakeItemFn([this](const std::string & name, const wm::Entity & entity)
         {
             return makeItem(name, entity);
         });
-        entityBuilder.setUpdateItemFn([this](const std::string&, const Entity & entity, QTreeWidgetItem *  entityItem)
+        workingmemoryEntityBuilder.setUpdateItemFn([this](const std::string&, const wm::Entity & entity, QTreeWidgetItem *  entityItem)
         {
             updateContainerItem(entity, entityItem);
             updateChildren(entity, entityItem);
             return true;
         });
 
-        snapshotBuilder.setMakeItemFn([this](const armem::Time & time, const EntitySnapshot & snapshot)
+        workingmemorySnapshotBuilder.setMakeItemFn([this](const armem::Time & time, const wm::EntitySnapshot & snapshot)
         {
             QTreeWidgetItem* item = makeItem(toDateTimeMilliSeconds(time), snapshot);
             item->setData(int(Columns::KEY), Qt::ItemDataRole::UserRole, QVariant(static_cast<qlonglong>(snapshot.time().toMicroSeconds())));
             return item;
         });
-        snapshotBuilder.setCompareFn([](const auto & pair, QTreeWidgetItem * item)
+        workingmemorySnapshotBuilder.setCompareFn([](const auto & pair, QTreeWidgetItem * item)
         {
-            const EntitySnapshot& snapshot = pair.second;
+            const wm::EntitySnapshot& snapshot = pair.second;
             return armarx::detail::compare(static_cast<qlonglong>(snapshot.time().toMicroSeconds()),
                                            item->data(int(Columns::KEY), Qt::ItemDataRole::UserRole).toLongLong());
         });
-        snapshotBuilder.setUpdateItemFn([this](const armem::Time&, const EntitySnapshot & snapshot, QTreeWidgetItem * snapshotItem)
+        workingmemorySnapshotBuilder.setUpdateItemFn([this](const armem::Time&, const wm::EntitySnapshot & snapshot, QTreeWidgetItem * snapshotItem)
         {
             updateContainerItem(snapshot, snapshotItem);
             updateChildren(snapshot, snapshotItem);
             return true;
         });
 
-        instanceBuilder.setMakeItemFn([this](const EntityInstance & instance)
+        workingmemoryInstanceBuilder.setMakeItemFn([this](const wm::EntityInstance & instance)
         {
             QTreeWidgetItem* item = makeItem("", instance);
             return item;
         });
-        instanceBuilder.setCompareFn([](const EntityInstance & lhs, QTreeWidgetItem * rhsItem)
+        workingmemoryInstanceBuilder.setCompareFn([](const wm::EntityInstance & lhs, QTreeWidgetItem * rhsItem)
         {
             return armarx::detail::compare(lhs.index(), rhsItem->text(0).toInt());
         });
-        instanceBuilder.setUpdateItemFn([this](const EntityInstance & instance, QTreeWidgetItem * instanceItem)
+        workingmemoryInstanceBuilder.setUpdateItemFn([this](const wm::EntityInstance & instance, QTreeWidgetItem * instanceItem)
         {
             updateItemItem(instance, instanceItem);
             updateChildren(instance, instanceItem);
@@ -141,7 +141,7 @@ namespace armarx::armem::gui::memory
     }
 
 
-    void TreeWidget::update(const armem::Memory& memory)
+    void TreeWidget::update(const armem::wm::Memory& memory)
     {
         // Removing elements during the update can create unwanted signals triggering selection handling.
         handleSelections = false;
@@ -150,7 +150,7 @@ namespace armarx::armem::gui::memory
         emit updated();
     }
 
-    void TreeWidget::update(const std::map<std::string, const armem::Memory*>& memories)
+    void TreeWidget::update(const std::map<std::string, const armem::wm::Memory*>& memories)
     {
         handleSelections = false;
         updateChildren(memories, this);
@@ -183,27 +183,27 @@ namespace armarx::armem::gui::memory
             _selectedID = id;
 
             const std::string levelName = item->data(int(Columns::LEVEL), Qt::UserRole).toString().toStdString();
-            if (levelName == Memory().getLevelName())
+            if (levelName == wm::Memory().getLevelName())
             {
                 emit memorySelected(*_selectedID);
             }
-            else if (levelName == CoreSegment().getLevelName())
+            else if (levelName == wm::CoreSegment().getLevelName())
             {
                 emit coreSegmentSelected(*_selectedID);
             }
-            else if (levelName == ProviderSegment().getLevelName())
+            else if (levelName == wm::ProviderSegment().getLevelName())
             {
                 emit providerSegmentSelected(*_selectedID);
             }
-            else if (levelName == Entity().getLevelName())
+            else if (levelName == wm::Entity().getLevelName())
             {
                 emit entitySelected(*_selectedID);
             }
-            else if (levelName == EntitySnapshot().getLevelName())
+            else if (levelName == wm::EntitySnapshot().getLevelName())
             {
                 emit snapshotSelected(*_selectedID);
             }
-            else if (levelName == EntityInstance().getLevelName())
+            else if (levelName == wm::EntityInstance().getLevelName())
             {
                 emit instanceSelected(*_selectedID);
             }
@@ -214,48 +214,48 @@ namespace armarx::armem::gui::memory
     }
 
 
-    void TreeWidget::updateChildren(const armem::Memory& memory, QTreeWidget* tree)
+    void TreeWidget::updateChildren(const armem::wm::Memory& memory, QTreeWidget* tree)
     {
-        updateChildren(std::map<std::string, const armem::Memory*> {{memory.name(), &memory}}, tree);
+        updateChildren(std::map<std::string, const armem::wm::Memory*> {{memory.name(), &memory}}, tree);
     }
 
-    void TreeWidget::updateChildren(const std::map<std::string, const armem::Memory*>& memories, QTreeWidget* tree)
+    void TreeWidget::updateChildren(const std::map<std::string, const armem::wm::Memory*>& memories, QTreeWidget* tree)
     {
-        memoryBuilder.updateTree(tree, memories);
+        workingmemoryBuilder.updateTree(tree, memories);
     }
 
 
-    void TreeWidget::updateChildren(const armem::Memory& memory, QTreeWidgetItem* memoryItem)
+    void TreeWidget::updateChildren(const armem::wm::Memory& memory, QTreeWidgetItem* memoryItem)
     {
-        coreSegmentBuilder.updateTree(memoryItem, memory.coreSegments);
+        workingmemoryCoreSegmentBuilder.updateTree(memoryItem, memory.coreSegments());
     }
 
-    void TreeWidget::updateChildren(const armem::CoreSegment& coreSeg, QTreeWidgetItem* coreSegItem)
+    void TreeWidget::updateChildren(const armem::wm::CoreSegment& coreSeg, QTreeWidgetItem* coreSegItem)
     {
-        provSegmentBuilder.updateTree(coreSegItem, coreSeg.providerSegments);
+        workingmemoryProvSegmentBuilder.updateTree(coreSegItem, coreSeg.providerSegments());
     }
 
-    void TreeWidget::updateChildren(const armem::ProviderSegment& provSeg, QTreeWidgetItem* provSegItem)
+    void TreeWidget::updateChildren(const armem::wm::ProviderSegment& provSeg, QTreeWidgetItem* provSegItem)
     {
-        entityBuilder.updateTree(provSegItem, provSeg.entities);
+        workingmemoryEntityBuilder.updateTree(provSegItem, provSeg.entities());
     }
 
-    void TreeWidget::updateChildren(const armem::Entity& entity, QTreeWidgetItem* entityItem)
+    void TreeWidget::updateChildren(const armem::wm::Entity& entity, QTreeWidgetItem* entityItem)
     {
-        snapshotBuilder.updateTree(entityItem, entity.history);
+        workingmemorySnapshotBuilder.updateTree(entityItem, entity.history());
     }
 
-    void TreeWidget::updateChildren(const armem::EntitySnapshot& snapshot, QTreeWidgetItem* snapshotItem)
+    void TreeWidget::updateChildren(const armem::wm::EntitySnapshot& snapshot, QTreeWidgetItem* snapshotItem)
     {
-        instanceBuilder.updateTree(snapshotItem, snapshot.instances);
+        workingmemoryInstanceBuilder.updateTree(snapshotItem, snapshot.instances());
     }
 
-    void TreeWidget::updateChildren(const armem::EntityInstance& data, QTreeWidgetItem* dataItem)
+    void TreeWidget::updateChildren(const armem::wm::EntityInstance& data, QTreeWidgetItem* dataItem)
     {
         (void) data, (void) dataItem;
     }
 
-    QTreeWidgetItem* TreeWidget::makeItem(const std::string& key, const armem::detail::MemoryItem& memoryItem)
+    QTreeWidgetItem* TreeWidget::makeItem(const std::string& key, const armem::base::detail::MemoryItem& memoryItem)
     {
         (void) key;
         QStringList columns;
@@ -272,14 +272,14 @@ namespace armarx::armem::gui::memory
         return item;
     }
 
-    void TreeWidget::updateItemItem(const armem::detail::MemoryItem& level, QTreeWidgetItem* item)
+    void TreeWidget::updateItemItem(const armem::base::detail::MemoryItem& level, QTreeWidgetItem* item)
     {
         (void) level, (void) item;
     }
 
     template <class... T>
     void TreeWidget::updateContainerItem(
-        const armem::detail::MemoryContainer<T...>& container, QTreeWidgetItem* item)
+        const armem::wm::detail::MemoryContainer<T...>& container, QTreeWidgetItem* item)
     {
         updateItemItem(container, item);
         item->setText(int(Columns::SIZE), QString::number(container.size()));
@@ -287,7 +287,7 @@ namespace armarx::armem::gui::memory
 
     template <class... T>
     void TreeWidget::updateTypedContainerItem(
-        const armem::detail::TypedEntityContainer<T...>& container, QTreeWidgetItem* item)
+        const armem::wm::detail::TypedEntityContainer<T...>& container, QTreeWidgetItem* item)
     {
         updateContainerItem(container, item);
         std::string typeName;
diff --git a/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.h b/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.h
index be73a68b6a9fb482c57f8262c3fb514638dfb3d9..1ce80192013f4d045ff84b4f461589bbd4a43297 100644
--- a/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.h
+++ b/source/RobotAPI/libraries/armem_gui/memory/TreeWidget.h
@@ -4,7 +4,9 @@
 
 #include <QTreeWidget>
 
-#include <RobotAPI/libraries/armem/core/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/longtermmemory/Memory.h>
+
 #include <RobotAPI/libraries/armem_gui/TreeWidgetBuilder.h>
 
 
@@ -20,8 +22,8 @@ namespace armarx::armem::gui::memory
 
         TreeWidget();
 
-        void update(const armem::Memory& memory);
-        void update(const std::map<std::string, const armem::Memory*>& memories);
+        void update(const armem::wm::Memory& memory);
+        void update(const std::map<std::string, const armem::wm::Memory*>& memories);
 
         std::optional<MemoryID> selectedID() const;
 
@@ -54,34 +56,34 @@ namespace armarx::armem::gui::memory
         void initWidget();
         void initBuilders();
 
-        void updateChildren(const armem::Memory& memory, QTreeWidget* tree);
-        void updateChildren(const std::map<std::string, const armem::Memory*>& memories, QTreeWidget* tree);
+        void updateChildren(const armem::wm::Memory& memory, QTreeWidget* tree);
+        void updateChildren(const std::map<std::string, const armem::wm::Memory*>& memories, QTreeWidget* tree);
 
-        void updateChildren(const armem::Memory& memory, QTreeWidgetItem* memoryItem);
-        void updateChildren(const armem::CoreSegment& coreSeg, QTreeWidgetItem* coreSegItem);
-        void updateChildren(const armem::ProviderSegment& provSeg, QTreeWidgetItem* provSegItem);
-        void updateChildren(const armem::Entity& entity, QTreeWidgetItem* entityItem);
-        void updateChildren(const armem::EntitySnapshot& snapshot, QTreeWidgetItem* snapshotItem);
-        void updateChildren(const armem::EntityInstance& data, QTreeWidgetItem* parent);
+        void updateChildren(const armem::wm::Memory& memory, QTreeWidgetItem* memoryItem);
+        void updateChildren(const armem::wm::CoreSegment& coreSeg, QTreeWidgetItem* coreSegItem);
+        void updateChildren(const armem::wm::ProviderSegment& provSeg, QTreeWidgetItem* provSegItem);
+        void updateChildren(const armem::wm::Entity& entity, QTreeWidgetItem* entityItem);
+        void updateChildren(const armem::wm::EntitySnapshot& snapshot, QTreeWidgetItem* snapshotItem);
+        void updateChildren(const armem::wm::EntityInstance& data, QTreeWidgetItem* parent);
 
 
-        QTreeWidgetItem* makeItem(const std::string& key, const armem::detail::MemoryItem& container);
+        QTreeWidgetItem* makeItem(const std::string& key, const armem::base::detail::MemoryItem& container);
 
-        void updateItemItem(const armem::detail::MemoryItem& level, QTreeWidgetItem* item);
+        void updateItemItem(const armem::base::detail::MemoryItem& level, QTreeWidgetItem* item);
         template <class... T>
-        void updateContainerItem(const armem::detail::MemoryContainer<T...>& container, QTreeWidgetItem* item);
+        void updateContainerItem(const armem::wm::detail::MemoryContainer<T...>& container, QTreeWidgetItem* item);
         template <class... T>
-        void updateTypedContainerItem(const armem::detail::TypedEntityContainer<T...>& container, QTreeWidgetItem* item);
+        void updateTypedContainerItem(const armem::wm::detail::TypedEntityContainer<T...>& container, QTreeWidgetItem* item);
 
 
     private:
 
-        MapTreeWidgetBuilder<std::string, const Memory*> memoryBuilder;
-        MapTreeWidgetBuilder<std::string, CoreSegment> coreSegmentBuilder;
-        MapTreeWidgetBuilder<std::string, ProviderSegment> provSegmentBuilder;
-        MapTreeWidgetBuilder<std::string, Entity> entityBuilder;
-        MapTreeWidgetBuilder<armem::Time, EntitySnapshot> snapshotBuilder;
-        TreeWidgetBuilder<std::vector<EntityInstance>> instanceBuilder;
+        MapTreeWidgetBuilder<std::string, const wm::Memory*> workingmemoryBuilder;
+        MapTreeWidgetBuilder<std::string, wm::CoreSegment> workingmemoryCoreSegmentBuilder;
+        MapTreeWidgetBuilder<std::string, wm::ProviderSegment> workingmemoryProvSegmentBuilder;
+        MapTreeWidgetBuilder<std::string, wm::Entity> workingmemoryEntityBuilder;
+        MapTreeWidgetBuilder<armem::Time, wm::EntitySnapshot> workingmemorySnapshotBuilder;
+        TreeWidgetBuilder<std::vector<wm::EntityInstance>> workingmemoryInstanceBuilder;
 
         std::optional<MemoryID> _selectedID;
         /// While this is false, do not handle selection updates.
diff --git a/source/RobotAPI/libraries/armem_robot_localization/TransformReader.cpp b/source/RobotAPI/libraries/armem_robot_localization/TransformReader.cpp
index b14f1a711e490c2bcae4eca0ca81976ca888a6ea..c3b24c4895328e951bc4950339639200206a9daf 100644
--- a/source/RobotAPI/libraries/armem_robot_localization/TransformReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_localization/TransformReader.cpp
@@ -47,9 +47,9 @@
 // this package
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
-#include <RobotAPI/libraries/armem/core/Memory.h>
-#include <RobotAPI/libraries/armem/core/ProviderSegment.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
 #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
 #include <RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.h>
 #include <RobotAPI/libraries/core/FramedPose.h>
@@ -128,7 +128,7 @@ namespace armarx::armem
 
     // }
 
-    std::vector<std::string> TransformReader::buildTransformChain(const armem::Memory& memory,
+    std::vector<std::string> TransformReader::buildTransformChain(const armem::wm::Memory& memory,
             const TransformQuery& query) const
     {
         ARMARX_DEBUG << "Building transform chain";
@@ -202,7 +202,7 @@ namespace armarx::armem
         return chain;
     }
 
-    inline Transform convertEntityToTransform(const armem::EntityInstance& item)
+    inline Transform convertEntityToTransform(const armem::wm::EntityInstance& item)
     {
         aron::Transform aronTransform;
         aronTransform.fromAron(item.data());
@@ -271,14 +271,14 @@ namespace armarx::armem
         return simox::math::interpolatePose(posePreIt->transform, poseNextIt->transform, t);
     }
 
-    Eigen::Affine3f TransformReader::obtainTransform(const std::string& entityName, const armem::ProviderSegment& agentProviderSegment, const int64_t timestamp) const
+    Eigen::Affine3f TransformReader::obtainTransform(const std::string& entityName, const armem::wm::ProviderSegment& agentProviderSegment, const int64_t timestamp) const
     {
 
         ARMARX_DEBUG << "getEntity:" + entityName;
         const auto& entity = agentProviderSegment.getEntity(entityName);
 
-        ARMARX_DEBUG << "History (size: " << entity.history.size() << ")"
-                     << simox::alg::get_keys(entity.history);
+        ARMARX_DEBUG << "History (size: " << entity.history().size() << ")"
+                     << simox::alg::get_keys(entity.history());
 
         // if (entity.history.empty())
         // {
@@ -289,9 +289,9 @@ namespace armarx::armem
 
 
         std::vector<Transform> transforms;
-        transforms.reserve(entity.history.size());
+        transforms.reserve(entity.history().size());
 
-        const auto entitySnapshots = simox::alg::get_values(entity.history);
+        const auto entitySnapshots = simox::alg::get_values(entity.history());
         std::transform(entitySnapshots.begin(),
                        entitySnapshots.end(),
                        std::back_inserter(transforms),
@@ -329,13 +329,13 @@ namespace armarx::armem
     }
 
     std::vector<Eigen::Affine3f>
-    TransformReader::obtainTransforms(const armem::Memory& memory,
+    TransformReader::obtainTransforms(const armem::wm::Memory& memory,
                                       const std::vector<std::string>& tfChain,
                                       const std::string& agent,
                                       const std::int64_t& timestamp) const
     {
 
-        ARMARX_DEBUG << "Core segments" << simox::alg::get_keys(memory.coreSegments);
+        ARMARX_DEBUG << "Core segments" << simox::alg::get_keys(memory.coreSegments());
 
         const auto& agentProviderSegment =
             memory.getCoreSegment(properties.localizationMemoryName).getProviderSegment(agent);
@@ -343,9 +343,9 @@ namespace armarx::armem
         ARMARX_DEBUG << "Provider segments"
                      << simox::alg::get_keys(
                          memory.getCoreSegment(properties.localizationMemoryName)
-                         .providerSegments);
+                         .providerSegments());
 
-        ARMARX_DEBUG << "Entities: " << simox::alg::get_keys(agentProviderSegment.entities);
+        ARMARX_DEBUG << "Entities: " << simox::alg::get_keys(agentProviderSegment.entities());
 
         try
         {
diff --git a/source/RobotAPI/libraries/armem_robot_localization/TransformReader.h b/source/RobotAPI/libraries/armem_robot_localization/TransformReader.h
index 061499f7b69fd1a8a1b372efe590229f5722c73e..9b04899545e78bdad1b3d0dbcca03c0ba61b4dcd 100644
--- a/source/RobotAPI/libraries/armem_robot_localization/TransformReader.h
+++ b/source/RobotAPI/libraries/armem_robot_localization/TransformReader.h
@@ -64,14 +64,14 @@ namespace armarx::armem
         }
 
     private:
-        std::vector<std::string> buildTransformChain(const armem::Memory& memory,
+        std::vector<std::string> buildTransformChain(const armem::wm::Memory& memory,
                 const TransformQuery& query) const;
 
-        std::vector<Eigen::Affine3f> obtainTransforms(const armem::Memory& memory,
+        std::vector<Eigen::Affine3f> obtainTransforms(const armem::wm::Memory& memory,
                 const std::vector<std::string>& tfChain,
                 const std::string& agent, const std::int64_t& timestamp) const;
 
-        Eigen::Affine3f obtainTransform(const std::string& entityName, const armem::ProviderSegment& agentProviderSegment, int64_t timestamp) const;
+        Eigen::Affine3f obtainTransform(const std::string& entityName, const armem::wm::ProviderSegment& agentProviderSegment, int64_t timestamp) const;
 
 
         armem::client::Reader memoryReader;
diff --git a/source/RobotAPI/libraries/armem_robot_localization/TransformWriter.cpp b/source/RobotAPI/libraries/armem_robot_localization/TransformWriter.cpp
index 2db61f978e45fb2f8582532454d6423026b9fcfe..1ac8ea58b31d24e14d7f2ee14eb9c34d61178e44 100644
--- a/source/RobotAPI/libraries/armem_robot_localization/TransformWriter.cpp
+++ b/source/RobotAPI/libraries/armem_robot_localization/TransformWriter.cpp
@@ -37,10 +37,10 @@
 
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/query_fns.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ice_conversions.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h>
 #include <RobotAPI/libraries/armem/server/MemoryRemoteGui.h>
-#include <RobotAPI/libraries/armem/core/Memory.h>
-#include <RobotAPI/libraries/armem/core/ProviderSegment.h>
 #include <RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.h>
 #include <RobotAPI/libraries/core/FramedPose.h>
 
diff --git a/source/RobotAPI/libraries/armem_robot_mapping/MappingDataReader.cpp b/source/RobotAPI/libraries/armem_robot_mapping/MappingDataReader.cpp
index aae0106dab35ac2252e90f78ee5dd79a37c9188c..d035b2b7926376c0e16e38bcfd6d8182f4609d87 100644
--- a/source/RobotAPI/libraries/armem_robot_mapping/MappingDataReader.cpp
+++ b/source/RobotAPI/libraries/armem_robot_mapping/MappingDataReader.cpp
@@ -12,35 +12,32 @@
 #include <IceUtil/Time.h>
 #include <IceUtil/Handle.h>
 
+#include <SimoxUtility/algorithm/get_map_keys_values.h>
+
 #include <ArmarXCore/core/logging/Logging.h>
 #include <ArmarXCore/core/logging/LogSender.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include <SimoxUtility/algorithm/get_map_keys_values.h>
-
-#include <RobotAPI/libraries/armem_robot_localization/MemoryConnector.h>
+#include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
+#include <RobotAPI/interface/units/LaserScannerUnit.h>
+#include <RobotAPI/libraries/aron/core/Exception.h>
+#include <RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.h>
 #include <RobotAPI/libraries/armem/client/Query.h>
 #include <RobotAPI/libraries/armem/client/Reader.h>
 #include <RobotAPI/libraries/armem/client/query/Builder.h>
 #include <RobotAPI/libraries/armem/client/query/selectors.h>
-#include <RobotAPI/libraries/armem/core/CoreSegment.h>
-#include <RobotAPI/libraries/armem/core/Memory.h>
-#include <RobotAPI/libraries/armem/core/ProviderSegment.h>
-#include <RobotAPI/libraries/aron/core/Exception.h>
-#include <RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/CoreSegment.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/EntityInstance.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Memory.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/Entity.h>
+#include <RobotAPI/libraries/armem/core/workingmemory/ProviderSegment.h>
 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
-#include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
-#include <RobotAPI/interface/units/LaserScannerUnit.h>
-#include <RobotAPI/libraries/armem/core/EntityInstance.h>
 #include <RobotAPI/libraries/armem/util/util.h>
+#include <RobotAPI/libraries/armem_robot_localization/MemoryConnector.h>
 #include <RobotAPI/libraries/armem_robot_mapping/aron/LaserScan.aron.generated.h>
 #include <RobotAPI/libraries/armem_robot_mapping/aron_conversions.h>
 #include <RobotAPI/libraries/armem_robot_mapping/types.h>
 
-namespace armarx::armem
-{
-    class Entity;
-}  // namespace armarx
 
 namespace armarx::armem
 {
@@ -107,7 +104,7 @@ namespace armarx::armem
             .coreSegments().withName(properties.mappingMemoryName)
             .providerSegments().withName(query.agent)
             .entities().withNames(query.sensorList)
-            .snapshots().timeRange(query.timeRange.min,query.timeRange.max);
+            .snapshots().timeRange(query.timeRange.min, query.timeRange.max);
             // clang-format on
         }
 
@@ -115,7 +112,7 @@ namespace armarx::armem
 
     }
 
-    std::vector<LaserScanStamped> asLaserScans(const std::map<std::string, Entity>& entities)
+    std::vector<LaserScanStamped> asLaserScans(const std::map<std::string, wm::Entity>& entities)
     {
         std::vector<LaserScanStamped> outV;
 
@@ -124,7 +121,7 @@ namespace armarx::armem
             ARMARX_WARNING << "No entities!";
         }
 
-        const auto convert = [](const arondto::LaserScanStamped & aronLaserScanStamped, const EntityInstance & ei) -> LaserScanStamped
+        const auto convert = [](const arondto::LaserScanStamped & aronLaserScanStamped, const wm::EntityInstance & ei) -> LaserScanStamped
         {
             LaserScanStamped laserScanStamped;
             fromAron(aronLaserScanStamped, laserScanStamped);
@@ -144,16 +141,16 @@ namespace armarx::armem
         // loop over all entities and their snapshots
         for (const auto &[s, entity] : entities)
         {
-            if (entity.history.empty())
+            if (entity.empty())
             {
                 ARMARX_WARNING << "Empty history for " << s;
             }
 
-            ARMARX_INFO << "History size: " << entity.history.size();
+            ARMARX_INFO << "History size: " << entity.size();
 
-            for (const auto &[ss, entitySnapshot] : entity.history)
+            for (const auto &[ss, entitySnapshot] : entity)
             {
-                for (const auto& entityInstance : entitySnapshot.instances)
+                for (const auto& entityInstance : entitySnapshot.instances())
                 {
                     const auto o = tryCast<arondto::LaserScanStamped>(entityInstance);
 
@@ -194,7 +191,7 @@ namespace armarx::armem
         const auto& entities =
             qResult.memory.getCoreSegment(properties.mappingMemoryName)
             .getProviderSegment(query.agent)
-            .entities;
+            .entities();
 
         const auto laserScans = asLaserScans(entities);
         const auto sensors = simox::alg::get_keys(entities);
diff --git a/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.cpp b/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.cpp
index 40471a632c66708ecb8085ea63a65acf6013d5a2..b37a88381383b41ea6c3ca9bd3075a50e8b733ef 100644
--- a/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.cpp
+++ b/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.cpp
@@ -24,7 +24,7 @@ namespace armarx
 
     SensorHeader fromAron(const arondto::SensorHeader& aronSensorHeader)
     {
-        
+
         return {.agent = aronSensorHeader.agent,
                 .frame = aronSensorHeader.frame,
                 .timestamp = timeFromAron(aronSensorHeader.timestamp)};
diff --git a/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.h b/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.h
index 7e0d690a48da10f3d07290f6bf32281251a877e5..7ecffc237d480fd33c30226ef7f1cf02c09308de 100644
--- a/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.h
+++ b/source/RobotAPI/libraries/armem_robot_mapping/aron_conversions.h
@@ -63,7 +63,7 @@ namespace armarx
 
     inline aron::datanavigator::NDArrayNavigatorPtr toAron(const LaserScan& laserScan)
     {
-        return aron::datanavigator::NDArrayNavigator::FromVector(laserScan);
+        return aron::converter::AronVectorConverter::ConvertFromVector(laserScan);
     }
 
 
diff --git a/source/RobotAPI/libraries/aron/converter/common/Converter.h b/source/RobotAPI/libraries/aron/converter/common/Converter.h
index 570344ab618f8a353327a716aaa9ba5f850eaca8..f6e9959dfba18891807fad9579580375bf53382d 100644
--- a/source/RobotAPI/libraries/aron/converter/common/Converter.h
+++ b/source/RobotAPI/libraries/aron/converter/common/Converter.h
@@ -33,12 +33,12 @@ namespace armarx::aron
      *  You have to provide a converter function for the element with the signature
      *
      *      PlainCppType fromAron(const AronType&)
-     * 
+     *
      * @tparam T the aron vector element
      * @param v the vector of elements
      * @return the vector of aron elements
      */
-    template <typename T> 
+    template <typename T>
     auto fromAron(const std::vector<T>& v) -> std::vector<decltype(fromAron(T()))>
     {
         std::vector<decltype(fromAron(T()))> r;
diff --git a/source/RobotAPI/libraries/aron/converter/common/VectorConverter.h b/source/RobotAPI/libraries/aron/converter/common/VectorConverter.h
index 17475a3b9df0f39ee10e82443f24e5251db63c58..78cce4a1a7d2d9b6d9f5fc9a1f156683c67c0d71 100644
--- a/source/RobotAPI/libraries/aron/converter/common/VectorConverter.h
+++ b/source/RobotAPI/libraries/aron/converter/common/VectorConverter.h
@@ -39,7 +39,7 @@ namespace armarx::aron::converter
     {
     public:
         AronVectorConverter() = delete;
-       
+
         template<typename T>
         static std::vector<T> ConvertToVector(const datanavigator::NDArrayNavigatorPtr& nav)
         {
@@ -47,16 +47,16 @@ namespace armarx::aron::converter
 
             const auto& dims = nav->getDimensions();
 
-            if(dims.size() != 2)
+            if (dims.size() != 2)
             {
                 throw error::AronException("AronVectorConverter", "ConvertToVector", "The NDArray must have two dimensions.", nav->getPath());
             }
-            
-            if(dims.at(1) != sizeof(T))
+
+            if (dims.at(1) != sizeof(T))
             {
                 throw error::AronException("AronVectorConverter", "ConvertToVector", "Dimension 1 of the array has to match the element size.", nav->getPath());
             }
-            
+
             const int size = std::accumulate(std::begin(dims), std::end(dims), 1, std::multiplies<>());
 
             std::vector<T> v(dims.at(0));
@@ -64,6 +64,19 @@ namespace armarx::aron::converter
 
             return v;
         }
+
+
+        template<typename T>
+        static datanavigator::NDArrayNavigatorPtr ConvertFromVector(const std::vector<T>& data)
+        {
+            datanavigator::NDArrayNavigatorPtr ndArr(new datanavigator::NDArrayNavigator);
+
+            ndArr->setDimensions({static_cast<int>(data.size()), sizeof(T)});
+            ndArr->setData(sizeof(T) * data.size(), reinterpret_cast <const unsigned char* >(data.data()));
+
+            return ndArr;
+        }
+
     };
 
 }  // namespace armarx::aron::converter
diff --git a/source/RobotAPI/libraries/aron/core/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/CMakeLists.txt
index 673ea307e6b52105e4152e54c9c7b2f41f8ca48a..c2afd4f51bc1c18dd1c509a7328f31720eb519bf 100644
--- a/source/RobotAPI/libraries/aron/core/CMakeLists.txt
+++ b/source/RobotAPI/libraries/aron/core/CMakeLists.txt
@@ -18,7 +18,9 @@ set(LIBS
     ArmarXCore
     RobotAPIInterfaces
     cppgen
+
     Simox::SimoxUtility
+
     # System libraries
     Eigen3::Eigen
     # PCLInterface
@@ -222,8 +224,8 @@ armarx_add_library("${LIB_NAME}" "${LIB_FILES}" "${LIB_HEADERS}" "${LIBS}")
 
 
 if(PCL_FOUND)
-target_include_directories("${LIB_NAME}" 
-    SYSTEM PUBLIC 
+target_include_directories("${LIB_NAME}"
+    SYSTEM PUBLIC
         "${PCL_INCLUDE_DIRS}"
 )
 endif()
diff --git a/source/RobotAPI/libraries/aron/core/Debug.h b/source/RobotAPI/libraries/aron/core/Debug.h
index 6687e8909ffb6d33918cde779f3e9d7f8a342007..28b3958646b984914a6092d272d5b39d3a7dd2ba 100644
--- a/source/RobotAPI/libraries/aron/core/Debug.h
+++ b/source/RobotAPI/libraries/aron/core/Debug.h
@@ -47,7 +47,7 @@ namespace armarx::aron
         static std::string AronDataPtrToString(const data::AronDataPtr& data)
         {
             dataIO::writer::NlohmannJSONWriter w;
-            dataIO::Visitor::SetupWriterFromAronDataPtr(w, data);
+            dataIO::Visitor::VisitAndSetup(w, data);
             return w.getResult().dump(2);
         }
 
@@ -58,14 +58,14 @@ namespace armarx::aron
                 return "";
             }
             dataIO::writer::NlohmannJSONWriter w;
-            dataIO::Visitor::SetupWriterFromAronDataPtr(w, data);
+            dataIO::Visitor::VisitAndSetup(w, data);
             return w.getResult().dump(2);
         }
 
         static std::string AronTypePtrToString(const type::AronTypePtr& data)
         {
             typeIO::writer::NlohmannJSONWriter w;
-            typeIO::Visitor::SetupWriterFromAronTypePtr(w, data);
+            typeIO::Visitor::VisitAndSetup(w, data);
             return w.getResult().dump(2);
         }
 
@@ -76,7 +76,7 @@ namespace armarx::aron
                 return "";
             }
             typeIO::writer::NlohmannJSONWriter w;
-            typeIO::Visitor::SetupWriterFromAronTypePtr(w, data);
+            typeIO::Visitor::VisitAndSetup(w, data);
             return w.getResult().dump(2);
         }
     };
diff --git a/source/RobotAPI/libraries/aron/core/Descriptor.h b/source/RobotAPI/libraries/aron/core/Descriptor.h
index 8beadd6fe75e32997382623f96e68f7a5ee70f47..26e9e24ba442a6d04f7590181e8736ace884ab29 100644
--- a/source/RobotAPI/libraries/aron/core/Descriptor.h
+++ b/source/RobotAPI/libraries/aron/core/Descriptor.h
@@ -35,7 +35,7 @@
 
 namespace armarx::aron::type
 {
-    enum Descriptor
+    enum class Descriptor
     {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
     e##upperType,
@@ -48,11 +48,11 @@ namespace armarx::aron::type
     const std::map<type::Descriptor, std::string> _descriptorstring =
     {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-    { e##upperType, "armarx::aron::type::Descriptor::e" + std::string(#upperType) },
+    { Descriptor::e##upperType, "armarx::aron::type::Descriptor::e" + std::string(#upperType) },
 
         HANDLE_ALL_ARON_TYPES
 #undef RUN_ARON_MACRO
-        {eUnknown, "armarx::aron::type::Descriptor::eUnknown"}
+        {Descriptor::eUnknown, "armarx::aron::type::Descriptor::eUnknown"}
     };
 
     inline std::string DESCRIPTOR_TO_STRING(const type::Descriptor d)
@@ -63,7 +63,7 @@ namespace armarx::aron::type
 
 namespace armarx::aron::data
 {
-    enum Descriptor
+    enum class Descriptor
     {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
     e##upperType,
@@ -76,11 +76,11 @@ namespace armarx::aron::data
     const std::map<data::Descriptor, std::string> _descriptorstring =
     {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-    { e##upperType, "armarx::aron::data::Descriptor::e" + std::string(#upperType) },
+    { Descriptor::e##upperType, "armarx::aron::data::Descriptor::e" + std::string(#upperType) },
 
         HANDLE_ALL_ARON_DATA
 #undef RUN_ARON_MACRO
-        {eUnknown, "armarx::aron::data::Descriptor::eUnknown"}
+        {Descriptor::eUnknown, "armarx::aron::data::Descriptor::eUnknown"}
     };
 
     inline std::string DESCRIPTOR_TO_STRING(const data::Descriptor d)
diff --git a/source/RobotAPI/libraries/aron/core/Randomizer.h b/source/RobotAPI/libraries/aron/core/Randomizer.h
index aeefb6913607dde05b926bfc237262a490fa93a4..315dbed6511f2933fda4dff223a87c6f473b0592 100644
--- a/source/RobotAPI/libraries/aron/core/Randomizer.h
+++ b/source/RobotAPI/libraries/aron/core/Randomizer.h
@@ -44,13 +44,13 @@ namespace armarx::aron
 
         typenavigator::NavigatorPtr generateRandomType(bool mustBeObject = false) const
         {
-            type::Descriptor nextType = type::eObject;
+            type::Descriptor nextType = type::Descriptor::eObject;
             if (!mustBeObject)
             {
                 std::vector<type::Descriptor> descriptors =
                 {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-    type::e##upperType,
+    type::Descriptor::e##upperType,
 
                     HANDLE_ALL_ARON_TYPES
 #undef RUN_ARON_MACRO
@@ -62,7 +62,7 @@ namespace armarx::aron
 
             switch (nextType)
             {
-                case type::eObject:
+                case type::Descriptor::eObject:
                 {
                     typenavigator::ObjectNavigatorPtr t = typenavigator::ObjectNavigatorPtr(new typenavigator::ObjectNavigator(Path()));
                     std::string objectName = generateRandomWord();
@@ -81,7 +81,7 @@ namespace armarx::aron
                     }
                     return t;
                 }
-                case type::eDict:
+                case type::Descriptor::eDict:
                 {
                     typenavigator::DictNavigatorPtr t = typenavigator::DictNavigatorPtr(new typenavigator::DictNavigator());
                     typenavigator::NavigatorPtr a = generateRandomType(false);
@@ -89,7 +89,7 @@ namespace armarx::aron
                     t->setAcceptedType(a);
                     return t;
                 }
-                case type::eTuple:
+                case type::Descriptor::eTuple:
                 {
                     typenavigator::TupleNavigatorPtr t = typenavigator::TupleNavigatorPtr(new typenavigator::TupleNavigator());
 
@@ -101,7 +101,7 @@ namespace armarx::aron
                     }
                     return t;
                 }
-                case type::eList:
+                case type::Descriptor::eList:
                 {
                     typenavigator::ListNavigatorPtr t = typenavigator::ListNavigatorPtr(new typenavigator::ListNavigator());
                     typenavigator::NavigatorPtr a = generateRandomType(false);
@@ -109,7 +109,7 @@ namespace armarx::aron
                     t->setAcceptedType(a);
                     return t;
                 }
-                case type::ePair:
+                case type::Descriptor::ePair:
                 {
                     typenavigator::PairNavigatorPtr t = typenavigator::PairNavigatorPtr(new typenavigator::PairNavigator());
                     typenavigator::NavigatorPtr a = generateRandomType(false);
@@ -119,46 +119,46 @@ namespace armarx::aron
                     t->setSecondAcceptedType(b);
                     return t;
                 }
-                case type::eEigenMatrix:
-                case type::eEigenQuaternion:
-                case type::eIVTCByteImage:
-                case type::eOpenCVMat:
-                case type::ePCLPointCloud:
-                case type::ePosition:
-                case type::eOrientation:
-                case type::ePose:
-
-                case type::eInt:
+                case type::Descriptor::eEigenMatrix:
+                case type::Descriptor::eEigenQuaternion:
+                case type::Descriptor::eIVTCByteImage:
+                case type::Descriptor::eOpenCVMat:
+                case type::Descriptor::ePCLPointCloud:
+                case type::Descriptor::ePosition:
+                case type::Descriptor::eOrientation:
+                case type::Descriptor::ePose:
+
+                case type::Descriptor::eInt:
                 {
                     auto t = std::make_shared<typenavigator::IntNavigator>();
                     return t;
                 }
-                case type::eLong:
+                case type::Descriptor::eLong:
                 {
                     auto t = std::make_shared<typenavigator::LongNavigator>();
                     return t;
                 }
-                case type::eFloat:
+                case type::Descriptor::eFloat:
                 {
                     auto t = std::make_shared<typenavigator::FloatNavigator>();
                     return t;
                 }
-                case type::eDouble:
+                case type::Descriptor::eDouble:
                 {
                     auto t = std::make_shared<typenavigator::DoubleNavigator>();
                     return t;
                 }
-                case type::eString:
+                case type::Descriptor::eString:
                 {
                     auto t = std::make_shared<typenavigator::StringNavigator>();
                     return t;
                 }
-                case type::eBool:
+                case type::Descriptor::eBool:
                 {
                     auto t = std::make_shared<typenavigator::BoolNavigator>();
                     return t;
                 }
-                case type::eTime:
+                case type::Descriptor::eTime:
                 {
                     auto t = std::make_shared<typenavigator::TimeNavigator>();
                     return t;
@@ -176,7 +176,7 @@ namespace armarx::aron
             switch (desc)
             {
                 // In an object, we do not want to edit the keys.
-                case type::eObject:
+                case type::Descriptor::eObject:
                 {
                     typenavigator::ObjectNavigatorPtr t = typenavigator::ObjectNavigator::DynamicCastAndCheck(type);
                     datanavigator::DictNavigatorPtr d = datanavigator::DictNavigatorPtr(new datanavigator::DictNavigator());
@@ -188,14 +188,14 @@ namespace armarx::aron
                 }
 
                 // here all totally random
-                case type::eDict:
+                case type::Descriptor::eDict:
                 {
                     typenavigator::DictNavigatorPtr t = typenavigator::DictNavigator::DynamicCastAndCheck(type);
                     return datanavigator::NavigatorPtr(new datanavigator::DictNavigator());
                 }
 
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-case type::e##upperType: \
+case type::Descriptor::e##upperType: \
 { \
     typenavigator::upperType##NavigatorPtr t = typenavigator::upperType##Navigator::DynamicCastAndCheck(type); \
     return datanavigator::NavigatorPtr(new datanavigator::ListNavigator()); \
@@ -205,7 +205,7 @@ case type::e##upperType: \
 #undef RUN_ARON_MACRO
 
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-case type::e##upperType: \
+case type::Descriptor::e##upperType: \
 { \
     typenavigator::upperType##NavigatorPtr t = typenavigator::upperType##Navigator::DynamicCastAndCheck(type); \
     datanavigator::NDArrayNavigatorPtr ndarray = datanavigator::NDArrayNavigatorPtr(new datanavigator::NDArrayNavigator()); \
@@ -216,7 +216,7 @@ case type::e##upperType: \
 #undef RUN_ARON_MACRO
 
 #define RUN_ARON_MACRO(upperType, lowerType, capsType, upperData, lowerData, capsData) \
-case type::e##upperType: \
+case type::Descriptor::e##upperType: \
 { \
     typenavigator::upperType##NavigatorPtr t = typenavigator::upperType##Navigator::DynamicCastAndCheck(type); \
     return datanavigator::NavigatorPtr(new datanavigator::upperData##Navigator()); \
@@ -239,7 +239,7 @@ case type::e##upperType: \
             {
 
 #define RUN_ARON_MACRO(upperType, lowerType, capsType, upperData, lowerData, capsData) \
-case type::e##upperType: \
+case type::Descriptor::e##upperType: \
 { \
     typenavigator::upperType##NavigatorPtr t = typenavigator::upperType##Navigator::DynamicCastAndCheck(type); \
     datanavigator::upperData##NavigatorPtr d = datanavigator::upperData##Navigator::DynamicCastAndCheck(data); \
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp
index 7b777b8201d2ddfa302135a1b7795afd134a8c9d..15d698675592fa368cca5b212300d839c2142b8f 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/SerializerFactory.cpp
@@ -36,27 +36,27 @@ namespace armarx::aron::cppcodegenerator
     {
         static const std::map<type::Descriptor, SerializerFactoryPtr> Factories =
         {
-            {type::eObject, SerializerFactoryPtr(new ObjectSerializerFactory())},
-            {type::eDict, SerializerFactoryPtr(new DictSerializerFactory())},
-            {type::eList, SerializerFactoryPtr(new ListSerializerFactory())},
-            {type::eTuple, SerializerFactoryPtr(new TupleSerializerFactory())},
-            {type::ePair, SerializerFactoryPtr(new PairSerializerFactory())},
-            {type::eEigenMatrix, SerializerFactoryPtr(new EigenMatrixSerializerFactory())},
-            {type::eEigenQuaternion, SerializerFactoryPtr(new EigenQuaternionSerializerFactory())},
-            {type::eIVTCByteImage, SerializerFactoryPtr(new IVTCByteImageSerializerFactory())},
-            {type::eOpenCVMat, SerializerFactoryPtr(new OpenCVMatSerializerFactory())},
-            {type::ePCLPointCloud, SerializerFactoryPtr(new PCLPointCloudSerializerFactory())},
-            {type::ePosition, SerializerFactoryPtr(new PositionSerializerFactory())},
-            {type::eOrientation, SerializerFactoryPtr(new OrientationSerializerFactory())},
-            {type::ePose, SerializerFactoryPtr(new PoseSerializerFactory())},
-            {type::eIntEnum, SerializerFactoryPtr(new IntEnumSerializerFactory())},
-            {type::eInt, SerializerFactoryPtr(new IntSerializerFactory())},
-            {type::eLong, SerializerFactoryPtr(new LongSerializerFactory())},
-            {type::eFloat, SerializerFactoryPtr(new FloatSerializerFactory())},
-            {type::eDouble, SerializerFactoryPtr(new DoubleSerializerFactory())},
-            {type::eString, SerializerFactoryPtr(new StringSerializerFactory())},
-            {type::eBool, SerializerFactoryPtr(new BoolSerializerFactory())},
-            {type::eTime, SerializerFactoryPtr(new TimeSerializerFactory())}
+            {type::Descriptor::eObject, SerializerFactoryPtr(new ObjectSerializerFactory())},
+            {type::Descriptor::eDict, SerializerFactoryPtr(new DictSerializerFactory())},
+            {type::Descriptor::eList, SerializerFactoryPtr(new ListSerializerFactory())},
+            {type::Descriptor::eTuple, SerializerFactoryPtr(new TupleSerializerFactory())},
+            {type::Descriptor::ePair, SerializerFactoryPtr(new PairSerializerFactory())},
+            {type::Descriptor::eEigenMatrix, SerializerFactoryPtr(new EigenMatrixSerializerFactory())},
+            {type::Descriptor::eEigenQuaternion, SerializerFactoryPtr(new EigenQuaternionSerializerFactory())},
+            {type::Descriptor::eIVTCByteImage, SerializerFactoryPtr(new IVTCByteImageSerializerFactory())},
+            {type::Descriptor::eOpenCVMat, SerializerFactoryPtr(new OpenCVMatSerializerFactory())},
+            {type::Descriptor::ePCLPointCloud, SerializerFactoryPtr(new PCLPointCloudSerializerFactory())},
+            {type::Descriptor::ePosition, SerializerFactoryPtr(new PositionSerializerFactory())},
+            {type::Descriptor::eOrientation, SerializerFactoryPtr(new OrientationSerializerFactory())},
+            {type::Descriptor::ePose, SerializerFactoryPtr(new PoseSerializerFactory())},
+            {type::Descriptor::eIntEnum, SerializerFactoryPtr(new IntEnumSerializerFactory())},
+            {type::Descriptor::eInt, SerializerFactoryPtr(new IntSerializerFactory())},
+            {type::Descriptor::eLong, SerializerFactoryPtr(new LongSerializerFactory())},
+            {type::Descriptor::eFloat, SerializerFactoryPtr(new FloatSerializerFactory())},
+            {type::Descriptor::eDouble, SerializerFactoryPtr(new DoubleSerializerFactory())},
+            {type::Descriptor::eString, SerializerFactoryPtr(new StringSerializerFactory())},
+            {type::Descriptor::eBool, SerializerFactoryPtr(new BoolSerializerFactory())},
+            {type::Descriptor::eTime, SerializerFactoryPtr(new TimeSerializerFactory())}
         };
 
         //CheckIfPtrIsNull("NavigatorFactory", "create", path, n);
diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.h
index 5e7d3875fe29a4f10e15fb7123fecf33276e19d1..cf5b46c25b102ce0d2e49d4e971a6c5935f50000 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.h
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.h
@@ -61,6 +61,7 @@ namespace armarx::aron::cppcodegenerator::serializer
         virtual CppBlockPtr getReadBlock(const std::string&) const override;
         virtual CppBlockPtr getEqualsBlock(const std::string&, const std::string&) const override;
 
+        // TODO: Move some of those methods to upper class for enums (if we want to support multiple enums)
         CppCtorPtr toCopyCtor(const std::string&) const;
         CppCtorPtr toInnerEnumCtor(const std::string&) const;
         CppEnumPtr toInnerEnumDefinition() const;
diff --git a/source/RobotAPI/libraries/aron/core/io/Data.h b/source/RobotAPI/libraries/aron/core/io/Data.h
index 6d29388942067854205998b2c0aaef4e4b74a402..73c693b53311f47232c1b581698dc7765495c8c4 100644
--- a/source/RobotAPI/libraries/aron/core/io/Data.h
+++ b/source/RobotAPI/libraries/aron/core/io/Data.h
@@ -40,18 +40,18 @@ namespace armarx::aron::io
 
     public:
         // TODO: Remove copy from ReaderWriter
-        static constexpr const char* READER_WRITER_NAME_SLUG = "ARON_NAME";
-        static constexpr const char* READER_WRITER_DICT_ACCEPTED_TYPE_SLUG = "ARON_DICT_ACCEPTED_TYPE";
-        static constexpr const char* READER_WRITER_LIST_ACCEPTED_TYPE_SLUG = "ARON_LIST_ACCEPTED_TYPE";
-
-        static constexpr const char* READER_WRITER_NDARRAY_NAME_SLUG = "ARON_NDARRAY_NAME";
-        static constexpr const char* READER_WRITER_NDARRAY_DIMENSIONS_SLUG = "ARON_NDARRAY_DIMESIONS";
-        static constexpr const char* READER_WRITER_NDARRAY_TYPE_SLUG = "ARON_NDARRAY_TYPE";
-        static constexpr const char* READER_WRITER_NDARRAY_DATA_SLUG = "ARON_NDARRAY_DATA";
-
-        static constexpr const char* READER_WRITER_INT_ENUM_NAME_SLUG = "ARON_INT_ENUM_NAME";
-        static constexpr const char* READER_WRITER_INT_ENUM_VALUE_SLUG = "ARON_INT_ENUM_VALUE";
-        static constexpr const char* READER_WRITER_ENUM_KEY_SLUG = "ARON_ENUM_KEY";
+        static constexpr const char* READER_WRITER_NAME_SLUG = "__ARON_NAME";
+        static constexpr const char* READER_WRITER_DICT_ACCEPTED_TYPE_SLUG = "__ARON_DICT_ACCEPTED_TYPE";
+        static constexpr const char* READER_WRITER_LIST_ACCEPTED_TYPE_SLUG = "__ARON_LIST_ACCEPTED_TYPE";
+
+        static constexpr const char* READER_WRITER_NDARRAY_NAME_SLUG = "__ARON_NDARRAY_NAME";
+        static constexpr const char* READER_WRITER_NDARRAY_DIMENSIONS_SLUG = "__ARON_NDARRAY_DIMESIONS";
+        static constexpr const char* READER_WRITER_NDARRAY_TYPE_SLUG = "__ARON_NDARRAY_TYPE";
+        static constexpr const char* READER_WRITER_NDARRAY_DATA_SLUG = "__ARON_NDARRAY_DATA";
+
+        static constexpr const char* READER_WRITER_INT_ENUM_NAME_SLUG = "__ARON_INT_ENUM_NAME";
+        static constexpr const char* READER_WRITER_INT_ENUM_VALUE_SLUG = "__ARON_INT_ENUM_VALUE";
+        static constexpr const char* READER_WRITER_ENUM_KEY_SLUG = "__ARON_ENUM_KEY";
 
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
     static constexpr const char* READER_WRITER_##capsType##_TYPENAME_SLUG = #capsType;
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
index 7df44a015c8f93f531e1e54c8dd2524ae98308d6..574b9167d3f6b77e4b2a8434a5dfb90911cabd2c 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/Reader.h
@@ -64,6 +64,6 @@ namespace armarx::aron::dataIO
         virtual void loadMember(const std::string&) = 0;
 
         // Helper functions
-        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::eUnknown) const = 0;
+        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const = 0;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.cpp
index 13b6703cd69bffe9e6c8f89cf4164ada98649bc0..a0feee781f33f1623d24948600a26370368db685 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.cpp
@@ -31,21 +31,22 @@
 
 namespace armarx::aron::dataIO
 {
-    void Converter::ConvertFromReader(ReaderInterface& reader, WriterInterface& writer, const aron::typenavigator::NavigatorPtr& expectedStructure)
+    void Converter::ReadAndConvert(ReaderInterface& reader, WriterInterface& writer, const aron::typenavigator::NavigatorPtr& expectedStructure)
     {
-        type::Descriptor t_desc = expectedStructure != nullptr ? expectedStructure->getDescriptor() : type::eUnknown;
+        type::Descriptor t_desc = expectedStructure != nullptr ? expectedStructure->getDescriptor() : type::Descriptor::eUnknown;
+        //std::cout << "Expected Structure: " << type::DESCRIPTOR_TO_STRING(t_desc) << std::endl;
         data::Descriptor desc = reader.getTypeOfNext(t_desc);
         switch (desc)
         {
-            case data::eDict:
+            case data::Descriptor::eDict:
             {
                 int elements = reader.readStartDict();
                 writer.writeStartDict();
 
                 typenavigator::NavigatorPtr childType = nullptr;
-                if (t_desc == type::eDict)
+                if (t_desc == type::Descriptor::eDict)
                 {
-                    auto t = typenavigator::DictNavigator::DynamicCast(expectedStructure);
+                    auto t = typenavigator::DictNavigator::DynamicCastAndCheck(expectedStructure);
                     childType = t->getAcceptedType();
                 }
 
@@ -54,13 +55,13 @@ namespace armarx::aron::dataIO
                     std::string key = reader.readKey();
                     writer.writeKey(key);
 
-                    if (t_desc == type::eObject)
+                    if (t_desc == type::Descriptor::eObject)
                     {
-                        auto t = typenavigator::ObjectNavigator::DynamicCast(expectedStructure);
+                        auto t = typenavigator::ObjectNavigator::DynamicCastAndCheck(expectedStructure);
                         childType = t->getMemberType(key);
                     }
 
-                    Converter::ConvertFromReader(reader, writer, childType);
+                    Converter::ReadAndConvert(reader, writer, childType);
                 }
 
                 writer.writeEndDict();
@@ -68,62 +69,85 @@ namespace armarx::aron::dataIO
 
                 break;
             }
-            case data::eList:
+            case data::Descriptor::eList:
             {
                 int elements = reader.readStartList();
                 writer.writeStartList();
 
                 typenavigator::NavigatorPtr childType = nullptr;
-                if (t_desc == type::eList)
+                if (t_desc == type::Descriptor::eList)
                 {
-                    auto t = typenavigator::ListNavigator::DynamicCast(expectedStructure);
+                    auto t = typenavigator::ListNavigator::DynamicCastAndCheck(expectedStructure);
                     childType = t->getAcceptedType();
                 }
 
                 for (int i = 0; i < elements; ++i)
                 {
-                    if (t_desc == type::eObject)
+                    if (t_desc == type::Descriptor::eObject)
                     {
-                        auto t = typenavigator::TupleNavigator::DynamicCast(expectedStructure);
+                        auto t = typenavigator::TupleNavigator::DynamicCastAndCheck(expectedStructure);
                         childType = t->getAcceptedType(i);
                     }
 
-                    Converter::ConvertFromReader(reader, writer, childType);
+                    Converter::ReadAndConvert(reader, writer, childType);
                 }
 
                 writer.writeEndList();
                 reader.readEndList();
                 break;
             }
-#define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-case data::e##upperType: \
-{ \
-    auto [dims, type] = reader.readStart##upperType(); \
-    int elements = std::accumulate(std::begin(dims), std::end(dims), 1, std::multiplies<int>()); \
-    std::vector<unsigned char> data(elements); \
-    reader.readEnd##upperType(data.data()); \
-    \
-    writer.write##upperType(dims, type, data.data()); \
-    break; \
-}
 
-            HANDLE_COMPLEX_DATA
-#undef RUN_ARON_MACRO
+            case data::Descriptor::eNDArray:
+            {
+                auto [dims, type] = reader.readStartNDArray();
+                int elements = std::accumulate(std::begin(dims), std::end(dims), 1, std::multiplies<int>());
+                std::vector<unsigned char> data(elements);
+                reader.readEndNDArray(data.data());
 
-#define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-case data::e##upperType: \
-{ \
-    lowerType val = reader.readPrimitive<lowerType>(); \
-    writer.writePrimitive(val); \
-    break; \
-}
+                writer.writeNDArray(dims, type, data.data());
+                break;
+            }
 
-            HANDLE_PRIMITIVE_DATA
-#undef RUN_ARON_MACRO
+            case data::Descriptor::eInt:
+            {
+                int val = reader.readPrimitive<int>();
+                writer.writePrimitive(val);
+                break;
+            }
+            case data::Descriptor::eLong:
+            {
+                long val = reader.readPrimitive<long>();
+                writer.writePrimitive(val);
+                break;
+            }
+            case data::Descriptor::eFloat:
+            {
+                float val = reader.readPrimitive<float>();
+                writer.writePrimitive(val);
+                break;
+            }
+            case data::Descriptor::eDouble:
+            {
+                double val = reader.readPrimitive<double>();
+                writer.writePrimitive(val);
+                break;
+            }
+            case data::Descriptor::eString:
+            {
+                std::string val = reader.readPrimitive<std::string>();
+                writer.writePrimitive(val);
+                break;
+            }
+            case data::Descriptor::eBool:
+            {
+                bool val = reader.readPrimitive<bool>();
+                writer.writePrimitive(val);
+                break;
+            }
 
             default:
             {
-                throw error::DescriptorNotValidException("LegacyAronDataReader", "SetupReaderAndGetResult", "Data-Type could not be resolved", desc);
+                throw error::DescriptorNotValidException("Converter", "ReadAndConvert", "Data-Type could not be resolved", desc);
             }
         }
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h b/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h
index d51d81761b764d5616bb70e5cefd67dd105987bd..1ea6c6f5c3bf984d2fad6b8ffd55f7cc7d50f76c 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/converter/Converter.h
@@ -43,6 +43,6 @@ namespace armarx::aron::dataIO
         Converter() = delete;
 
     public:
-        static void ConvertFromReader(ReaderInterface&, WriterInterface&, const aron::typenavigator::NavigatorPtr& expectedStructure = nullptr);
+        static void ReadAndConvert(ReaderInterface&, WriterInterface&, const aron::typenavigator::NavigatorPtr& expectedStructure = nullptr);
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
index a757d2778ca04857fb436977bcec6e4eb9de3710..b1c8e774e9b252bb582ba7a7dbf2c38c8f158122 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/ReaderToken.h
@@ -45,7 +45,7 @@ namespace armarx::aron::dataIO
 
 
         // Interface
-        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::eUnknown) const = 0;
+        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const = 0;
         virtual ElementTypename getNextElement() const = 0;
 
         // General implementation
@@ -115,7 +115,7 @@ namespace armarx::aron::dataIO
 
     protected:
         // members
-        data::Descriptor descriptor = data::eUnknown;
+        data::Descriptor descriptor = data::Descriptor::eUnknown;
         ElementTypename element;
 
         unsigned int childrenSize = 0;
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp
index aa5d3d14864aff4fd5d86b8cfc47b06a81cc0200..2dc7c3db842d4e7deb5ee1c5d94b4be5618f2e64 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.cpp
@@ -72,7 +72,7 @@ namespace armarx::aron::dataIO::reader
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = datanavigator::DictNavigator::DynamicCastAndCheck(current_nav);
         int c = current_nav->childrenSize();
-        auto newToken = std::make_shared<NavigatorReaderToken>(data::eDict, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(data::Descriptor::eDict, current_nav_casted);
         stack.push(newToken);
         return c;
     }
@@ -95,7 +95,7 @@ namespace armarx::aron::dataIO::reader
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = datanavigator::ListNavigator::DynamicCastAndCheck(current_nav);
         int c = current_nav->childrenSize();
-        auto newToken = std::make_shared<NavigatorReaderToken>(data::eList, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(data::Descriptor::eList, current_nav_casted);
         stack.push(newToken);
         return c;
     }
@@ -192,6 +192,17 @@ namespace armarx::aron::dataIO::reader
     // Helper functions
     data::Descriptor NavigatorReader::getTypeOfNext(const type::Descriptor hint) const
     {
+        if (stack.empty())
+        {
+            if (hint == type::Descriptor::eUnknown)
+            {
+                return data::Descriptor::eDict;
+            }
+            else
+            {
+                return Resolver::GetCorresponding(hint);
+            }
+        }
         auto token = stack.top();
         return token->getTypeOfNext(hint);
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h
index 0bcc56b7bdc6e22775fc2d4345e1f9715e942d1f..db52ad1d85c2f10807d10f63bc44c7de717e6b97 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReader.h
@@ -66,7 +66,7 @@ namespace armarx::aron::dataIO::reader
         virtual std::string readKey() override;
         virtual void loadMember(const std::string&) override;
 
-        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::eUnknown) const override;
+        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const override;
 
     private:
         datanavigator::NavigatorPtr getNext();
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h
index 2efb3352f203d93fa0b647ea318affea7d41b4fd..4b85fe7725b3840c2e9c2b87a5d6cc9c48f9e63f 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/navigator/NavigatorReaderToken.h
@@ -69,7 +69,7 @@ namespace armarx::aron::dataIO::reader
             }
         }
 
-        data::Descriptor getTypeOfNext(const type::Descriptor hint = type::eUnknown) const override
+        data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const override
         {
             const datanavigator::NavigatorPtr next = getNextElement();
             return next->getDescriptor();
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
index 9b15c88280210b4e9b2e583ba7439d87e68909d9..c243c4e4beaf851090607423dd91e1d5ade4118a 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
@@ -70,7 +70,7 @@ namespace armarx::aron::dataIO::reader
     {
         nlohmann::json current_json = getNextAndIncrease();
         int c = current_json.size();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(data::eDict, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(data::Descriptor::eDict, current_json);
         stack.push(newToken);
         return c;
     }
@@ -78,7 +78,7 @@ namespace armarx::aron::dataIO::reader
     bool NlohmannJSONReader::readEndDict()
     {
         auto token = stack.top();
-        token->assertType(data::eDict);
+        token->assertType(data::Descriptor::eDict);
 
         if (token->finishedElement())
         {
@@ -92,7 +92,7 @@ namespace armarx::aron::dataIO::reader
     {
         nlohmann::json current_json = getNextAndIncrease();
         int c = current_json.size();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(data::eList, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(data::Descriptor::eList, current_json);
         stack.push(newToken);
         return c;
     }
@@ -100,7 +100,7 @@ namespace armarx::aron::dataIO::reader
     bool NlohmannJSONReader::readEndList()
     {
         auto token = stack.top();
-        token->assertType(data::eList);
+        token->assertType(data::Descriptor::eList);
 
         if (token->finishedElement())
         {
@@ -184,6 +184,17 @@ namespace armarx::aron::dataIO::reader
     // Helper functions
     data::Descriptor NlohmannJSONReader::getTypeOfNext(const type::Descriptor hint) const
     {
+        if (stack.empty())
+        {
+            if (hint == type::Descriptor::eUnknown)
+            {
+                return data::Descriptor::eDict;
+            }
+            else
+            {
+                return Resolver::GetCorresponding(hint);
+            }
+        }
         auto token = stack.top();
         return token->getTypeOfNext(hint);
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h
index 1ca1810a0c3085e4d53b7a79c934dc1eaa7e1e25..7749530308b806da5898881879cef6df26143358 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h
@@ -64,7 +64,7 @@ namespace armarx::aron::dataIO::reader
         virtual std::string readKey() override;
         virtual void loadMember(const std::string&) override;
 
-        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::eUnknown) const override;
+        virtual data::Descriptor getTypeOfNext(const type::Descriptor hint = type::Descriptor::eUnknown) const override;
 
     private:
         nlohmann::json getNext();
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
index d155a2d155027ad03f16a359a903da88dae6776c..04acd920b51789d2ce925f8aab48c268baf3fed7 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
@@ -57,7 +57,7 @@ namespace armarx::aron::dataIO::reader
 
             switch (descriptor)
             {
-                case data::eDict:
+                case data::Descriptor::eDict:
                 {
                     for (auto it = data.begin(); it != data.end(); ++it)
                     {
@@ -66,7 +66,7 @@ namespace armarx::aron::dataIO::reader
                     childrenSize = data.size();
                     break;
                 }
-                case data::eList:
+                case data::Descriptor::eList:
                 {
                     childrenSize = data.size();
                     break;
@@ -84,36 +84,36 @@ namespace armarx::aron::dataIO::reader
                 // Check if specific NDArray key exists
                 if (next.find(io::Data::READER_WRITER_NDARRAY_DATA_SLUG) != next.end())
                 {
-                    return data::eNDArray;
+                    return data::Descriptor::eNDArray;
                 }
-                return data::eDict;
+                return data::Descriptor::eDict;
             }
             if (next.is_array())
             {
-                return data::eList;
+                return data::Descriptor::eList;
             }
             if (next.is_number_integer())
             {
 
                 data::Descriptor d = Resolver::GetFirstIfRelated(
                                          Resolver::GetCorresponding(hint),
-                                         data::eLong);
+                                         data::Descriptor::eLong);
                 return d;
             }
             if (next.is_number_float())
             {
                 data::Descriptor d = Resolver::GetFirstIfRelated(
                                          Resolver::GetCorresponding(hint),
-                                         data::eDouble);
+                                         data::Descriptor::eDouble);
                 return d;
             }
             if (next.is_boolean())
             {
-                return data::eBool;
+                return data::Descriptor::eBool;
             }
             if (next.is_string())
             {
-                return data::eString;
+                return data::Descriptor::eString;
             }
             throw error::AronException("NlohmannJSONReaderToken", "getTypeOfNextElement", "Could not determine the type of an nlohmann::json object. Could not convert to data::Descriptor enum.");
         }
@@ -122,12 +122,12 @@ namespace armarx::aron::dataIO::reader
         {
             switch (descriptor)
             {
-                case data::eDict:
+                case data::Descriptor::eDict:
                 {
                     nlohmann::json ret = element[getCurrentKey()];
                     return ret;
                 }
-                case data::eList:
+                case data::Descriptor::eList:
                 {
                     nlohmann::json ret = element[currentIndex];
                     return ret;
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.cpp
index 9f2dd3cd6e470c72698aae1c5c0bdcd948194e53..b5be280a8cfe72963afa63b88a900b6885250c33 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.cpp
@@ -33,76 +33,76 @@
 namespace armarx::aron::dataIO
 {
 
-    void Visitor::SetupWriterFromAronDataPtr(WriterInterface& writer, const datanavigator::NavigatorPtr& aron)
+    void Visitor::VisitAndSetup(WriterInterface& writer, const datanavigator::NavigatorPtr& aron)
     {
-        SetupWriterFromAronDataPtr(writer, aron->getResult());
+        VisitAndSetup(writer, aron->getResult());
     }
 
-    void Visitor::SetupWriterFromAronDataPtr(WriterInterface& writer, const data::AronDataPtr& aron)
+    void Visitor::VisitAndSetup(WriterInterface& writer, const data::AronDataPtr& aron)
     {
         data::Descriptor desc = Resolver::GetDescriptor(aron);
         switch (desc)
         {
-            case data::eDict:
+            case data::Descriptor::eDict:
             {
                 data::AronDictPtr casted = data::AronDictPtr::dynamicCast(aron);
                 writer.writeStartDict();
                 for (const auto& [key, value] : casted->elements)
                 {
                     writer.writeKey(key);
-                    Visitor::SetupWriterFromAronDataPtr(writer, value);
+                    Visitor::VisitAndSetup(writer, value);
                 }
                 writer.writeEndDict();
                 break;
             }
-            case data::eList:
+            case data::Descriptor::eList:
             {
                 data::AronListPtr casted = data::AronListPtr::dynamicCast(aron);
                 writer.writeStartList();
                 for (const auto& value : casted->elements)
                 {
-                    Visitor::SetupWriterFromAronDataPtr(writer, value);
+                    Visitor::VisitAndSetup(writer, value);
                 }
                 writer.writeEndList();
                 break;
             }
-            case data::eNDArray:
+            case data::Descriptor::eNDArray:
             {
                 data::AronNDArrayPtr casted = data::AronNDArrayPtr::dynamicCast(aron);
                 writer.writeNDArray(casted->dimensions, casted->type, casted->data.data());
                 break;
             }
-            case data::eInt:
+            case data::Descriptor::eInt:
             {
                 data::AronIntPtr casted = data::AronIntPtr::dynamicCast(aron);
                 writer.writePrimitive(casted->value);
                 break;
             }
-            case data::eLong:
+            case data::Descriptor::eLong:
             {
                 data::AronLongPtr casted = data::AronLongPtr::dynamicCast(aron);
                 writer.writePrimitive(casted->value);
                 break;
             }
-            case data::eFloat:
+            case data::Descriptor::eFloat:
             {
                 data::AronFloatPtr casted = data::AronFloatPtr::dynamicCast(aron);
                 writer.writePrimitive(casted->value);
                 break;
             }
-            case data::eDouble:
+            case data::Descriptor::eDouble:
             {
                 data::AronDoublePtr casted = data::AronDoublePtr::dynamicCast(aron);
                 writer.writePrimitive(casted->value);
                 break;
             }
-            case data::eString:
+            case data::Descriptor::eString:
             {
                 data::AronStringPtr casted = data::AronStringPtr::dynamicCast(aron);
                 writer.writePrimitive(casted->value);
                 break;
             }
-            case data::eBool:
+            case data::Descriptor::eBool:
             {
                 data::AronBoolPtr casted = data::AronBoolPtr::dynamicCast(aron);
                 writer.writePrimitive(casted->value);
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h b/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h
index b45ef50c60207e97e6e29e170df39cf0be237a90..b6b00cbbc7d55ff95c3a1674af3dd7d6b9b28e29 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/visitor/Visitor.h
@@ -41,8 +41,8 @@ namespace armarx::aron::dataIO
         Visitor() = delete;
 
     public:
-        static void SetupWriterFromAronDataPtr(WriterInterface&, const datanavigator::NavigatorPtr&);
-        static void SetupWriterFromAronDataPtr(WriterInterface&, const data::AronDataPtr&);
+        static void VisitAndSetup(WriterInterface&, const datanavigator::NavigatorPtr&);
+        static void VisitAndSetup(WriterInterface&, const data::AronDataPtr&);
 
     public:
     };
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/WriterToken.h b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/WriterToken.h
index 950baf3f13359a2ff38db78a16af0c73e24d303e..f91f6c0404fa5f1efaca3301b754165e98abebc8 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/WriterToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/WriterToken.h
@@ -71,9 +71,9 @@ namespace armarx::aron::dataIO
             data::Descriptor desc = this->getDescriptor();
             switch (desc)
             {
-                case data::eDict:
+                case data::Descriptor::eDict:
                     return currentKey;
-                case data::eList:
+                case data::Descriptor::eList:
                     return std::to_string(currentIndex);
                 default:
                     throw error::DescriptorNotValidException("NavigatorWriterToken", "toElementAccessor", "Could not resove a type of a navigator. Allowed are only containers.", desc);
@@ -82,7 +82,7 @@ namespace armarx::aron::dataIO
 
     protected:
         // members
-        data::Descriptor descriptor = data::eUnknown;
+        data::Descriptor descriptor = data::Descriptor::eUnknown;
         ElementTypename element;
 
         // current index
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp
index adebb69a3a86875ac18e9854c96256c01458a9a3..15f57ecf56e00bf09720c4250e8972b9f79f546d 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.cpp
@@ -53,7 +53,7 @@ namespace armarx::aron::dataIO::writer
     {
         Path path = generatePath();
         auto data = std::make_shared<datanavigator::DictNavigator>(path);
-        auto new_token = std::make_shared<NavigatorWriterToken>(data::eDict, data);
+        auto new_token = std::make_shared<NavigatorWriterToken>(data::Descriptor::eDict, data);
         stack.push(new_token);
     }
 
@@ -73,7 +73,7 @@ namespace armarx::aron::dataIO::writer
     {
         Path path = generatePath();
         auto data = std::make_shared<datanavigator::ListNavigator>(path);
-        auto new_token = std::make_shared<NavigatorWriterToken>(data::eList, data);
+        auto new_token = std::make_shared<NavigatorWriterToken>(data::Descriptor::eList, data);
         stack.push(new_token);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
index e57ee04fd96febf4aeeb128385ac14dce87d9217..b768c5da072915d37406b2c0d7f3fb9bb5839dd9 100644
--- a/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
@@ -32,7 +32,7 @@ namespace armarx::aron::dataIO::writer
     void NlohmannJSONWriter::writeStartDict()
     {
         nlohmann::json data;
-        auto new_token = std::make_shared<NlohmannJSONWriterToken>(data::eDict, data);
+        auto new_token = std::make_shared<NlohmannJSONWriterToken>(data::Descriptor::eDict, data);
         stack.push(new_token);
     }
 
@@ -51,7 +51,7 @@ namespace armarx::aron::dataIO::writer
     void NlohmannJSONWriter::writeStartList()
     {
         nlohmann::json data;
-        auto new_token = std::make_shared<NlohmannJSONWriterToken>(data::eList, data);
+        auto new_token = std::make_shared<NlohmannJSONWriterToken>(data::Descriptor::eList, data);
         stack.push(new_token);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp
index b9aca9ffceea3bbae3fbd76794112bdca58379d8..48decff3a1763338b8d2de06c217bfa38b60cf86 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.cpp
@@ -27,12 +27,12 @@
 
 namespace armarx::aron::typeIO
 {
-    void Converter::ConvertFromReader(ReaderInterface& reader, WriterInterface& writer)
+    void Converter::ReadAndConvert(ReaderInterface& reader, WriterInterface& writer)
     {
         type::Descriptor desc = reader.getTypeOfNext();
         switch (desc)
         {
-            case type::eObject:
+            case type::Descriptor::eObject:
             {
                 const auto [name, elements] = reader.readStartObject();
                 writer.writeStartObject(name);
@@ -41,134 +41,134 @@ namespace armarx::aron::typeIO
                 {
                     std::string key = reader.readKey();
                     writer.writeKey(key);
-                    Converter::ConvertFromReader(reader, writer);
+                    Converter::ReadAndConvert(reader, writer);
                 }
 
                 writer.writeEndObject();
                 reader.readEndObject();
                 break;
             }
-            case type::eDict:
+            case type::Descriptor::eDict:
             {
                 reader.readStartDict();
                 writer.writeStartDict();
 
-                Converter::ConvertFromReader(reader, writer);
+                Converter::ReadAndConvert(reader, writer);
 
                 writer.writeEndDict();
                 reader.readEndDict();
                 break;
             }
-            case type::eTuple:
+            case type::Descriptor::eTuple:
             {
                 int elements = reader.readStartTuple();
                 writer.writeStartTuple();
 
                 for (int i = 0; i < elements; ++i)
                 {
-                    Converter::ConvertFromReader(reader, writer);
+                    Converter::ReadAndConvert(reader, writer);
                 }
 
                 writer.writeEndTuple();
                 reader.readEndTuple();
                 break;
             }
-            case type::eList:
+            case type::Descriptor::eList:
             {
                 reader.readStartList();
                 writer.writeStartList();
 
-                Converter::ConvertFromReader(reader, writer);
+                Converter::ReadAndConvert(reader, writer);
 
                 writer.writeEndList();
                 reader.readEndList();
                 break;
             }
-            case type::eEigenMatrix:
+            case type::Descriptor::eEigenMatrix:
             {
                 auto x = reader.readEigenMatrix();
                 writer.writeEigenMatrix(std::get<0>(x), std::get<1>(x));
                 break;
             }
-            case type::eEigenQuaternion:
+            case type::Descriptor::eEigenQuaternion:
             {
                 auto x = reader.readEigenQuaternion();
                 writer.writeEigenQuaternion(x);
                 break;
             }
-            case type::eIVTCByteImage:
+            case type::Descriptor::eIVTCByteImage:
             {
                 auto x = reader.readIVTCByteImage();
                 writer.writeIVTCByteImage(std::get<0>(x), std::get<1>(x), std::get<2>(x));
                 break;
             }
-            case type::eOpenCVMat:
+            case type::Descriptor::eOpenCVMat:
             {
                 auto x = reader.readOpenCVMat();
                 writer.writeOpenCVMat(std::get<0>(x), std::get<1>(x));
                 break;
             }
-            case type::ePCLPointCloud:
+            case type::Descriptor::ePCLPointCloud:
             {
                 auto x = reader.readPCLPointCloud();
                 writer.writePCLPointCloud(std::get<0>(x), std::get<1>(x), std::get<2>(x));
                 break;
             }
-            case type::ePosition:
+            case type::Descriptor::ePosition:
             {
                 reader.readPosition();
                 writer.writePosition();
                 break;
             }
-            case type::eOrientation:
+            case type::Descriptor::eOrientation:
             {
                 reader.readOrientation();
                 writer.writeOrientation();
                 break;
             }
-            case type::ePose:
+            case type::Descriptor::ePose:
             {
                 reader.readPose();
                 writer.writePose();
                 break;
             }
-            case type::eInt:
+            case type::Descriptor::eInt:
             {
                 reader.readInt();
                 writer.writeInt();
                 break;
             }
-            case type::eLong:
+            case type::Descriptor::eLong:
             {
                 reader.readLong();
                 writer.writeLong();
                 break;
             }
-            case type::eFloat:
+            case type::Descriptor::eFloat:
             {
                 reader.readFloat();
                 writer.writeFloat();
                 break;
             }
-            case type::eDouble:
+            case type::Descriptor::eDouble:
             {
                 reader.readDouble();
                 writer.writeDouble();
                 break;
             }
-            case type::eString:
+            case type::Descriptor::eString:
             {
                 reader.readString();
                 writer.writeString();
                 break;
             }
-            case type::eBool:
+            case type::Descriptor::eBool:
             {
                 reader.readBool();
                 writer.writeBool();
                 break;
             }
-            case type::eTime:
+            case type::Descriptor::eTime:
             {
                 reader.readTime();
                 writer.writeTime();
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h b/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h
index f1c59c61894ff07dfdea24d1f5682620392ebf35..8ef1007efb1d06ac2b0360ccc8008f7fdfa634d2 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/converter/Converter.h
@@ -45,7 +45,7 @@ namespace armarx::aron::typeIO
         Converter() = delete;
 
     public:
-        static void ConvertFromReader(ReaderInterface&, WriterInterface&);
+        static void ReadAndConvert(ReaderInterface&, WriterInterface&);
 
     public:
     };
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/ReaderToken.h b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/ReaderToken.h
index c4487c6baee1fd033932c276dc114891f274d575..17b364ff4874a397820cf3143fb180cf21cd8275 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/ReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/ReaderToken.h
@@ -54,8 +54,8 @@ namespace armarx::aron::typeIO
         {
             switch (descriptor)
             {
-                case type::eObject:
-                case type::eIntEnum:
+                case type::Descriptor::eObject:
+                case type::Descriptor::eIntEnum:
                 {
                     return elementName;
                 }
@@ -125,7 +125,7 @@ namespace armarx::aron::typeIO
 
     protected:
         // members
-        type::Descriptor descriptor = type::eUnknown;
+        type::Descriptor descriptor = type::Descriptor::eUnknown;
         ElementTypename element;
         std::string elementName = "";
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp
index 19a19936f8cc8e01f494c00105735a6556c1ef14..0effe2a60983b988abd7c3e8ae8191f69e30ee0d 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/navigator/NavigatorReader.cpp
@@ -59,7 +59,7 @@ namespace armarx::aron::typeIO::reader
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::ObjectNavigator::DynamicCastAndCheck(current_nav);
-        auto newToken = std::make_shared<NavigatorReaderToken>(type::eObject, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eObject, current_nav_casted);
         stack.push(newToken);
         return {newToken->getElementName(), newToken->getElementChildrenSize()};
     }
@@ -67,7 +67,7 @@ namespace armarx::aron::typeIO::reader
     bool NavigatorReader::readEndObject()
     {
         auto token = stack.top();
-        token->assertType(type::eObject);
+        token->assertType(type::Descriptor::eObject);
 
         if (token->finishedElement())
         {
@@ -81,7 +81,7 @@ namespace armarx::aron::typeIO::reader
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::DictNavigator::DynamicCastAndCheck(current_nav);
-        auto newToken = std::make_shared<NavigatorReaderToken>(type::eDict, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eDict, current_nav_casted);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -89,7 +89,7 @@ namespace armarx::aron::typeIO::reader
     bool NavigatorReader::readEndDict()
     {
         auto token = stack.top();
-        token->assertType(type::eDict);
+        token->assertType(type::Descriptor::eDict);
 
         if (token->finishedElement())
         {
@@ -103,7 +103,7 @@ namespace armarx::aron::typeIO::reader
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::ListNavigator::DynamicCastAndCheck(current_nav);
-        auto newToken = std::make_shared<NavigatorReaderToken>(type::eList, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eList, current_nav_casted);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -111,7 +111,7 @@ namespace armarx::aron::typeIO::reader
     bool NavigatorReader::readEndList()
     {
         auto token = stack.top();
-        token->assertType(type::eList);
+        token->assertType(type::Descriptor::eList);
 
         if (token->finishedElement())
         {
@@ -125,7 +125,7 @@ namespace armarx::aron::typeIO::reader
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::TupleNavigator::DynamicCastAndCheck(current_nav);
-        auto newToken = std::make_shared<NavigatorReaderToken>(type::eTuple, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::eTuple, current_nav_casted);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -133,7 +133,7 @@ namespace armarx::aron::typeIO::reader
     bool NavigatorReader::readEndTuple()
     {
         auto token = stack.top();
-        token->assertType(type::eTuple);
+        token->assertType(type::Descriptor::eTuple);
 
         if (token->finishedElement())
         {
@@ -147,7 +147,7 @@ namespace armarx::aron::typeIO::reader
     {
         auto current_nav = getNextAndIncrease();
         auto current_nav_casted = typenavigator::PairNavigator::DynamicCastAndCheck(current_nav);
-        auto newToken = std::make_shared<NavigatorReaderToken>(type::ePair, current_nav_casted);
+        auto newToken = std::make_shared<NavigatorReaderToken>(type::Descriptor::ePair, current_nav_casted);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -155,7 +155,7 @@ namespace armarx::aron::typeIO::reader
     bool NavigatorReader::readEndPair()
     {
         auto token = stack.top();
-        token->assertType(type::ePair);
+        token->assertType(type::Descriptor::ePair);
 
         if (token->finishedElement())
         {
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
index eea8c5dc279d527d9aa6024b1c3bfed2f2e9da8a..98d6953ade3f36ca2408dc379a3b325e8fd007de 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReader.cpp
@@ -40,7 +40,7 @@ namespace armarx::aron::typeIO::reader
     }
 
     NlohmannJSONReader::NlohmannJSONReader(const std::string& n) :
-        input(n)
+        input(nlohmann::json::parse(n))
     {
     }
 
@@ -58,7 +58,7 @@ namespace armarx::aron::typeIO::reader
     std::tuple<std::string, int> NlohmannJSONReader::readStartObject()
     {
         nlohmann::json current_json = getNextAndIncrease();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::eObject, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eObject, current_json);
         stack.push(newToken);
         return {newToken->getElementName(), newToken->getElementChildrenSize()};
     }
@@ -66,7 +66,7 @@ namespace armarx::aron::typeIO::reader
     bool NlohmannJSONReader::readEndObject()
     {
         NlohmannJSONReaderTokenPtr token = stack.top();
-        token->assertType(type::eObject);
+        token->assertType(type::Descriptor::eObject);
 
         if (token->finishedElement())
         {
@@ -79,7 +79,7 @@ namespace armarx::aron::typeIO::reader
     int NlohmannJSONReader::readStartDict()
     {
         nlohmann::json current_json = getNextAndIncrease();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::eDict, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eDict, current_json);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -87,7 +87,7 @@ namespace armarx::aron::typeIO::reader
     bool NlohmannJSONReader::readEndDict()
     {
         NlohmannJSONReaderTokenPtr token = stack.top();
-        token->assertType(type::eDict);
+        token->assertType(type::Descriptor::eDict);
 
         if (token->finishedElement())
         {
@@ -100,7 +100,7 @@ namespace armarx::aron::typeIO::reader
     int NlohmannJSONReader::readStartList()
     {
         nlohmann::json current_json = getNextAndIncrease();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::eList, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eList, current_json);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -108,7 +108,7 @@ namespace armarx::aron::typeIO::reader
     bool NlohmannJSONReader::readEndList()
     {
         NlohmannJSONReaderTokenPtr token = stack.top();
-        token->assertType(type::eList);
+        token->assertType(type::Descriptor::eList);
 
         if (token->finishedElement())
         {
@@ -121,7 +121,7 @@ namespace armarx::aron::typeIO::reader
     int NlohmannJSONReader::readStartTuple()
     {
         nlohmann::json current_json = getNextAndIncrease();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::eTuple, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::eTuple, current_json);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -129,7 +129,7 @@ namespace armarx::aron::typeIO::reader
     bool NlohmannJSONReader::readEndTuple()
     {
         NlohmannJSONReaderTokenPtr token = stack.top();
-        token->assertType(type::eTuple);
+        token->assertType(type::Descriptor::eTuple);
 
         if (token->finishedElement())
         {
@@ -142,7 +142,7 @@ namespace armarx::aron::typeIO::reader
     int NlohmannJSONReader::readStartPair()
     {
         nlohmann::json current_json = getNextAndIncrease();
-        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::ePair, current_json);
+        auto newToken = std::make_shared<NlohmannJSONReaderToken>(type::Descriptor::ePair, current_json);
         stack.push(newToken);
         return newToken->getElementChildrenSize();
     }
@@ -150,7 +150,7 @@ namespace armarx::aron::typeIO::reader
     bool NlohmannJSONReader::readEndPair()
     {
         NlohmannJSONReaderTokenPtr token = stack.top();
-        token->assertType(type::ePair);
+        token->assertType(type::Descriptor::ePair);
 
         if (token->finishedElement())
         {
@@ -268,6 +268,11 @@ namespace armarx::aron::typeIO::reader
     // Helper functions
     type::Descriptor NlohmannJSONReader::getTypeOfNext() const
     {
+        if (stack.empty())
+        {
+            return type::Descriptor::eObject;
+        }
+
         auto token = stack.top();
         return token->getTypeOfNext();
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
index 78b3c04ab5fe09cef34cee4c96c5749a9eff908c..3d3503af2567199be5ebf627f45813f2b220c606 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/reader/nlohmannJSON/NlohmannJSONReaderToken.h
@@ -57,14 +57,14 @@ namespace armarx::aron::typeIO::reader
             {
                 case type::Descriptor::eObject:
                 {
-                    for (auto it = type.begin(); it != type.end(); ++it)
+                    for (auto& [key, val] : type.get<nlohmann::json::object_t>())
                     {
-                        if (it.key() == io::Data::READER_WRITER_NAME_SLUG)
+                        if (key == io::Data::READER_WRITER_NAME_SLUG)
                         {
                             continue;
                         }
 
-                        allMemberNames.push_back(it.key());
+                        allMemberNames.push_back(key);
                     }
                     childrenSize = allMemberNames.size();
                     elementName = element[io::Data::READER_WRITER_NAME_SLUG];
@@ -85,7 +85,7 @@ namespace armarx::aron::typeIO::reader
                     childrenSize = 1;
                     break;
                 }
-                case type::ePair:
+                case type::Descriptor::ePair:
                 {
                     childrenSize = 2;
                     break;
@@ -103,87 +103,87 @@ namespace armarx::aron::typeIO::reader
             {
                 if (next.find(io::Data::READER_WRITER_DICT_ACCEPTED_TYPE_SLUG) != next.end())
                 {
-                    return type::eDict;
+                    return type::Descriptor::eDict;
                 }
                 if (next.find(io::Data::READER_WRITER_LIST_ACCEPTED_TYPE_SLUG) != next.end())
                 {
-                    return type::eList;
+                    return type::Descriptor::eList;
                 }
                 if (next.find(io::Data::READER_WRITER_INT_ENUM_NAME_SLUG) != next.end())
                 {
-                    return type::eIntEnum;
+                    return type::Descriptor::eIntEnum;
                 }
                 if (next.find(io::Data::READER_WRITER_NDARRAY_NAME_SLUG) != next.end())
                 {
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "EigenMatrix")
                     {
-                        return type::eEigenMatrix;
+                        return type::Descriptor::eEigenMatrix;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "EigenQuaternion")
                     {
-                        return type::eEigenQuaternion;
+                        return type::Descriptor::eEigenQuaternion;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "IVTCByteImage")
                     {
-                        return type::eIVTCByteImage;
+                        return type::Descriptor::eIVTCByteImage;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "OpenCVMat")
                     {
-                        return type::eOpenCVMat;
+                        return type::Descriptor::eOpenCVMat;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "PCLPointCloud")
                     {
-                        return type::ePCLPointCloud;
+                        return type::Descriptor::ePCLPointCloud;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "Position")
                     {
-                        return type::ePosition;
+                        return type::Descriptor::ePosition;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "Orientation")
                     {
-                        return type::eOrientation;
+                        return type::Descriptor::eOrientation;
                     }
                     if (next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG] == "Pose")
                     {
-                        return type::ePose;
+                        return type::Descriptor::ePose;
                     }
                     throw error::AronException("NlohmannJSONReaderToken", "getTypeOfNextElement", "Could not determine the type of an nlohmann::json object. Found indicator of NDArray but could not resolve real type. Found JSON: " + next[io::Data::READER_WRITER_NDARRAY_NAME_SLUG].dump(2));
                 }
-                return type::eObject;
+                return type::Descriptor::eObject;
             }
             if (next.is_array())
             {
-                return type::eTuple;
+                return type::Descriptor::eTuple;
             }
             if (next.is_string())
             {
                 if (next == io::Data::READER_WRITER_INT_TYPENAME_SLUG)
                 {
-                    return type::eInt;
+                    return type::Descriptor::eInt;
                 }
                 if (next == io::Data::READER_WRITER_LONG_TYPENAME_SLUG)
                 {
-                    return type::eLong;
+                    return type::Descriptor::eLong;
                 }
                 if (next == io::Data::READER_WRITER_FLOAT_TYPENAME_SLUG)
                 {
-                    return type::eFloat;
+                    return type::Descriptor::eFloat;
                 }
                 if (next == io::Data::READER_WRITER_DOUBLE_TYPENAME_SLUG)
                 {
-                    return type::eDouble;
+                    return type::Descriptor::eDouble;
                 }
                 if (next == io::Data::READER_WRITER_STRING_TYPENAME_SLUG)
                 {
-                    return type::eString;
+                    return type::Descriptor::eString;
                 }
                 if (next == io::Data::READER_WRITER_BOOL_TYPENAME_SLUG)
                 {
-                    return type::eBool;
+                    return type::Descriptor::eBool;
                 }
                 if (next == io::Data::READER_WRITER_TIME_TYPENAME_SLUG)
                 {
-                    return type::eTime;
+                    return type::Descriptor::eTime;
                 }
             }
             throw error::AronException("NlohmannJSONReaderToken", "getTypeOfNextElement", "Could not determine the type of an nlohmann::json object. Could not convert to type::Descriptor enum. Found JSON: " + next.dump(2));
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp
index 99005c64e9a148fad4cbf4b54932d10f68332a5a..1b0bb02c4ea191472b8a5502ade389fefcc30028 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.cpp
@@ -33,137 +33,137 @@
 namespace armarx::aron::typeIO
 {
 
-    void Visitor::SetupWriterFromAronTypePtr(WriterInterface& writer, const typenavigator::NavigatorPtr& aron)
+    void Visitor::VisitAndSetup(WriterInterface& writer, const typenavigator::NavigatorPtr& aron)
     {
-        SetupWriterFromAronTypePtr(writer, aron->getResult());
+        VisitAndSetup(writer, aron->getResult());
     }
 
-    void Visitor::SetupWriterFromAronTypePtr(WriterInterface& writer, const type::AronTypePtr& aron)
+    void Visitor::VisitAndSetup(WriterInterface& writer, const type::AronTypePtr& aron)
     {
         type::Descriptor desc = Resolver::GetDescriptor(aron);
         switch (desc)
         {
-            case type::eObject:
+            case type::Descriptor::eObject:
             {
                 type::AronObjectPtr casted = type::AronObjectPtr::dynamicCast(aron);
                 writer.writeStartObject(casted->objectName);
                 for (const auto& [key, value] : casted->elementTypes)
                 {
                     writer.writeKey(key);
-                    Visitor::SetupWriterFromAronTypePtr(writer, value);
+                    Visitor::VisitAndSetup(writer, value);
                 }
                 writer.writeEndObject();
                 break;
             }
-            case type::eDict:
+            case type::Descriptor::eDict:
             {
                 type::AronDictPtr casted = type::AronDictPtr::dynamicCast(aron);
                 writer.writeStartDict();
-                Visitor::SetupWriterFromAronTypePtr(writer, casted->acceptedType);
+                Visitor::VisitAndSetup(writer, casted->acceptedType);
                 writer.writeEndDict();
                 break;
             }
-            case type::eTuple:
+            case type::Descriptor::eTuple:
             {
                 type::AronTuplePtr casted = type::AronTuplePtr::dynamicCast(aron);
                 writer.writeStartTuple();
                 for (const auto& value : casted->elementTypes)
                 {
-                    Visitor::SetupWriterFromAronTypePtr(writer, value);
+                    Visitor::VisitAndSetup(writer, value);
                 }
                 writer.writeEndTuple();
                 break;
             }
-            case type::eList:
+            case type::Descriptor::eList:
             {
                 type::AronListPtr casted = type::AronListPtr::dynamicCast(aron);
                 writer.writeStartList();
-                Visitor::SetupWriterFromAronTypePtr(writer, casted->acceptedType);
+                Visitor::VisitAndSetup(writer, casted->acceptedType);
                 writer.writeEndList();
                 break;
             }
-            case type::eEigenMatrix:
+            case type::Descriptor::eEigenMatrix:
             {
                 type::AronEigenMatrixPtr casted = type::AronEigenMatrixPtr::dynamicCast(aron);
                 writer.writeEigenMatrix(casted->dimensions, casted->typeName);
                 break;
             }
-            case type::eEigenQuaternion:
+            case type::Descriptor::eEigenQuaternion:
             {
                 type::AronEigenQuaternionPtr casted = type::AronEigenQuaternionPtr::dynamicCast(aron);
                 writer.writeEigenQuaternion(casted->typeName);
                 break;
             }
-            case type::eIVTCByteImage:
+            case type::Descriptor::eIVTCByteImage:
             {
                 type::AronIVTCByteImagePtr casted = type::AronIVTCByteImagePtr::dynamicCast(aron);
                 writer.writeIVTCByteImage(casted->width, casted->height, casted->typeName);
                 break;
             }
-            case type::eOpenCVMat:
+            case type::Descriptor::eOpenCVMat:
             {
                 type::AronOpenCVMatPtr casted = type::AronOpenCVMatPtr::dynamicCast(aron);
                 writer.writeOpenCVMat(casted->dimensions, casted->typeName);
                 break;
             }
-            case type::ePCLPointCloud:
+            case type::Descriptor::ePCLPointCloud:
             {
                 type::AronPCLPointCloudPtr casted = type::AronPCLPointCloudPtr::dynamicCast(aron);
                 writer.writePCLPointCloud(casted->width, casted->height, casted->typeName);
                 break;
             }
-            case type::ePosition:
+            case type::Descriptor::ePosition:
             {
                 writer.writePosition();
                 break;
             }
-            case type::eOrientation:
+            case type::Descriptor::eOrientation:
             {
                 writer.writeOrientation();
                 break;
             }
-            case type::ePose:
+            case type::Descriptor::ePose:
             {
                 writer.writePose();
                 break;
             }
-            case type::eInt:
+            case type::Descriptor::eInt:
             {
                 type::AronIntPtr casted = type::AronIntPtr::dynamicCast(aron);
                 writer.writeInt();
                 break;
             }
-            case type::eLong:
+            case type::Descriptor::eLong:
             {
                 type::AronLongPtr casted = type::AronLongPtr::dynamicCast(aron);
                 writer.writeLong();
                 break;
             }
-            case type::eFloat:
+            case type::Descriptor::eFloat:
             {
                 type::AronFloatPtr casted = type::AronFloatPtr::dynamicCast(aron);
                 writer.writeFloat();
                 break;
             }
-            case type::eDouble:
+            case type::Descriptor::eDouble:
             {
                 type::AronDoublePtr casted = type::AronDoublePtr::dynamicCast(aron);
                 writer.writeDouble();
                 break;
             }
-            case type::eString:
+            case type::Descriptor::eString:
             {
                 type::AronStringPtr casted = type::AronStringPtr::dynamicCast(aron);
                 writer.writeString();
                 break;
             }
-            case type::eBool:
+            case type::Descriptor::eBool:
             {
                 type::AronBoolPtr casted = type::AronBoolPtr::dynamicCast(aron);
                 writer.writeBool();
                 break;
             }
-            case type::eTime:
+            case type::Descriptor::eTime:
             {
                 type::AronTimePtr casted = type::AronTimePtr::dynamicCast(aron);
                 writer.writeTime();
@@ -171,7 +171,7 @@ namespace armarx::aron::typeIO
             }
             default:
             {
-                throw error::DescriptorNotValidException("LegacyAronTypeWriter", "SetupWriterFromAronTypePtr", "Type-Type could not be resolved. The ice_id of the input was: " + aron->ice_id(), desc);
+                throw error::DescriptorNotValidException("Visitor", "SetupWriterFromAronTypePtr", "Type-Type could not be resolved. The ice_id of the input was: " + aron->ice_id(), desc);
             }
         }
     }
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h b/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h
index 6f781b3dae61236e202ffffd0fd243f89732f5d7..fc9ea5b879011b109b5831418feab0e373311aef 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/visitor/Visitor.h
@@ -41,8 +41,8 @@ namespace armarx::aron::typeIO
         Visitor() = delete;
 
     public:
-        static void SetupWriterFromAronTypePtr(WriterInterface&, const typenavigator::NavigatorPtr&);
-        static void SetupWriterFromAronTypePtr(WriterInterface&, const type::AronTypePtr&);
+        static void VisitAndSetup(WriterInterface&, const typenavigator::NavigatorPtr&);
+        static void VisitAndSetup(WriterInterface&, const type::AronTypePtr&);
 
     public:
     };
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/WriterToken.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/WriterToken.h
index 2b858da0c52b65d3e13d72b4ec3d11edc7ef7e4d..37be1d9cae29ffd46a84ab818fd3ac9f6967b705 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/WriterToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/WriterToken.h
@@ -86,7 +86,7 @@ namespace armarx::aron::typeIO
 
     protected:
         // members
-        type::Descriptor descriptor = type::eUnknown;
+        type::Descriptor descriptor = type::Descriptor::eUnknown;
         ElementTypename element;
 
         // current index
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriterToken.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriterToken.h
index 20b337298c61c58e0665fb1bcf21bb54eb1d845d..d94350f9df9a19ef04898b70e34449c883062a95 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriterToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriterToken.h
@@ -56,32 +56,32 @@ namespace armarx::aron::typeIO::writer
         {
             switch (descriptor)
             {
-                case type::eDict:
+                case type::Descriptor::eDict:
                 {
                     typenavigator::DictNavigatorPtr casted = typenavigator::DictNavigator::DynamicCastAndCheck(element);
                     casted->setAcceptedType(n);
                     break;
                 }
-                case type::eList:
+                case type::Descriptor::eList:
                 {
                     typenavigator::ListNavigatorPtr casted = typenavigator::ListNavigator::DynamicCastAndCheck(element);
                     casted->setAcceptedType(n);
                     break;
                 }
-                case type::eObject:
+                case type::Descriptor::eObject:
                 {
                     typenavigator::ObjectNavigatorPtr casted = typenavigator::ObjectNavigator::DynamicCastAndCheck(element);
                     casted->addMemberType(currentKey, n);
                     break;
                 }
-                case type::eTuple:
+                case type::Descriptor::eTuple:
                 {
                     typenavigator::TupleNavigatorPtr casted = typenavigator::TupleNavigator::DynamicCastAndCheck(element);
                     casted->addAcceptedType(n);
                     currentIndex++;
                     break;
                 }
-                case type::ePair:
+                case type::Descriptor::ePair:
                 {
                     typenavigator::PairNavigatorPtr casted = typenavigator::PairNavigator::DynamicCastAndCheck(element);
                     casted->addAcceptedType(n);
@@ -98,13 +98,13 @@ namespace armarx::aron::typeIO::writer
         {
             switch (descriptor)
             {
-                case type::eObject:
+                case type::Descriptor::eObject:
                 {
                     typenavigator::ObjectNavigatorPtr casted = typenavigator::ObjectNavigator::DynamicCast(element);
                     casted->setObjectName(n);
                     break;
                 }
-                case type::eIntEnum:
+                case type::Descriptor::eIntEnum:
                 {
                     typenavigator::IntEnumNavigatorPtr casted = typenavigator::IntEnumNavigator::DynamicCast(element);
                     casted->setEnumName(n);
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
index 187c648096a0fa0e3c9e3b406b1dbc4a7f0b1dcf..0f3e96192baf5c2c5d088e0c3a5a2fb4e354d68d 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp
@@ -30,7 +30,7 @@ namespace armarx::aron::typeIO::writer
     {
         nlohmann::json data;
         data[io::Data::READER_WRITER_NAME_SLUG] = n;
-        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eList, data);
+        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eObject, data);
         stack.push(new_token);
     }
 
@@ -68,7 +68,7 @@ namespace armarx::aron::typeIO::writer
     void NlohmannJSONWriter::writeStartDict()
     {
         nlohmann::json data;
-        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eList, data);
+        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eDict, data);
         stack.push(new_token);
     }
 
@@ -87,7 +87,7 @@ namespace armarx::aron::typeIO::writer
     void NlohmannJSONWriter::writeStartTuple()
     {
         nlohmann::json data;
-        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eList, data);
+        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eTuple, data);
         stack.push(new_token);
     }
 
@@ -106,7 +106,7 @@ namespace armarx::aron::typeIO::writer
     void NlohmannJSONWriter::writeStartPair()
     {
         nlohmann::json data;
-        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::eList, data);
+        auto new_token = std::make_shared<NlohmannJSONWriterToken>(type::Descriptor::ePair, data);
         stack.push(new_token);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriterToken.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriterToken.h
index 826524dddcd7c6a7d2e8bf7919240bb7d1b109b0..ea4410885b98ece7ee08e8c0ffb1c7443253c5f6 100644
--- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriterToken.h
+++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriterToken.h
@@ -94,16 +94,5 @@ namespace armarx::aron::typeIO::writer
             }
             element[io::Data::READER_WRITER_NAME_SLUG] = n;
         }
-
-    private:
-        // members
-        type::Descriptor descriptor;
-        nlohmann::json element;
-
-        // current index
-        unsigned int currentIndex;
-
-        // current key
-        std::string currentKey;
     };
 }
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp
index ee89003517219102eb5be1a276876434fb63630a..1adcdfff3dd6786b6042bec2b20591ad56ff3281 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/NavigatorFactory.cpp
@@ -36,8 +36,7 @@ namespace armarx::aron::datanavigator
     NavigatorPtr NavigatorFactory::create(const data::AronDataPtr& aron, const Path& path) const
     {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-    {data::e##upperType, NavigatorFactoryPtr(new upperType##NavigatorFactory())},
-
+    {data::Descriptor::e##upperType, NavigatorFactoryPtr(new upperType##NavigatorFactory())},
         static const std::map<data::Descriptor, NavigatorFactoryPtr> Factories =
         {
             HANDLE_ALL_ARON_DATA
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp
index 97942372a9c6be2667ff6639c13779fc734e933a..6806d9dd41abe290d246d7a66a036f39a499461a 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.cpp
@@ -94,6 +94,10 @@ namespace armarx::aron::datanavigator
 
     bool NDArrayNavigator::equalsDeep(const NDArrayNavigatorPtr& other) const
     {
+        if (other == nullptr)
+        {
+            return false;
+        }
         return *this == *other;
     }
 
@@ -205,7 +209,7 @@ namespace armarx::aron::datanavigator
         switch (type->getDescriptor())
         {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-case type::e##upperType: \
+case type::Descriptor::e##upperType: \
 { \
     typenavigator::upperType##NavigatorPtr casted = typenavigator::upperType##Navigator::DynamicCast(type); \
     if (std::vector<int>(aron->dimensions.begin(), std::prev(aron->dimensions.end())) != casted->getDimensions() || aron->type != casted->getTypename()) \
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.h b/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.h
index 5e447b102d889f2ba91d95e23a60a89028cf1ff4..c6d12cc6b896a53a8b28cbc2e6c134fae58612f0 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/complex/NDArray.h
@@ -68,31 +68,10 @@ namespace armarx::aron::datanavigator
         /// Return dimensions in a readable string such as "(2, 3, 4)".
         static std::string DimensionsToString(const std::vector<int>& dimensions);
 
-        // TODO(fabian.reister): move this to VectorConverter?
-        template<typename T>
-        static NDArrayNavigatorPtr FromVector(const std::vector<T>& data)
-        {
-            NDArrayNavigatorPtr ndArr(new NDArrayNavigator);
-
-            ndArr->setDimensions({static_cast<int>(data.size()), sizeof(T)});
-            ndArr->setData(data);
-
-            return ndArr;
-        }
-
-
         // public member functions
         unsigned char* getData() const;
         void setData(unsigned int, const unsigned char*);
 
-        // TODO(fabian.reister): move this to VectorConverter?
-        template<typename T>
-        void setData(const std::vector<T>& data)
-        {
-            using E = typename decltype(aron->data)::value_type;
-            setData(sizeof(T) * data.size(), reinterpret_cast < const E* >(data.data()));
-        }
-
         std::vector<int> getDimensions() const;
         void setDimensions(const std::vector<int>&);
         void addDimension(int);
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp
index 90653ddcd7e080510528673ceb24c4c14f70af09..67a2a6d816823611376158d2862c0b5918d6d693 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/container/Dict.cpp
@@ -96,6 +96,10 @@ namespace armarx::aron::datanavigator
 
     bool DictNavigator::equalsDeep(const DictNavigatorPtr& other) const
     {
+        if (other == nullptr)
+        {
+            return false;
+        }
         return *this == *other;
     }
 
@@ -221,7 +225,7 @@ namespace armarx::aron::datanavigator
         type::Descriptor typeDesc = type->getDescriptor();
         switch (typeDesc)
         {
-            case type::eObject:
+            case type::Descriptor::eObject:
             {
                 typenavigator::ObjectNavigatorPtr objectTypeNav = typenavigator::ObjectNavigator::DynamicCast(type);
                 for (const auto& [key, nav] : childrenNavigators)
@@ -233,7 +237,7 @@ namespace armarx::aron::datanavigator
                 }
                 return true;
             }
-            case type::eDict:
+            case type::Descriptor::eDict:
             {
                 typenavigator::DictNavigatorPtr dictTypeNav = typenavigator::DictNavigator::DynamicCast(type);
                 for (const auto& [_, nav] : childrenNavigators)
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp
index 3cce35ea38e9f72e4be92bd185893d7d400909a2..d2d5bee4af83060dad86c93498be761f42a84f80 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/container/List.cpp
@@ -100,6 +100,10 @@ namespace armarx::aron::datanavigator
 
     bool ListNavigator::equalsDeep(const ListNavigatorPtr& other) const
     {
+        if (other == nullptr)
+        {
+            return false;
+        }
         return *this == *other;
     }
 
@@ -212,7 +216,7 @@ namespace armarx::aron::datanavigator
         type::Descriptor typeDesc = type->getDescriptor();
         switch (typeDesc)
         {
-            case type::eList:
+            case type::Descriptor::eList:
             {
                 typenavigator::ListNavigatorPtr listTypeNav = typenavigator::ListNavigator::DynamicCast(type);
                 for (const auto& nav : childrenNavigators)
@@ -224,7 +228,7 @@ namespace armarx::aron::datanavigator
                 }
                 return true;
             }
-            case type::eTuple:
+            case type::Descriptor::eTuple:
             {
                 typenavigator::TupleNavigatorPtr tupleTypeNav = typenavigator::TupleNavigator::DynamicCast(type);
                 unsigned int i = 0;
@@ -237,7 +241,7 @@ namespace armarx::aron::datanavigator
                 }
                 return true;
             }
-            case type::ePair:
+            case type::Descriptor::ePair:
             {
                 typenavigator::PairNavigatorPtr pairTypeNav = typenavigator::PairNavigator::DynamicCast(type);
                 if (childrenSize() != 2)
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.cpp b/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.cpp
index 860b760ce31c864efcdd498c5e2dfa3c2f571c90..23e117fc3f23ed1639faa0b310ba9ddd0f997e24 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.cpp
@@ -50,6 +50,11 @@ namespace armarx::aron::datanavigator
     } \
     \
     /* operators */ \
+    upperType##Navigator::operator lowerType() const \
+    { \
+        return aron->value; \
+    } \
+    \
     bool upperType##Navigator::operator==(const upperType##Navigator& other) const \
     { \
         const auto& otherAron = other.toAron##upperType##Ptr(); \
@@ -71,6 +76,10 @@ namespace armarx::aron::datanavigator
     bool upperType##Navigator::equalsDeep(const upperType##NavigatorPtr& other) const \
     { \
         /* only for consistency. There is no "deep" comparison. */ \
+        if (other == nullptr) \
+        { \
+            return false; \
+        } \
         return *this == *other; \
     } \
     \
diff --git a/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.h b/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.h
index 195ba609dff8b0b4b352a5c0a68ee8db0167e69b..2891a277fd1e2d13f116bce302957bcc6042f746 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.h
+++ b/source/RobotAPI/libraries/aron/core/navigator/data/primitive/Primitive.h
@@ -54,6 +54,7 @@ namespace armarx::aron::datanavigator
         upperType##Navigator(const lowerType&, const Path& = Path()); \
         \
         /* operators */ \
+        operator lowerType() const; \
         bool operator==(const upperType##Navigator&) const; \
         virtual bool equalsDataNavigator(const NavigatorPtr&) const override; \
         bool equalsDeep(const upperType##NavigatorPtr&) const; \
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp
index 48d135200d0590e175128d771706b5d19d3bfa3a..f0375363b95993f9e216d1e140fa459ea99a6913 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/NavigatorFactory.cpp
@@ -35,8 +35,7 @@ namespace armarx::aron::typenavigator
     NavigatorPtr NavigatorFactory::create(const type::AronTypePtr& aron, const Path& path) const
     {
 #define RUN_ARON_MACRO(upperType, lowerType, capsType) \
-    {type::e##upperType, NavigatorFactoryPtr(new upperType##NavigatorFactory())},
-
+    {type::Descriptor::e##upperType, NavigatorFactoryPtr(new upperType##NavigatorFactory())},
         static const std::map<type::Descriptor, NavigatorFactoryPtr> Factories =
         {
             HANDLE_ALL_ARON_TYPES
diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp
index 8f82d1d0776d9b4629f6a75379b56f70661e9531..bc030f335ae8d67ecd9160e949a8943d99196e16 100644
--- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp
+++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp
@@ -24,6 +24,9 @@
 // Header
 #include "Object.h"
 
+// ArmarX
+#include "SimoxUtility/algorithm/get_map_keys_values.h"
+
 
 namespace armarx::aron::typenavigator
 {
@@ -88,6 +91,10 @@ namespace armarx::aron::typenavigator
 
     NavigatorPtr ObjectNavigator::getMemberType(const std::string& s) const
     {
+        if (memberTypes.find(s) == memberTypes.end())
+        {
+            throw error::StringNotValidException("ObjectNavigator", "getMemberType", "Member not set. The list of all members is: " + simox::alg::to_string(simox::alg::get_keys(memberTypes)), s);
+        }
         return memberTypes.at(s);
     }
 
diff --git a/source/RobotAPI/libraries/aron/core/test/aronTest.cpp b/source/RobotAPI/libraries/aron/core/test/aronTest.cpp
index 1210ed0a5d0058825dede94196653f0af3fc201f..e8fd551be59727494f1c92040d81a8bddf1fe8bd 100644
--- a/source/RobotAPI/libraries/aron/core/test/aronTest.cpp
+++ b/source/RobotAPI/libraries/aron/core/test/aronTest.cpp
@@ -154,7 +154,7 @@ void runTestWithInstances(T& k1, T& k2)
     std::string k1_aron_json_str = k1_aron_json.dump(4);
 
     armarx::aron::dataIO::writer::NlohmannJSONWriter direct_json_writer_for_k1;
-    armarx::aron::dataIO::Visitor::SetupWriterFromAronDataPtr(direct_json_writer_for_k1, k1_aron);
+    armarx::aron::dataIO::Visitor::VisitAndSetup(direct_json_writer_for_k1, k1_aron);
     nlohmann::json direct_k1_aron_json = direct_json_writer_for_k1.getResult();
     std::string direct_k1_aron_json_str = direct_k1_aron_json.dump(4);
     BOOST_CHECK_EQUAL((k1_aron_json_str == direct_k1_aron_json_str), true);