diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCTRawDataProviderTool.h b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCTRawDataProviderTool.h
index 42cbe06792de5f1a18996d53abf6148ab14eba0d..b54dcd33195103ef66525b1061e713f42328fe47 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCTRawDataProviderTool.h
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCTRawDataProviderTool.h
@@ -38,7 +38,7 @@ class ISCTRawDataProviderTool : virtual public IAlgTool
 
   /** Main decoding methods */
   virtual StatusCode convert(std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>&,
-                             ISCT_RDO_Container&,
+                             SCT_RDO_Container&,
                              IDCInDetBSErrContainer& errs) const = 0;
 
 };
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCT_RodDecoder.h b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCT_RodDecoder.h
index 442c07060ddaa7d2ade164447da08f38f13eea63..4493f052e7c5d379520dcc49dbffba2ffa61bf4b 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCT_RodDecoder.h
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/SCT_RawDataByteStreamCnv/ISCT_RodDecoder.h
@@ -35,7 +35,7 @@ class ISCT_RodDecoder : virtual public IAlgTool
 
   /** Fill Collection method */
   virtual StatusCode fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment&,
-                                    ISCT_RDO_Container&,
+                                    SCT_RDO_Container&,
                                     IDCInDetBSErrContainer& errs,
                                     const std::vector<IdentifierHash>* vecHash = nullptr) const = 0;
 };
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProvider.cxx b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProvider.cxx
index 5d84f189a375a88f3bf2047515d775c9e77e73fd..eafdb926726a9a57213312a0f0929f0da6e3c382 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProvider.cxx
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProvider.cxx
@@ -57,8 +57,6 @@ StatusCode SCTRawDataProvider::initialize()
   return StatusCode::SUCCESS;
 }
 
-typedef EventContainers::IdentifiableContTemp<InDetRawDataCollection<SCT_RDORawData>> dummySCTRDO_t;
-
 // Execute
 
 StatusCode SCTRawDataProvider::execute(const EventContext& ctx) const
@@ -139,19 +137,10 @@ StatusCode SCTRawDataProvider::execute(const EventContext& ctx) const
     ATH_MSG_DEBUG("Stored LVL1ID " << lvl1ID << " and BCID " << bcID << " in InDetTimeCollections");
   }
 
