diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 1becb6eb9017d691dc72a5372b78e87e4d76e589..a5274706c4f359b45f1e8d7fb925b66479865625 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -37,6 +37,7 @@ set(LIB_FILES
     core/base/detail/EntityContainerBase.cpp
     core/base/detail/AronTyped.cpp
     core/base/detail/iteration_mixins.cpp
+    core/base/detail/negative_index_semantics.cpp
 
     # core/base/CoreSegmentBase.cpp
     core/base/EntityBase.cpp
@@ -156,6 +157,7 @@ set(LIB_HEADERS
     core/base/detail/EntityContainerBase.h
     core/base/detail/AronTyped.h
     core/base/detail/iteration_mixins.h
+    core/base/detail/negative_index_semantics.h
 
     core/base/CoreSegmentBase.h
     core/base/EntityBase.h
diff --git a/source/RobotAPI/libraries/armem/core/base/EntityBase.h b/source/RobotAPI/libraries/armem/core/base/EntityBase.h
index b3e3f7424657f3f6731e0fd35a01424ae65acdfc..f28f12b7be82e7c594c9306f6fa5e24b5decdd42 100644
--- a/source/RobotAPI/libraries/armem/core/base/EntityBase.h
+++ b/source/RobotAPI/libraries/armem/core/base/EntityBase.h
@@ -184,17 +184,6 @@ namespace armarx::armem::base
             return getLatestItem().second;
         }
 
-        /**
-         * @brief Return the lastest snapshot before or at time.
-         * @param time The time.
-         * @return The latest snapshot.
-         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
-         * @throw `armem::error::MissingEntry` If no such snapshot
-         */
-        const EntitySnapshotT& getLatestSnapshotBeforeOrAt(const Time& time) const
-        {
-            return getLatestSnapshotBefore(time + Time::microSeconds(1));
-        }
 
         /**
          * @brief Return the lastest snapshot before time.
@@ -231,37 +220,17 @@ namespace armarx::armem::base
         }
 
         /**
-         * @brief Return all snapshots before (excluding) time.
-         * @param time The time.
-         * @return The latest snapshots.
-         */
-        std::vector<std::reference_wrapper<const EntitySnapshotT>>
-                getSnapshotsBefore(const Time& time) const
-        {
-            std::vector<std::reference_wrapper<const EntitySnapshotT>> ret;
-            for (const auto& [timestamp, snapshot] : this->_container)
-            {
-                if (timestamp >= time)
-                {
-                    break;
-                }
-                ret.emplace_back(snapshot);
-            }
-            return ret;
-        }
-
-        /**
-         * @brief Return all snapshots before or at time.
+         * @brief Return the lastest snapshot before or at time.
          * @param time The time.
-         * @return The latest snapshots.
+         * @return The latest snapshot.
+         * @throw `armem::error::EntityHistoryEmpty` If the history is empty.
+         * @throw `armem::error::MissingEntry` If no such snapshot
          */
-        std::vector<std::reference_wrapper<const EntitySnapshotT>>
-                getSnapshotsBeforeOrAt(const Time& time) const
+        const EntitySnapshotT& getLatestSnapshotBeforeOrAt(const Time& time) const
         {
-            return getSnapshotsBefore(time + Time::microSeconds(1));
+            return getLatestSnapshotBefore(time + Time::microSeconds(1));
         }
 
-
         /**
          * @brief Return first snapshot after or at time.
          * @param time The time.
@@ -316,6 +285,94 @@ namespace armarx::armem::base
         // forEachEntityInstance() is provided by ForEachEntityInstanceMixin.
 
 
+        /**
+         * @brief Return all snapshots before (excluding) time.
+         * @param time The time.
+         * @return The latest snapshots.
+         */
+        template <class FunctionT>
+        void forEachSnapshotBefore(const Time& time, FunctionT&& func) const
+        {
+            for (const auto& [timestamp, snapshot] : this->_container)
+            {
+                if (timestamp >= time)
+                {
+                    break;
+                }
+                if (not func(snapshot))
+                {
+                    break;
+                }
+            }
+        }
+
+        /**
+         * @brief Return all snapshots before or at time.
+         * @param time The time.
+         * @return The latest snapshots.
+         */
+        template <class FunctionT>
+        void forEachSnapshotBeforeOrAt(const Time& time, FunctionT&& func) const
+        {
+            getSnapshotsBefore(time + Time::microSeconds(1), func);
+        }
+
+
+        /**
+         * @brief Return all snapshots between, including, min and max.
+         * @param min The lowest time to include.
+         * @param min The highest time to include.
+         * @return The snapshots in [min, max].
+         */
+        template <class FunctionT>
+        void forEachSnapshotInTimeRange(const Time& min, const Time& max, FunctionT&& func) const
+        {
+            // 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 ? this->_container.lower_bound(min) : this->_container.begin();
+            // Returns an iterator pointing to the first element that is *greater than* key.
+            auto end = max.toMicroSeconds() > 0 ? this->_container.upper_bound(max) : this->_container.end();
+
+            for (auto it = begin; it != end && it != this->_container.end(); ++it)
+            {
+                func(it->second);
+            }
+        }
+
+        /**
+         * @brief Return all snapshots from first to last index.
+         *
+         * Negative index are counted from the end, e.g.
+         * last == -1 results in getting all queries until the end.
+         *
+         * @param first The first index to include.
+         * @param first The last index to include.
+         * @return The snapshots in [first, last].
+         */
+        template <class FunctionT>
+        void forEachSnapshotInIndexRange(long first, long last, FunctionT&& func) const
+        {
+            if (this->empty())
+            {
+                return;
+            }
+
+            const size_t first_ = detail::negativeIndexSemantics(first, this->size());
+            const size_t last_ = detail::negativeIndexSemantics(last, this->size());
+
+            if (first_ <= last_)
+            {
+                auto it = this->_container.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)
+                {
+                    func(it->second);
+                }
+            }
+        }
+
+
         [[deprecated("Direct container access is deprecated. Use forEach*() instead.")]]
         inline const ContainerT& history() const
         {
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.cpp b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.cpp
index 857ca6220294c2faea84e84953af250faa46973e..459cd4d5c7bd694bcb289496352d7e2cad4966cd 100644
--- a/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.cpp
+++ b/source/RobotAPI/libraries/armem/core/base/detail/iteration_mixins.cpp
@@ -1,4 +1,5 @@
-#include "AronTyped.h"
+#include "iteration_mixins.h"
+
 
 namespace armarx::armem::base::detail
 {
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.cpp b/source/RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a1875ff53545a3d2574cf9764a14d321946e5514
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.cpp
@@ -0,0 +1,17 @@
+#include "negative_index_semantics.h"
+
+#include <algorithm>
+
+
+size_t armarx::armem::base::detail::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)));
+    }
+}
diff --git a/source/RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.h b/source/RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.h
new file mode 100644
index 0000000000000000000000000000000000000000..4efe169276c83ff12c13400e6de162a8b4db5d8d
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/core/base/detail/negative_index_semantics.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <stddef.h>
+
+
+namespace armarx::armem::base::detail
+{
+
+    size_t negativeIndexSemantics(long index, size_t size);
+
+}
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
index 009683a32779d5e6728c1c86387ab0631c9193b2..644ec02282fa46f96e0d643d56094ad59b56eadf 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/EntityQueryProcessorBase.h
@@ -148,25 +148,12 @@ namespace armarx::armem::base::query_proc
                      const armem::query::data::entity::IndexRange& query,
                      const _EntityT& entity) const
         {
-            if (entity.empty())
+            entity.forEachSnapshotInIndexRange(
+                query.first, query.last,
+                [this, &result](const EntitySnapshotT & snapshot)
             {
-                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);
-                }
-            }
+                addResultSnapshot(result, snapshot);
+            });
         }
 
         void process(_EntityT& result,
@@ -176,16 +163,12 @@ namespace armarx::armem::base::query_proc
                      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)
