diff --git a/Event/EventContainers/EventContainers/IdentifiableContainerBase.h b/Event/EventContainers/EventContainers/IdentifiableContainerBase.h
index b3b1d6d7ab0f0407bbfc7d48e63781f676a225c6..3f355408cbc62e131aeb912ad86ef17660d8a19e 100644
--- a/Event/EventContainers/EventContainers/IdentifiableContainerBase.h
+++ b/Event/EventContainers/EventContainers/IdentifiableContainerBase.h
@@ -10,7 +10,7 @@
 
 
 namespace EventContainers{ class IdentifiableCacheBase; 
-enum class Mode { OfflineLowMemory, OfflineFast };
+enum class Mode { OfflineLowMemory, OfflineFast, OfflineMap };
 class IdentifiableContainerBase{
 public:
 #include "EventContainers/deleter.h"
diff --git a/Event/EventContainers/EventContainers/IdentifiableContainerMT.h b/Event/EventContainers/EventContainers/IdentifiableContainerMT.h
index 8791b57b881f699fa51b2edad021676cc006f323..a4ccd3517c288730d5e0f7d2e98759584b441606 100644
--- a/Event/EventContainers/EventContainers/IdentifiableContainerMT.h
+++ b/Event/EventContainers/EventContainers/IdentifiableContainerMT.h
@@ -208,6 +208,8 @@ public:
         return m_link->fullSize();
     }    
 
+    void prepareItr() const { m_link->wait(); }
+
     /// return number of collections
     virtual size_t numberOfCollections() const override final{
         return IdentifiableContainerBase::numberOfCollections();
diff --git a/Event/EventContainers/EventContainers/InternalOfflineMap.h b/Event/EventContainers/EventContainers/InternalOfflineMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..c69d08186f736b57129ae7294293f1681ad6aef7
--- /dev/null
+++ b/Event/EventContainers/EventContainers/InternalOfflineMap.h
@@ -0,0 +1,51 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef EVENTCONTAINERS_InternalOfflineMap_H
+#define EVENTCONTAINERS_InternalOfflineMap_H
+#include "EventContainers/I_InternalIDC.h"
+#include "CxxUtils/checker_macros.h"
+#include <atomic>
+#include <mutex>
+#include <unordered_map>
+
+namespace EventContainers{
+/*
+This class implements the IdentifiableContainer code for the offline case.
+This class balances speed against memory usage by using an unordered_map
+
+Moderately fast random access, fast iteration, moderate memory usage.
+*/
+class InternalOfflineMap final : public I_InternalIDC {
+public:
+    InternalOfflineMap(size_t max);
+    virtual ~InternalOfflineMap()=default;
+    virtual InternalConstItr cbegin() const override;
+    virtual InternalConstItr cend() const override;
+    virtual InternalConstItr indexFind( IdentifierHash hashId ) const override;
+    virtual const std::vector < hashPair >& getAllHashPtrPair() const override;
+    mutable std::vector<std::pair<IdentifierHash::value_type, const void*>> m_map;
+    std::unordered_map<IdentifierHash::value_type, const void*> m_fullMap;
+    mutable std::mutex m_waitMutex ATLAS_THREAD_SAFE;
+    mutable std::atomic<bool> m_needsupdate ATLAS_THREAD_SAFE; //These mutables are carefully thought out, do not change
+    virtual bool tryAddFromCache(IdentifierHash hashId, EventContainers::IDC_WriteHandleBase &lock) override;
+    virtual bool tryAddFromCache(IdentifierHash hashId) override;
+    virtual void wait() const override;
+    virtual std::vector<IdentifierHash> getAllCurrentHashes() const override;
+    virtual size_t numberOfCollections() const override;
+    virtual void cleanUp(deleter_f* deleter) noexcept override;
+    virtual size_t fullSize() const noexcept override {return m_maxsize;}
+    virtual StatusCode fetchOrCreate(IdentifierHash hashId) override;
+    virtual StatusCode fetchOrCreate(const std::vector<IdentifierHash> &hashIds) override;
+    virtual bool insert(IdentifierHash hashId, const void* ptr) override;
+    virtual const void* findIndexPtr(IdentifierHash hashId) const noexcept override;
+    virtual StatusCode addLock(IdentifierHash hashId, const void* ptr) override;
+    virtual void* removeCollection( IdentifierHash hashId ) override;
+    virtual void destructor(deleter_f*) noexcept override;
+private:
+    const size_t m_maxsize;
+};
+
+}
+#endif
diff --git a/Event/EventContainers/src/IdentifiableContainerBase.cxx b/Event/EventContainers/src/IdentifiableContainerBase.cxx
index 3c6fdcc09acb4f510c297fd022165761455de6c5..7ed316fa3350416a173c3ed27606ededa51a11f5 100644
--- a/Event/EventContainers/src/IdentifiableContainerBase.cxx
+++ b/Event/EventContainers/src/IdentifiableContainerBase.cxx
@@ -8,6 +8,7 @@
 #include "EventContainers/InternalOnline.h"
 #include "EventContainers/InternalOffline.h"
 #include "EventContainers/InternalOfflineFast.h"
+#include "EventContainers/InternalOfflineMap.h"
 
 using namespace EventContainers;
 
@@ -27,6 +28,7 @@ using namespace EventContainers;
     m_OnlineMode = false;
     if(mode == Mode::OfflineLowMemory) m_link = std::make_unique<EventContainers::InternalOffline>(max);
     else if(mode == Mode::OfflineFast) m_link = std::make_unique<EventContainers::InternalOfflineFast>(max);
+    else if(mode == Mode::OfflineMap)  m_link = std::make_unique<EventContainers::InternalOfflineMap>(max);
     else{
       throw std::runtime_error("Invalid Mode specified");
     }
diff --git a/Event/EventContainers/src/InternalOfflineMap.cxx b/Event/EventContainers/src/InternalOfflineMap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f60ec109d92dccf3235c90a5b6a02c942c633881
--- /dev/null
+++ b/Event/EventContainers/src/InternalOfflineMap.cxx
@@ -0,0 +1,135 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "EventContainers/InternalOfflineMap.h"
+#include <algorithm>
+#include "EventContainers/IDC_WriteHandleBase.h"
+
+using namespace EventContainers;
+typedef I_InternalIDC::InternalConstItr InternalConstItr;
+InternalOfflineMap::InternalOfflineMap(size_t max) : m_needsupdate(false), m_maxsize(max) {}
+
+
+bool InternalOfflineMap::tryAddFromCache(IdentifierHash hash, EventContainers::IDC_WriteHandleBase&) {
+    return m_fullMap.count(hash);
+}
+
+bool InternalOfflineMap::tryAddFromCache(IdentifierHash hash)
+{
+    return m_fullMap.count(hash);
+}
+
+void InternalOfflineMap::wait() const {
+   std::lock_guard lock (m_waitMutex);
+   if(m_needsupdate == false) return;
+   m_map.clear();
+   m_map.reserve(m_fullMap.size());
+   for(const auto &pair : m_fullMap){
+     m_map.emplace_back(pair.first, pair.second);
+   }
+   std::sort(m_map.begin(), m_map.end());
+   m_needsupdate.store(false);
+}
+
+std::vector<IdentifierHash> InternalOfflineMap::getAllCurrentHashes() const {
+    std::vector<IdentifierHash> ids;
+    ids.reserve(m_fullMap.size());
+    if(m_needsupdate == true){
+       for(const auto &pair : m_fullMap){
+         ids.emplace_back(pair.first);
+       }
+       std::sort(ids.begin(), ids.end());
+    }else{
+       for(const auto &pair : m_map){
+          ids.emplace_back(pair.first);
+       }
+    }
+    return ids;
+}
+
+InternalConstItr
+ InternalOfflineMap::cend() const {
+    if(m_needsupdate) wait();
+    return m_map.cend();
+}
+
+const std::vector < I_InternalIDC::hashPair >& InternalOfflineMap::getAllHashPtrPair() const{
+    if(m_needsupdate) wait();
+    return m_map;
+}
+
+InternalConstItr
+ InternalOfflineMap::cbegin() const {
+    if(m_needsupdate) wait();
+    return m_map.cbegin();
+}
+
+InternalConstItr InternalOfflineMap::indexFind( IdentifierHash hashId ) const{
+   if(m_needsupdate) wait();
+   auto itr = std::lower_bound( m_map.cbegin(), m_map.cend(), hashId.value(), [](const hashPair &lhs,  IdentifierHash::value_type rhs) -> bool { return lhs.first < rhs; } );
+   if(itr!= m_map.cend() && itr->first==hashId) return itr;
+   return m_map.cend();
+}
+
+size_t InternalOfflineMap::numberOfCollections() const {
+    return m_fullMap.size();
+}
+
+void InternalOfflineMap::cleanUp(deleter_f* deleter) noexcept {
+    destructor(deleter);
+    m_map.clear();
+    m_fullMap.clear();
+    m_needsupdate.store(false, std::memory_order_relaxed);
+}
+
+bool InternalOfflineMap::insert(IdentifierHash hashId, const void* ptr) {
+    if(hashId >= m_maxsize) return false;
+    auto &mapptr = m_fullMap[hashId];
+    if(mapptr!=nullptr) return false; //already present
+    mapptr = ptr;
+    m_needsupdate.store(true, std::memory_order_relaxed);
+    return true;
+}
+
+const void* InternalOfflineMap::findIndexPtr(IdentifierHash hashId) const noexcept{
+    if(hashId >= m_maxsize) return nullptr;
+    auto search = m_fullMap.find(hashId);
+    if(search!=m_fullMap.cend()) return search->second;
+    return nullptr;
+}
+
+StatusCode InternalOfflineMap::addLock(IdentifierHash hashId, const void* ptr) {
+    bool added = insert(hashId, ptr);
+    if(!added) {
+#ifndef NDEBUG
+        std::cout << "IDC WARNING Deletion shouldn't occur in addLock paradigm" << std::endl;
+#endif
+        return StatusCode::FAILURE;
+    }
+    return StatusCode::SUCCESS;
+}
+
+void* InternalOfflineMap::removeCollection( IdentifierHash hashId ) {
+   auto search = m_fullMap.find(hashId);
+   if(search==m_fullMap.cend()) return nullptr;
+   void* ptr = const_cast< void* > (search->second);
+   m_fullMap.erase(search);
+   m_needsupdate.store(true, std::memory_order_relaxed);
+   return ptr;
+}
+
+StatusCode InternalOfflineMap::fetchOrCreate(IdentifierHash) {
+    throw std::runtime_error("Not implemented in offline mode");
+}
+StatusCode InternalOfflineMap::fetchOrCreate(const std::vector<IdentifierHash>&)
+{
+    throw std::runtime_error("Not implemented in offline mode");
+}
+
+void InternalOfflineMap::destructor(deleter_f* deleter) noexcept {
+    if(!m_needsupdate) for(const auto& x : m_map)  deleter(x.second);
+    else {
+      for(const auto &pair : m_fullMap) {  deleter(pair.second);  }
+    }
+}
diff --git a/Event/EventContainers/test/IDC_Benchmark.cxx b/Event/EventContainers/test/IDC_Benchmark.cxx
index 6e7b9bfddfe43d1ea168e9398288d63c969ee498..85c66d3dc51fcdf00d1de43f8f49bd95dbfe916b 100644
--- a/Event/EventContainers/test/IDC_Benchmark.cxx
+++ b/Event/EventContainers/test/IDC_Benchmark.cxx
@@ -30,6 +30,12 @@ void timebackwardsfill(std::string name, IdentifiableContainerMT<long unsigned i
 
 void accessTime(std::string name, IdentifiableContainerMT<long unsigned int>& container){
 
+   auto startwait  = std::chrono::steady_clock::now();
+   container.prepareItr();
+   auto endwait = std::chrono::steady_clock::now();
+   std::chrono::duration<double> offlinewait = endwait-startwait;
+   std::cout << name << " wait time " << offlinewait.count() << std::endl;
+
    auto start3 = std::chrono::steady_clock::now();
    auto offlinecnt = container.GetAllCurrentHashes();
    for(auto hash : offlinecnt) if(hash !=  *container.indexFindPtr(hash) ) std::abort();
@@ -81,25 +87,40 @@ int main(){
    auto end3 = std::chrono::steady_clock::now();
    std::chrono::duration<double> offlinefillfast = end3-start3;
    std::cout << "offlinefast fill time " << offlinefillfast.count() << std::endl;
+
+   auto start4 = std::chrono::steady_clock::now();
+   auto offlinemap = new IdentifiableContainerMT<long unsigned int>(50000, EventContainers::Mode::OfflineMap);
+   for(size_t i =3;i<50000;i+=3){
+      offlinemap->addCollection(new long unsigned int(i) ,i).ignore();
+   }
+   auto end4 = std::chrono::steady_clock::now();   
+   std::chrono::duration<double> offlinefillmap = end4-start4;
+   std::cout << "offlinemap fill time " << offlinefillmap.count() << std::endl;
+
    accessTime("online ", *online);
    accessTime("offline ", *offline);
    accessTime("offlinefast ", *offlinefast);
+   accessTime("offlinemap ", *offlinemap);
    timedelete("onlineCont ", online);
    timedelete("onlineCache ", cache);
    timedelete("offline ", offline);
    timedelete("offlinefast ", offlinefast);
+   timedelete("offlinemap ", offlinemap);
 
    auto offlinefast2 = new IdentifiableContainerMT<long unsigned int>(50000, EventContainers::Mode::OfflineFast);
    auto cache2  = new IdentifiableCache<long unsigned int>(50000, nullptr);
    auto online2 = new IdentifiableContainerMT<long unsigned int>(cache2);
    auto offline2 = new IdentifiableContainerMT<long unsigned int>(50000);
+   auto offlinemap2 = new IdentifiableContainerMT<long unsigned int>(50000, EventContainers::Mode::OfflineMap);
    timebackwardsfill("offlinefast", offlinefast2);
+   timebackwardsfill("offlinemap", offlinemap2);
    timebackwardsfill("offline", offline2);
    timebackwardsfill("online", online2);
    delete offline2;
    delete online2;
    delete cache2;
    delete offlinefast2;
+   delete offlinemap2;
    std::cout << "Test Successful" << std::endl;
    return 0;
 }