-  std::unique_ptr<dummySCTRDO_t> dummyRDO;
-  ISCT_RDO_Container *rdoInterface{nullptr};
-  if (externalCacheRDO) {
-    dummyRDO = std::make_unique<dummySCTRDO_t>(rdoContainer.ptr());
-    rdoInterface = static_cast< ISCT_RDO_Container*> (dummyRDO.get());
-  }
-  else {
-    rdoInterface = static_cast<ISCT_RDO_Container* >(rdoContainer.ptr());
-  }
   if ( not hashIDs.empty() ) {
     int missingCount{};
     for ( IdentifierHash hash: hashIDs ) {
-      if ( not rdoInterface->tryAddFromCache( hash ) ) missingCount++;
+      if ( not rdoContainer->tryAddFromCache( hash ) ) missingCount++;
       bsIDCErrContainer->tryAddFromCache( hash );
     }
     ATH_MSG_DEBUG("Out of: " << hashIDs.size() << "Hash IDs missing: " << missingCount );
@@ -162,11 +151,10 @@ StatusCode SCTRawDataProvider::execute(const EventContext& ctx) const
 
   // Ask SCTRawDataProviderTool to decode it and to fill the IDC
   if (m_rawDataTool->convert(vecROBFrags,
-                             *rdoInterface,
+                             *(rdoContainer.ptr()),
 			     *bsIDCErrContainer).isFailure()) {
     ATH_MSG_WARNING("BS conversion into RDOs failed");
   }
 
-  if (dummyRDO) ATH_CHECK(dummyRDO->MergeToRealContainer(rdoContainer.ptr()));
   return StatusCode::SUCCESS;
 }
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.cxx b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.cxx
index 43228e7102ae6739bb1438b9b2841d5cebbefb84..72d70a4b86533a6701cf28098504de81f850c574 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.cxx
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.cxx
@@ -27,7 +27,7 @@ StatusCode SCTRawDataProviderTool::initialize()
 
 // Convert method
 StatusCode SCTRawDataProviderTool::convert(std::vector<const ROBFragment*>& vecROBFrags,
-                                           ISCT_RDO_Container& rdoIDCont,
+                                           SCT_RDO_Container& rdoIDCont,
                                            IDCInDetBSErrContainer& errs) const
 {
   if (vecROBFrags.empty()) return StatusCode::SUCCESS;
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.h b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.h
index d52f6ed9cb452a879e5acec6211f60c4283bf498..6af06ee63f8c0bd9b0f8758cbb03eba36c0d442f 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.h
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCTRawDataProviderTool.h
@@ -50,7 +50,7 @@ class SCTRawDataProviderTool : public extends<AthAlgTool, ISCTRawDataProviderToo
    * @param ctx EventContext of the event
    *  */
   virtual StatusCode convert(std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vecROBFrags,
-                             ISCT_RDO_Container& rdoIDCont,
+                             SCT_RDO_Container& rdoIDCont,
                              IDCInDetBSErrContainer& errs) const override;
 
  private: 
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx
index ae5ab86e7e31f90a4f29cbc1b65a4318a212c2fc..729c6a24af1e140270668eb04f54396bd183fedf 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx
@@ -5,11 +5,9 @@
 #include "SCT_RodDecoder.h"
 
 #include "ByteStreamData/RawEvent.h"
-#include "InDetIdentifier/SCT_ID.h"
-#include "SCT_ReadoutGeometry/SCT_DetectorManager.h"
 #include "InDetReadoutGeometry/SiDetectorElement.h"
 #include "InDetReadoutGeometry/SiDetectorElementCollection.h"
-#include "SCT_ConditionsTools/ISCT_ByteStreamErrorsTool.h"
+#include "SCT_ReadoutGeometry/SCT_DetectorManager.h"
 
 #include "Identifier/IdentifierHash.h"
 
@@ -165,38 +163,9 @@ StatusCode SCT_RodDecoder::finalize()
 }
 
 
-/**
- * @brief allows to accumulate errors in one fillColection call
- *
- * Errors information is scattered across this code.
- * To be sure that all of the errors are saved this helper class provides add method allowing to update/accumulate erorr.
- * The IDC, for a very good reasons (MT safety) do not allow for that.
- **/
-class SCT_RodDecoderErrorsHelper {
-public:
-  SCT_RodDecoderErrorsHelper(IDCInDetBSErrContainer& idcContainer)
-    : errorsIDC{ idcContainer } {}
-  ~SCT_RodDecoderErrorsHelper() {
-    for (auto [id, err]: accumulatedErrors) {
-      errorsIDC.setOrDrop(id, err);
-    }
-  }
-  void noerror(const IdentifierHash id) {
-    accumulatedErrors[id]; // this adds 0 (no error) for an ID
-  }
-
-  void add(const IdentifierHash id, SCT_ByteStreamErrors::ErrorType etype) {
-    SCT_ByteStreamErrors::addError(accumulatedErrors[id], etype);
-  }
-
-  std::map<IdentifierHash, IDCInDetBSErrContainer::ErrorCode> accumulatedErrors;
-  IDCInDetBSErrContainer& errorsIDC;
-};
-
-
 // fillCollection method
 StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment& robFrag,