+            entity.forEachSnapshotInTimeRange(
+                min, max,
+                [this, &result](const EntitySnapshotT & snapshot)
             {
-                addResultSnapshot(result, it);
-            }
+                addResultSnapshot(result, snapshot);
+            });
         }
 
 
@@ -213,11 +196,18 @@ namespace armarx::armem::base::query_proc
                      const _EntityT& entity) const
         {
             const armem::Time referenceTimestamp = fromIce<Time>(query.timestamp);
-            ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp is negative!";
+            ARMARX_CHECK(referenceTimestamp.toMicroSeconds() >= 0) << "Reference timestamp must be non-negative.";
 
+#if 0
             try
             {
-                const auto& befores = entity.getSnapshotsBefore(referenceTimestamp);
+#endif
+                std::vector<const EntitySnapshotT*> befores;
+                entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s)
+                {
+                    befores.push_back(&s);
+                    return true;
+                });
 
                 size_t num = 0;
                 if (query.maxEntries < 0)
@@ -232,13 +222,15 @@ namespace armarx::armem::base::query_proc
                 for (size_t r = 0; r < num; ++r)
                 {
                     size_t i = befores.size() - 1 - r;
-                    addResultSnapshot(result, befores[i]);
+                    addResultSnapshot(result, *befores[i]);
                 }