-                                          ISCT_RDO_Container& rdoIDCont,
+                                          SCT_RDO_Container& rdoIDCont,
                                           IDCInDetBSErrContainer& errorsIDC,
                                           const std::vector<IdentifierHash>* vecHash) const
 {
@@ -342,7 +311,7 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB
 
   // Create the last RDO of the last link of the event
   if (not data.isSaved(false) and data.oldStrip>=0) {
-    const int rdoMade{makeRDO(false, data, rdoIDCont, cache, errs)};
+    const int rdoMade{makeRDO(false, data, cache)};
     if (rdoMade == -1) {
       sc = StatusCode::RECOVERABLE;
       ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -358,6 +327,18 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB
     ATH_CHECK(addRODError(robID, SCT_ByteStreamErrors::MissingLinkHeaderError, errs, &(data.foundHashes)));
   }
 
+  for (auto& [hash, rdoColl] : data.rdoCollMap) {
+    if (rdoColl==nullptr) continue; // nullptr means the collection is already filled.
+
+    if (rdoColl->empty()) { // Empty collection is not filled.
+      rdoColl.reset();
+      errs.removeIfEmpty(hash); // To get the same result as before. Not sure whether we need this.
+      continue;
+    }
+
+    ATH_CHECK(data.writeHandleMap[hash].addOrDelete(std::move(rdoColl)));
+  }
+
   if (sc.isFailure()) ATH_MSG_DEBUG("One or more ByteStream errors found ");
   return sc;
 }
@@ -365,11 +346,13 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB
 // makeRDO method
 
 int SCT_RodDecoder::makeRDO(const bool isOld,
-                            const SharedData& data,
-                            ISCT_RDO_Container& rdoIDCont,
-                            CacheHelper& cache,
-                            SCT_RodDecoderErrorsHelper& errs) const
+                            SharedData& data,
+                            CacheHelper& cache) const
 {
+  // If the link is already decoded, RDO will not be created.
+  SCT_RDO_Collection* rdoColl{data.rdoCollMap[data.linkIDHash].get()};
+  if (rdoColl==nullptr) return 0;
+
   int strip{isOld ? data.oldStrip : data.strip};
   if (((strip & 0x7F) + (data.groupSize-1) >= N_STRIPS_PER_CHIP) or (strip<0) or (strip>=N_STRIPS_PER_SIDE)) {
     ATH_MSG_WARNING("Cluster with " << data.groupSize << " strips, starting at strip " << strip
@@ -398,11 +381,6 @@ int SCT_RodDecoder::makeRDO(const bool isOld,
     }
   }
 
-  if (rdoIDCont.hasExternalCache() and rdoIDCont.tryAddFromCache(data.linkIDHash)) {
-    ATH_MSG_DEBUG("Hash already in collection - cache hit " << data.linkIDHash);
-    return 0;
-  }
-
   // See if strips go from 0 to N_STRIPS_PER_SIDE-1(=767) or vice versa
   if (m_swapPhiReadoutDirection[data.linkIDHash]) {
     strip = N_STRIPS_PER_SIDE-1 - strip;
@@ -410,8 +388,7 @@ int SCT_RodDecoder::makeRDO(const bool isOld,
   }
 
   // Get identifier from the hash, this is not nice
-  const Identifier collID{m_sctID->wafer_id(data.linkIDHash)};
-  const Identifier digitID{m_sctID->strip_id(collID, strip)};
+  const Identifier digitID{m_sctID->strip_id(data.collID, strip)};
   if (not m_sctID->is_sct(digitID)) {
     ATH_MSG_WARNING("Cluster with invalid Identifier. Will not make RDO");
     return -1;
@@ -419,28 +396,12 @@ int SCT_RodDecoder::makeRDO(const bool isOld,
 
   const unsigned int rawDataWord{static_cast<unsigned int>(data.groupSize | (strip << 11) | (data.timeBin <<22) | (data.errors << 25))};
 
-  ATH_MSG_DEBUG("Output Raw Data " << std::hex << " Coll " << collID.getString()
+  ATH_MSG_DEBUG("Output Raw Data " << std::hex << " Coll " << data.collID.getString()
                 << ":-> " << m_sctID->print_to_string(digitID) << std::dec);
 
-  SCT_RDO_Collection* sctRDOColl{nullptr};
-  ATH_CHECK(rdoIDCont.naughtyRetrieve(data.linkIDHash, sctRDOColl), 0); // Returns null if not present
-
-  if (sctRDOColl==nullptr) {
-    ATH_MSG_DEBUG(" Collection ID = " << data.linkIDHash << " does not exist, create it ");
-    // Create new collection
-    sctRDOColl = new SCT_RDO_Collection(data.linkIDHash);
-    errs.noerror(data.linkIDHash); // make sure the error information is filled for this ID
-    sctRDOColl->setIdentifier(collID);
-    StatusCode sc{rdoIDCont.addCollection(sctRDOColl, data.linkIDHash)};
-    ATH_MSG_DEBUG("Adding " << data.linkIDHash);
-    if (sc.isFailure()){
-      ATH_MSG_ERROR("failed to add SCT RDO collection to container");
-    }
-  }
-
   // Now the Collection is there for sure. Create RDO and push it into Collection.
   m_nRDOs++;
-  sctRDOColl->push_back(std::make_unique<SCT3_RawData>(digitID, rawDataWord, &(data.errorHit)));
+  rdoColl->push_back(std::make_unique<SCT3_RawData>(digitID, rawDataWord, &(data.errorHit)));
   return 1;
 }
 
@@ -665,7 +626,7 @@ StatusCode SCT_RodDecoder::setFirstTempMaskedChip(const IdentifierHash& hashID,
 StatusCode SCT_RodDecoder::processHeader(const uint16_t inData,
                                          const uint32_t robID,
                                          SharedData& data,
-                                         ISCT_RDO_Container& rdoIDCont,
+                                         SCT_RDO_Container& rdoIDCont,
                                          CacheHelper& cache,
                                          SCT_RodDecoderErrorsHelper& errs,
                                          bool& hasError,
@@ -679,7 +640,7 @@ StatusCode SCT_RodDecoder::processHeader(const uint16_t inData,
   // Create the last RDO of the previous link if any
   if (not data.isSaved(false) and data.oldStrip>=0) {
     
-    const int rdoMade{makeRDO(false, data, rdoIDCont, cache, errs)};
+    const int rdoMade{makeRDO(false, data, cache)};
     if (rdoMade == -1) {
       hasError = true;
       ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -707,8 +668,7 @@ StatusCode SCT_RodDecoder::processHeader(const uint16_t inData,
     return sc;
   }
   else {
-    data.linkIDHash = m_cabling->getHashFromOnlineId(onlineID);
-    data.foundHashes.insert(data.linkIDHash);
+    data.setCollection(m_sctID, m_cabling->getHashFromOnlineId(onlineID), rdoIDCont, errs);
   }
   // Look for masked off links - bit 7
   if ((inData >> 7) & 0x1) {
@@ -759,7 +719,7 @@ StatusCode SCT_RodDecoder::processHeader(const uint16_t inData,
 StatusCode SCT_RodDecoder::processSuperCondensedHit(const uint16_t inData,
                                                     const uint32_t robID,
                                                     SharedData& data,
-                                                    ISCT_RDO_Container& rdoIDCont,
+                                                    SCT_RDO_Container& rdoIDCont,
                                                     CacheHelper& cache,
                                                     SCT_RodDecoderErrorsHelper& errs,
                                                     bool& hasError) const
@@ -790,7 +750,7 @@ StatusCode SCT_RodDecoder::processSuperCondensedHit(const uint16_t inData,
   if ((data.side==1) and ((data.linkNumber%2)==0)) {
     if (((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) and (data.groupSize>0)) {
       // If it is a new cluster, make RDO with the previous cluster
-      const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(true, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -806,7 +766,7 @@ StatusCode SCT_RodDecoder::processSuperCondensedHit(const uint16_t inData,
   else if ((data.side==0) and ((data.linkNumber%2)!=0)) {
     if (((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) and (data.groupSize>0)) {
       // If it is a new cluster, make RDO with the previous cluster
-      const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(true, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -821,8 +781,7 @@ StatusCode SCT_RodDecoder::processSuperCondensedHit(const uint16_t inData,
   }
   if (secondSide) {
     const uint32_t onlineID{(robID & 0xFFFFFF) | (data.linkNumber << 24)};
-    data.linkIDHash = m_cabling->getHashFromOnlineId(onlineID);
-    data.foundHashes.insert(data.linkIDHash);
+    data.setCollection(m_sctID, m_cabling->getHashFromOnlineId(onlineID), rdoIDCont, errs);
   }
   
   if (data.groupSize == 0)  {
@@ -831,7 +790,7 @@ StatusCode SCT_RodDecoder::processSuperCondensedHit(const uint16_t inData,
 
   if ((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) {
     // If it is a new cluster, make RDO with the previous cluster
-    const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+    const int rdoMade{makeRDO(true, data, cache)};
     if (rdoMade == -1) {
       hasError = true;
       ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -849,7 +808,7 @@ StatusCode SCT_RodDecoder::processSuperCondensedHit(const uint16_t inData,
 StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
                                                const uint32_t robID,
                                                SharedData& data,
-                                               ISCT_RDO_Container& rdoIDCont,
+                                               SCT_RDO_Container& rdoIDCont,
                                                CacheHelper& cache,
                                                SCT_RodDecoderErrorsHelper& errs,
                                                bool& hasError) const
@@ -874,7 +833,7 @@ StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
   if ((data.side==1) and ((data.linkNumber%2)==0)) {
     if (((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) and (data.groupSize>0)) {
       // If it is a new cluster, make RDO with the previous cluster
-      const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(true, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -890,7 +849,7 @@ StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
   else if ((data.side==0) and ((data.linkNumber%2)!=0)) {
     if (((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) and (data.groupSize>0)) {
       // If it is a new cluster, make RDO with the previous cluster
-      const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(true, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -905,8 +864,7 @@ StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
   }
   if (secondSide) {
     const uint32_t onlineID{(robID & 0xFFFFFF) | (data.linkNumber << 24)};
-    data.linkIDHash = m_cabling->getHashFromOnlineId(onlineID);
-    data.foundHashes.insert(data.linkIDHash);
+    data.setCollection(m_sctID, m_cabling->getHashFromOnlineId(onlineID), rdoIDCont, errs);
   }
 
   if (data.groupSize == 0)  {
@@ -917,7 +875,7 @@ StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
     m_singleCondHitNumber++;
     if ((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) {
       // If it is a new cluster, make RDO with the previous cluster
-      const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(true, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -949,7 +907,7 @@ StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
     m_pairedCondHitNumber++;
     if ((data.strip!=data.oldStrip) or (data.side!=data.oldSide)) {
       // If it is a new cluster, make RDO with the previous cluster
-      const int rdoMade{makeRDO(true, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(true, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -982,7 +940,7 @@ StatusCode SCT_RodDecoder::processCondensedHit(const uint16_t inData,
 StatusCode SCT_RodDecoder::processExpandedHit(const uint16_t inData,
                                               const uint32_t robID,
                                               SharedData& data,
-                                              ISCT_RDO_Container& rdoIDCont,
+                                              SCT_RDO_Container& rdoIDCont,
                                               CacheHelper& cache,
                                               SCT_RodDecoderErrorsHelper& errs,
                                               bool& hasError) const
@@ -1016,11 +974,10 @@ StatusCode SCT_RodDecoder::processExpandedHit(const uint16_t inData,
     }
     if (secondSide) {
       const uint32_t onlineID{(robID & 0xFFFFFF) | (data.linkNumber << 24)};
-      data.linkIDHash = m_cabling->getHashFromOnlineId(onlineID);
-      data.foundHashes.insert(data.linkIDHash);
+      data.setCollection(m_sctID, m_cabling->getHashFromOnlineId(onlineID), rdoIDCont, errs);
     }
     data.groupSize = 1;
-    const int rdoMade{makeRDO(false, data, rdoIDCont, cache, errs)};
+    const int rdoMade{makeRDO(false, data, cache)};
     if (rdoMade == -1) {
       hasError = true;
       ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -1049,7 +1006,7 @@ StatusCode SCT_RodDecoder::processExpandedHit(const uint16_t inData,
       data.strip++;
       data.timeBin = (inData & 0x7);
       data.groupSize = 1;
-      const int rdoMade1{makeRDO(false, data, rdoIDCont, cache, errs)};
+      const int rdoMade1{makeRDO(false, data, cache)};
       if (rdoMade1 == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -1060,7 +1017,7 @@ StatusCode SCT_RodDecoder::processExpandedHit(const uint16_t inData,
       // Second hit from the pair
       data.strip++;
       data.timeBin = ((inData >> 4) & 0x7);
-      const int rdoMade2{makeRDO(false, data, rdoIDCont, cache, errs)};
+      const int rdoMade2{makeRDO(false, data, cache)};
       if (rdoMade2 == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
@@ -1081,7 +1038,7 @@ StatusCode SCT_RodDecoder::processExpandedHit(const uint16_t inData,
       data.strip++;
       data.timeBin = (inData & 0x7);
       data.groupSize = 1;
-      const int rdoMade{makeRDO(false, data, rdoIDCont, cache, errs)};
+      const int rdoMade{makeRDO(false, data, cache)};
       if (rdoMade == -1) {
         hasError = true;
         ATH_CHECK(addSingleError(data.linkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs));
diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h
index 9fcf8f28597d1a1f923a9097b6d9564214aa9fab..a62464ee515c95384db83376bcaf0c04f8928082 100644
--- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h
+++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h
@@ -11,8 +11,10 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 
 #include "InDetByteStreamErrors/IDCInDetBSErrContainer.h"
+#include "InDetIdentifier/SCT_ID.h"
 #include "SCT_ConditionsData/SCT_ByteStreamErrors.h"
 #include "SCT_Cabling/ISCT_CablingTool.h"
+#include "SCT_ConditionsTools/ISCT_ByteStreamErrorsTool.h"
 #include "SCT_ConditionsTools/ISCT_ConfigurationConditionsTool.h"
 #include "Identifier/IdContext.h"
 
@@ -21,12 +23,48 @@
 #include <atomic>
 #include <cstdint>
 #include <string>
+#include <unordered_map>
 #include <unordered_set>
 #include <vector>
 
 class IdentifierHash;
-class SCT_ID;
-class SCT_RodDecoderErrorsHelper;
+
+
+/**
+ * @brief allows to accumulate errors in one fillColection call
+ *
+ * Errors information is scattered across this code.
+ * To be sure that all of the errors are saved this helper class provides add method allowing to update/accumulate erorr.
+ * The IDC, for a very good reasons (MT safety) do not allow for that.
+ **/
+class SCT_RodDecoderErrorsHelper {
+public:
+  SCT_RodDecoderErrorsHelper(IDCInDetBSErrContainer& idcContainer)
+    : errorsIDC{ idcContainer } {}
+  ~SCT_RodDecoderErrorsHelper() {
+    for (auto [id, err]: accumulatedErrors) {
+      errorsIDC.setOrDrop(id, err);
+    }
+  }
+  void noerror(const IdentifierHash id) {
+    accumulatedErrors[id]; // this adds 0 (no error) for an ID
+  }
+
+  void add(const IdentifierHash id, SCT_ByteStreamErrors::ErrorType etype) {
+    SCT_ByteStreamErrors::addError(accumulatedErrors[id], etype);
+  }
+
+  void removeIfEmpty(const IdentifierHash id) {
+    if (accumulatedErrors[id]==0) {
+      accumulatedErrors.erase(id);
+    } 
+  }
+
+  std::map<IdentifierHash, IDCInDetBSErrContainer::ErrorCode> accumulatedErrors;
+  IDCInDetBSErrContainer& errorsIDC;
+};
+
+
 /** 
  * @class SCT_RodDecoder
  *
@@ -68,7 +106,7 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
    * @param vecHash Vector of hashes.
    */
   virtual StatusCode fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment& robFrag,
-                                    ISCT_RDO_Container& rdoIDCont,
+                                    SCT_RDO_Container& rdoIDCont,
                                     IDCInDetBSErrContainer& errs,
                                     const std::vector<IdentifierHash>* vecHash = nullptr) const override;
 
@@ -92,7 +130,8 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
     int strip{0};
     int groupSize{0};
     int timeBin{0};
-    IdentifierHash linkIDHash; // Determined from header and changed for links using Rx redundancy
+    IdentifierHash linkIDHash; // Determined from header and changed for links using Rx redundancy (waferHash)
+    Identifier collID; // Determined from linkIDHash (waferID)
     int errors{0}; // Encodes the errors on the header (bit 4: error in condensed mode 1st hit, bit 5: error in condensed mode 2nd hit)
     CacheHelper cache; // For the trigger
     std::vector<int> errorHit;
@@ -108,6 +147,9 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
     bool foundMissingLinkHeaderError{false};
     std::unordered_set<IdentifierHash> foundHashes;
 
+    std::unordered_map<IdentifierHash, std::unique_ptr<SCT_RDO_Collection>> rdoCollMap; // If SCT_RDO_Collection* is nullptr, it means the collection is already present in the container.
+    std::unordered_map<IdentifierHash, SCT_RDO_Container::IDC_WriteHandle> writeHandleMap;
+
     bool foundHeader{false};
 
     void reset() {
@@ -140,6 +182,27 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
         return saved[   side*N_STRIPS_PER_SIDE +    strip];
       }
     }
+    void setCollection(const SCT_ID* sctID,
+                       const IdentifierHash& waferHash,
+                       SCT_RDO_Container& rdoIDCont,
+                       SCT_RodDecoderErrorsHelper& errs) {
+      linkIDHash = waferHash;
+      collID = sctID->wafer_id(linkIDHash);
+      foundHashes.insert(linkIDHash);
+      if (rdoCollMap.count(linkIDHash)==0) { // The collection is not in the local map.
+        writeHandleMap.insert(std::pair<IdentifierHash, SCT_RDO_Container::IDC_WriteHandle>(linkIDHash, rdoIDCont.getWriteHandle(linkIDHash)));
+        if (writeHandleMap[linkIDHash].alreadyPresent()) { // The collection is already in the container.
+          rdoCollMap[linkIDHash] = nullptr;
+          writeHandleMap.erase(linkIDHash); // lock is released
+        }
+        else { // Create a new collection for linkIDHash
+          std::unique_ptr<SCT_RDO_Collection> rdoColl{std::make_unique<SCT_RDO_Collection>(linkIDHash)};
+          rdoColl->setIdentifier(collID);
+          rdoCollMap[linkIDHash] = std::move(rdoColl);
+          errs.noerror(linkIDHash); // make sure the error information is filled for this hash
+        }
+      }
+    }
   };
 
   /**
@@ -154,15 +217,11 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
    *
    * @param isOld if true use data.oldStrip, otherwise use data.strip.
    * @param data Struct to hold data shared in methods used in fillCollection method
-   * @param rdoIDCont RDO ID Container to be filled.
    * @param cache Cache.
-   * @param errorsCache - the cache to be filled for a given ID
    */
   int makeRDO(const bool isOld,
-              const SharedData& data,
-              ISCT_RDO_Container& rdoIDCont,
-              CacheHelper& cache,
-	      SCT_RodDecoderErrorsHelper& errorsCache) const;
+              SharedData& data,
+              CacheHelper& cache) const;
 
   /**
    * @brief Add an error for each wafer in the problematic ROD
@@ -212,7 +271,7 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
   StatusCode processHeader(const uint16_t inData,
                            const uint32_t robID,
                            SharedData& data,
-                           ISCT_RDO_Container& rdoIDCont,
+                           SCT_RDO_Container& rdoIDCont,
                            CacheHelper& cache,
                            SCT_RodDecoderErrorsHelper& errs,
                            bool& hasError,
@@ -232,7 +291,7 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
   StatusCode processSuperCondensedHit(const uint16_t inData,
                                       const uint32_t robID,
                                       SharedData& data,
-                                      ISCT_RDO_Container& rdoIDCont,
+                                      SCT_RDO_Container& rdoIDCont,
                                       CacheHelper& cache,
                                       SCT_RodDecoderErrorsHelper& errs,
                                       bool& hasError) const;
@@ -251,7 +310,7 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
   StatusCode processCondensedHit(const uint16_t inData,
                                  const uint32_t robID,
                                  SharedData& data,
-                                 ISCT_RDO_Container& rdoIDCont,
+                                 SCT_RDO_Container& rdoIDCont,
                                  CacheHelper& cache,
                                  SCT_RodDecoderErrorsHelper& errs,
                                  bool& hasError) const;
@@ -270,7 +329,7 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder>
   StatusCode processExpandedHit(const uint16_t inData,
                                 const uint32_t robID,
                                 SharedData& data,
-                                ISCT_RDO_Container& rdoIDCont,
+                                SCT_RDO_Container& rdoIDCont,
                                 CacheHelper& cache,
                                 SCT_RodDecoderErrorsHelper& errs,
                                 bool& hasError) const;