+#if 0
             }
             catch (const  error::MissingEntry&)
             {
                 // Leave empty.
             }
+#endif
         }
 
         void process(_EntityT& result,
@@ -293,18 +285,6 @@ namespace armarx::armem::base::query_proc
             }
         }
 
-        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;
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
index 55c5e51126b49775db7317d6401aa695c4b5581c..66c2a8042b740ec72c6be3ca653f6ed72fc8c35b 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h
@@ -65,10 +65,11 @@ namespace armarx::armem::base::query_proc
                      const armem::query::data::memory::All& query,
                      const _MemoryT& memory) const
         {
-            for (const auto& [name, coreSegment] : memory.coreSegments())
+            memory.forEachCoreSegment([this, &result, &query](const CoreSegmentT & coreSegment)
             {
                 result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
-            }
+                return true;
+            });
         }
 
         void process(_MemoryT& result,
@@ -89,14 +90,15 @@ namespace armarx::armem::base::query_proc
                      const armem::query::data::memory::Regex& query,
                      const _MemoryT& memory) const
         {
-            std::regex regex(query.coreSegmentNameRegex);
-            for (const auto& [name, coreSegment] : memory.coreSegments())
+            const std::regex regex(query.coreSegmentNameRegex);
+            memory.forEachCoreSegment([this, &result, &query, &regex](const CoreSegmentT & coreSegment)
             {
                 if (std::regex_search(coreSegment.name(), regex))
                 {
                     result.addCoreSegment(coreSegmentProcessorProcess(query.coreSegmentQueries, coreSegment));
                 }
-            }
+                return true;
+            });
         }
 
     protected:
diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
index b3b7da7ffa9cc1d06aeadabef58c5aebba3974de..cb191d02edeaaa471290d5bf67475a5950572213 100644
--- a/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
+++ b/source/RobotAPI/libraries/armem/server/query_proc/base/ProviderSegmentQueryProcessorBase.h
@@ -57,10 +57,11 @@ namespace armarx::armem::base::query_proc
                      const armem::query::data::provider::All& query,
                      const _ProviderSegmentT& providerSegment) const
         {
-            for (const auto& [name, entity] : providerSegment.entities())
+            providerSegment.forEachEntity([this, &result, &query](const EntityT & entity)
             {
                 result.addEntity(entityProcessorProcess(query.entityQueries, entity));
-            }
+                return true;
+            });
         }
 
         void process(_ProviderSegmentT& result,
@@ -82,14 +83,15 @@ namespace armarx::armem::base::query_proc
                      const armem::query::data::provider::Regex& query,
                      const _ProviderSegmentT& providerSegment) const
         {
-            std::regex regex(query.entityNameRegex);
-            for (const auto& [name, entity] : providerSegment.entities())
+            const std::regex regex(query.entityNameRegex);
+            providerSegment.forEachEntity([this, &result, &query, &regex](const EntityT & entity)
             {
                 if (std::regex_search(entity.name(), regex))
                 {
                     result.addEntity(entityProcessorProcess(query.entityQueries, entity));
                 }
-            }
+                return true;
+            });
         }
 
     protected: